Added Side Panel compact header (#6560)
Fixes issue #6487 Added a new prop, `isInRightDrawer` to both the `ShowPageSummaryCard` and `ShowPageRightContainer` components. This prop allows for different styles to be applied based on the specific needs of the drawer.. Rather than creating a new component, I opted to add this prop to avoid code duplication. However, if you would prefer a separate component for this functionality, I'm happy to make that adjustment—please just let me know! Also added `box-sizing: border-box` to `ShowPageSummaryCard` to make sure it aligns with figma designs. https://github.com/user-attachments/assets/38e8d85e-55d5-471e-884a-11c67467f56f
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
import { ChangeEvent, useRef, useState } from 'react';
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
import { ChangeEvent, useRef, useState } from 'react';
|
||||||
import { IconPlus } from 'twenty-ui';
|
import { IconPlus } from 'twenty-ui';
|
||||||
|
|
||||||
import { SkeletonLoader } from '@/activities/components/SkeletonLoader';
|
import { SkeletonLoader } from '@/activities/components/SkeletonLoader';
|
||||||
@ -33,7 +33,6 @@ const StyledFileInput = styled.input`
|
|||||||
|
|
||||||
const StyledDropZoneContainer = styled.div`
|
const StyledDropZoneContainer = styled.div`
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: ${({ theme }) => theme.spacing(6)};
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const Attachments = ({
|
export const Attachments = ({
|
||||||
|
|||||||
@ -155,6 +155,7 @@ export const RecordShowContainer = ({
|
|||||||
|
|
||||||
const summaryCard = isDefined(recordFromStore) ? (
|
const summaryCard = isDefined(recordFromStore) ? (
|
||||||
<ShowPageSummaryCard
|
<ShowPageSummaryCard
|
||||||
|
isMobile={isMobile}
|
||||||
id={objectRecordId}
|
id={objectRecordId}
|
||||||
logoOrAvatar={recordIdentifier?.avatarUrl ?? ''}
|
logoOrAvatar={recordIdentifier?.avatarUrl ?? ''}
|
||||||
avatarPlaceholder={recordIdentifier?.name ?? ''}
|
avatarPlaceholder={recordIdentifier?.name ?? ''}
|
||||||
@ -301,7 +302,7 @@ export const RecordShowContainer = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ShowPageContainer>
|
<ShowPageContainer>
|
||||||
<ShowPageLeftContainer forceMobile={isInRightDrawer}>
|
<ShowPageLeftContainer forceMobile={isMobile}>
|
||||||
{!isMobile && summaryCard}
|
{!isMobile && summaryCard}
|
||||||
{!isMobile && fieldsBox}
|
{!isMobile && fieldsBox}
|
||||||
</ShowPageLeftContainer>
|
</ShowPageLeftContainer>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { ReactElement } from 'react';
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
import { ReactElement } from 'react';
|
||||||
|
|
||||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||||
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
||||||
@ -16,6 +16,7 @@ const StyledInnerContainer = styled.div`
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: ${() => (useIsMobile() ? 'column' : 'row')};
|
flex-direction: ${() => (useIsMobile() ? 'column' : 'row')};
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledScrollWrapper = styled(ScrollWrapper)`
|
const StyledScrollWrapper = styled(ScrollWrapper)`
|
||||||
|
|||||||
@ -29,6 +29,7 @@ const StyledShowPageRightContainer = styled.div<{ isMobile: boolean }>`
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: start;
|
justify-content: start;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledTabListContainer = styled.div`
|
const StyledTabListContainer = styled.div`
|
||||||
@ -40,6 +41,19 @@ const StyledTabListContainer = styled.div`
|
|||||||
height: 40px;
|
height: 40px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const StyledGreyBox = styled.div<{ isInRightDrawer: boolean }>`
|
||||||
|
background: ${({ theme, isInRightDrawer }) =>
|
||||||
|
isInRightDrawer ? theme.background.secondary : ''};
|
||||||
|
border: ${({ isInRightDrawer, theme }) =>
|
||||||
|
isInRightDrawer ? `1px solid ${theme.border.color.medium}` : ''};
|
||||||
|
border-radius: ${({ isInRightDrawer, theme }) =>
|
||||||
|
isInRightDrawer ? theme.border.radius.md : ''};
|
||||||
|
height: ${({ isInRightDrawer }) => (isInRightDrawer ? 'auto' : '100%')};
|
||||||
|
|
||||||
|
margin: ${({ isInRightDrawer, theme }) =>
|
||||||
|
isInRightDrawer ? theme.spacing(4) : ''};
|
||||||
|
`;
|
||||||
|
|
||||||
export const TAB_LIST_COMPONENT_ID = 'show-page-right-tab-list';
|
export const TAB_LIST_COMPONENT_ID = 'show-page-right-tab-list';
|
||||||
|
|
||||||
type ShowPageRightContainerProps = {
|
type ShowPageRightContainerProps = {
|
||||||
@ -151,7 +165,6 @@ export const ShowPageRightContainer = ({
|
|||||||
hide: !shouldDisplayCalendarTab,
|
hide: !shouldDisplayCalendarTab,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const renderActiveTabContent = () => {
|
const renderActiveTabContent = () => {
|
||||||
switch (activeTabId) {
|
switch (activeTabId) {
|
||||||
case 'timeline':
|
case 'timeline':
|
||||||
@ -173,7 +186,12 @@ export const ShowPageRightContainer = ({
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
case 'fields':
|
case 'fields':
|
||||||
return fieldsBox;
|
return (
|
||||||
|
<StyledGreyBox isInRightDrawer={isInRightDrawer}>
|
||||||
|
{fieldsBox}
|
||||||
|
</StyledGreyBox>
|
||||||
|
);
|
||||||
|
|
||||||
case 'tasks':
|
case 'tasks':
|
||||||
return <ObjectTasks targetableObject={targetableObject} />;
|
return <ObjectTasks targetableObject={targetableObject} />;
|
||||||
case 'notes':
|
case 'notes':
|
||||||
@ -188,10 +206,8 @@ export const ShowPageRightContainer = ({
|
|||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledShowPageRightContainer isMobile={isMobile}>
|
<StyledShowPageRightContainer isMobile={isMobile}>
|
||||||
{summaryCard}
|
|
||||||
<StyledTabListContainer>
|
<StyledTabListContainer>
|
||||||
<TabList
|
<TabList
|
||||||
loading={loading}
|
loading={loading}
|
||||||
@ -199,6 +215,7 @@ export const ShowPageRightContainer = ({
|
|||||||
tabs={tabs}
|
tabs={tabs}
|
||||||
/>
|
/>
|
||||||
</StyledTabListContainer>
|
</StyledTabListContainer>
|
||||||
|
{summaryCard}
|
||||||
{renderActiveTabContent()}
|
{renderActiveTabContent()}
|
||||||
</StyledShowPageRightContainer>
|
</StyledShowPageRightContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -20,40 +20,45 @@ type ShowPageSummaryCardProps = {
|
|||||||
onUploadPicture?: (file: File) => void;
|
onUploadPicture?: (file: File) => void;
|
||||||
title: ReactNode;
|
title: ReactNode;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
|
isMobile?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const StyledShowPageSummaryCard = styled.div`
|
export const StyledShowPageSummaryCard = styled.div<{
|
||||||
|
isMobile: boolean;
|
||||||
|
}>`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: ${({ isMobile }) => (isMobile ? 'row' : 'column')};
|
||||||
gap: ${({ theme }) => theme.spacing(3)};
|
gap: ${({ theme, isMobile }) =>
|
||||||
justify-content: center;
|
isMobile ? theme.spacing(2) : theme.spacing(3)};
|
||||||
|
justify-content: ${({ isMobile }) => (isMobile ? 'flex-start' : 'center')};
|
||||||
padding: ${({ theme }) => theme.spacing(4)};
|
padding: ${({ theme }) => theme.spacing(4)};
|
||||||
border-bottom: 1px solid ${({ theme }) => theme.border.color.light};
|
border-bottom: 1px solid ${({ theme }) => theme.border.color.light};
|
||||||
height: 127px;
|
height: ${({ isMobile }) => (isMobile ? '77px' : '127px')};
|
||||||
|
box-sizing: border-box;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledInfoContainer = styled.div`
|
const StyledInfoContainer = styled.div<{ isMobile: boolean }>`
|
||||||
align-items: center;
|
align-items: ${({ isMobile }) => (isMobile ? 'flex-start' : 'center')};
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: ${({ theme }) => theme.spacing(1)};
|
gap: ${({ theme }) => theme.spacing(1)};
|
||||||
width: 100%;
|
width: 100%;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledDate = styled.div`
|
const StyledDate = styled.div<{ isMobile: boolean }>`
|
||||||
color: ${({ theme }) => theme.font.color.tertiary};
|
color: ${({ theme }) => theme.font.color.tertiary};
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
padding-left: ${({ theme, isMobile }) => (isMobile ? theme.spacing(2) : 0)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledTitle = styled.div`
|
const StyledTitle = styled.div<{ isMobile: boolean }>`
|
||||||
color: ${({ theme }) => theme.font.color.primary};
|
color: ${({ theme }) => theme.font.color.primary};
|
||||||
display: flex;
|
display: flex;
|
||||||
font-size: ${({ theme }) => theme.font.size.xl};
|
font-size: ${({ theme }) => theme.font.size.xl};
|
||||||
font-weight: ${({ theme }) => theme.font.weight.semiBold};
|
font-weight: ${({ theme }) => theme.font.weight.semiBold};
|
||||||
justify-content: center;
|
justify-content: ${({ isMobile }) => (isMobile ? 'flex-start' : 'center')};
|
||||||
|
width: ${({ isMobile }) => (isMobile ? '' : '100%')};
|
||||||
width: 100%;
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledAvatarWrapper = styled.div`
|
const StyledAvatarWrapper = styled.div`
|
||||||
@ -97,13 +102,13 @@ export const ShowPageSummaryCard = ({
|
|||||||
onUploadPicture,
|
onUploadPicture,
|
||||||
title,
|
title,
|
||||||
loading,
|
loading,
|
||||||
|
isMobile = false,
|
||||||
}: ShowPageSummaryCardProps) => {
|
}: ShowPageSummaryCardProps) => {
|
||||||
const beautifiedCreatedAt =
|
const beautifiedCreatedAt =
|
||||||
date !== '' ? beautifyPastDateRelativeToNow(date) : '';
|
date !== '' ? beautifyPastDateRelativeToNow(date) : '';
|
||||||
const exactCreatedAt = date !== '' ? beautifyExactDateTime(date) : '';
|
const exactCreatedAt = date !== '' ? beautifyExactDateTime(date) : '';
|
||||||
const dateElementId = `date-id-${uuidV4()}`;
|
const dateElementId = `date-id-${uuidV4()}`;
|
||||||
const inputFileRef = useRef<HTMLInputElement>(null);
|
const inputFileRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
const onFileChange = (e: ChangeEvent<HTMLInputElement>) => {
|
const onFileChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
if (isDefined(e.target.files)) onUploadPicture?.(e.target.files[0]);
|
if (isDefined(e.target.files)) onUploadPicture?.(e.target.files[0]);
|
||||||
};
|
};
|
||||||
@ -114,13 +119,13 @@ export const ShowPageSummaryCard = ({
|
|||||||
|
|
||||||
if (loading)
|
if (loading)
|
||||||
return (
|
return (
|
||||||
<StyledShowPageSummaryCard>
|
<StyledShowPageSummaryCard isMobile={isMobile}>
|
||||||
<StyledShowPageSummaryCardSkeletonLoader />
|
<StyledShowPageSummaryCardSkeletonLoader />
|
||||||
</StyledShowPageSummaryCard>
|
</StyledShowPageSummaryCard>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledShowPageSummaryCard>
|
<StyledShowPageSummaryCard isMobile={isMobile}>
|
||||||
<StyledAvatarWrapper>
|
<StyledAvatarWrapper>
|
||||||
<Avatar
|
<Avatar
|
||||||
avatarUrl={logoOrAvatar}
|
avatarUrl={logoOrAvatar}
|
||||||
@ -136,10 +141,10 @@ export const ShowPageSummaryCard = ({
|
|||||||
type="file"
|
type="file"
|
||||||
/>
|
/>
|
||||||
</StyledAvatarWrapper>
|
</StyledAvatarWrapper>
|
||||||
<StyledInfoContainer>
|
<StyledInfoContainer isMobile={isMobile}>
|
||||||
<StyledTitle>{title}</StyledTitle>
|
<StyledTitle isMobile={isMobile}>{title}</StyledTitle>
|
||||||
{beautifiedCreatedAt && (
|
{beautifiedCreatedAt && (
|
||||||
<StyledDate id={dateElementId}>
|
<StyledDate isMobile={isMobile} id={dateElementId}>
|
||||||
Added {beautifiedCreatedAt}
|
Added {beautifiedCreatedAt}
|
||||||
</StyledDate>
|
</StyledDate>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user