Add fields on calendar cards (#14513)
<img width="1919" height="956" alt="image" src="https://github.com/user-attachments/assets/32f3c5b3-3f1e-4279-98ef-5e185f6a7ac1" />
This commit is contained in:
+8
-6
@@ -16,6 +16,7 @@ import { RecordBoardCardBody } from '@/object-record/record-board/record-board-c
|
||||
import { RecordBoardCardHeader } from '@/object-record/record-board/record-board-card/components/RecordBoardCardHeader';
|
||||
import { RECORD_BOARD_CARD_CLICK_OUTSIDE_ID } from '@/object-record/record-board/record-board-card/constants/RecordBoardCardClickOutsideId';
|
||||
import { RecordBoardCardComponentInstanceContext } from '@/object-record/record-board/record-board-card/states/contexts/RecordBoardCardComponentInstanceContext';
|
||||
import { recordBoardCardIsExpandedComponentState } from '@/object-record/record-board/record-board-card/states/recordBoardCardIsExpandedComponentState';
|
||||
import { RecordBoardComponentInstanceContext } from '@/object-record/record-board/states/contexts/RecordBoardComponentInstanceContext';
|
||||
import { RecordCard } from '@/object-record/record-card/components/RecordCard';
|
||||
import { useOpenRecordFromIndexView } from '@/object-record/record-index/hooks/useOpenRecordFromIndexView';
|
||||
@@ -24,10 +25,11 @@ import { useScrollWrapperHTMLElement } from '@/ui/utilities/scroll/hooks/useScro
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useRecoilComponentFamilyState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyState';
|
||||
import { useRecoilComponentFamilyValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValue';
|
||||
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
|
||||
import styled from '@emotion/styled';
|
||||
import { useContext, useState } from 'react';
|
||||
import { useContext } from 'react';
|
||||
import { InView, useInView } from 'react-intersection-observer';
|
||||
import { AnimatedEaseInOut } from 'twenty-ui/utilities';
|
||||
import { useDebouncedCallback } from 'use-debounce';
|
||||
@@ -84,7 +86,10 @@ export const RecordBoardCard = () => {
|
||||
isRecordBoardCompactModeActiveComponentState,
|
||||
);
|
||||
|
||||
const [isCardExpanded, setIsCardExpanded] = useState(false);
|
||||
const [isCardExpanded, setIsCardExpanded] = useRecoilComponentState(
|
||||
recordBoardCardIsExpandedComponentState,
|
||||
`record-board-card-${recordId}`,
|
||||
);
|
||||
|
||||
const [isCurrentCardSelected, setIsCurrentCardSelected] =
|
||||
useRecoilComponentFamilyState(
|
||||
@@ -194,10 +199,7 @@ export const RecordBoardCard = () => {
|
||||
isPrimaryMultiDrag={isPrimaryMultiDrag}
|
||||
isSecondaryDragged={isSecondaryDragged}
|
||||
>
|
||||
<RecordBoardCardHeader
|
||||
isCardExpanded={isCardExpanded}
|
||||
setIsCardExpanded={setIsCardExpanded}
|
||||
/>
|
||||
<RecordBoardCardHeader />
|
||||
<AnimatedEaseInOut
|
||||
isOpen={isCardExpanded || !isCompactModeActive}
|
||||
initial={false}
|
||||
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
import { isRecordFieldReadOnly } from '@/object-record/read-only/utils/isRecordFieldReadOnly';
|
||||
import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext';
|
||||
import { RecordBoardCardBodyContainer } from '@/object-record/record-board/record-board-card/components/RecordBoardCardBodyContainer';
|
||||
import { StopPropagationContainer } from '@/object-record/record-board/record-board-card/components/StopPropagationContainer';
|
||||
import { RECORD_BOARD_CARD_INPUT_ID_PREFIX } from '@/object-record/record-board/record-board-card/constants/RecordBoardCardInputIdPrefix';
|
||||
import { RecordBoardCardContext } from '@/object-record/record-board/record-board-card/contexts/RecordBoardCardContext';
|
||||
import { recordBoardCardHoverPositionComponentState } from '@/object-record/record-board/record-board-card/states/recordBoardCardHoverPositionComponentState';
|
||||
import { RecordCardBodyContainer } from '@/object-record/record-card/components/RecordCardBodyContainer';
|
||||
import { visibleRecordFieldsComponentSelector } from '@/object-record/record-field/states/visibleRecordFieldsComponentSelector';
|
||||
import {
|
||||
FieldContext,
|
||||
@@ -58,7 +58,7 @@ export const RecordBoardCardBody = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<RecordBoardCardBodyContainer>
|
||||
<RecordCardBodyContainer>
|
||||
{visibleRecordFieldsExceptLabelIdentifier.map((recordField, index) => {
|
||||
const correspondingFieldDefinition =
|
||||
fieldDefinitionByFieldMetadataItemId[recordField.fieldMetadataItemId];
|
||||
@@ -105,6 +105,6 @@ export const RecordBoardCardBody = () => {
|
||||
</StopPropagationContainer>
|
||||
);
|
||||
})}
|
||||
</RecordBoardCardBodyContainer>
|
||||
</RecordCardBodyContainer>
|
||||
);
|
||||
};
|
||||
|
||||
+88
-31
@@ -4,25 +4,45 @@ import { RecordBoardCardContext } from '@/object-record/record-board/record-boar
|
||||
import { isRecordBoardCardSelectedComponentFamilyState } from '@/object-record/record-board/states/isRecordBoardCardSelectedComponentFamilyState';
|
||||
import { isRecordBoardCompactModeActiveComponentState } from '@/object-record/record-board/states/isRecordBoardCompactModeActiveComponentState';
|
||||
|
||||
import { RecordChip } from '@/object-record/components/RecordChip';
|
||||
import { useActiveRecordBoardCard } from '@/object-record/record-board/hooks/useActiveRecordBoardCard';
|
||||
import { useFocusedRecordBoardCard } from '@/object-record/record-board/hooks/useFocusedRecordBoardCard';
|
||||
import { RecordCardHeader } from '@/object-record/record-card/components/RecordCardHeader';
|
||||
import { StopPropagationContainer } from '@/object-record/record-board/record-board-card/components/StopPropagationContainer';
|
||||
import { recordBoardCardIsExpandedComponentState } from '@/object-record/record-board/record-board-card/states/recordBoardCardIsExpandedComponentState';
|
||||
import { RecordCardHeaderContainer } from '@/object-record/record-card/components/RecordCardHeaderContainer';
|
||||
import { useOpenRecordFromIndexView } from '@/object-record/record-index/hooks/useOpenRecordFromIndexView';
|
||||
import { recordIndexOpenRecordInState } from '@/object-record/record-index/states/recordIndexOpenRecordInState';
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { useRecoilComponentFamilyState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyState';
|
||||
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { type Dispatch, type SetStateAction, useContext } from 'react';
|
||||
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
|
||||
import styled from '@emotion/styled';
|
||||
import { useContext } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { ChipVariant } from 'twenty-ui/components';
|
||||
import { IconEye, IconEyeOff } from 'twenty-ui/display';
|
||||
import { Checkbox, CheckboxVariant, LightIconButton } from 'twenty-ui/input';
|
||||
|
||||
type RecordBoardCardHeaderProps = {
|
||||
isCardExpanded?: boolean;
|
||||
setIsCardExpanded?: Dispatch<SetStateAction<boolean>>;
|
||||
};
|
||||
const StyledCompactIconContainer = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-left: ${({ theme }) => theme.spacing(1)};
|
||||
`;
|
||||
|
||||
export const RecordBoardCardHeader = ({
|
||||
isCardExpanded,
|
||||
setIsCardExpanded,
|
||||
}: RecordBoardCardHeaderProps) => {
|
||||
const StyledCheckboxContainer = styled.div`
|
||||
margin-left: auto;
|
||||
`;
|
||||
|
||||
const StyledRecordChipContainer = styled.div`
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
overflow: hidden;
|
||||
`;
|
||||
|
||||
export const RecordBoardCardHeader = () => {
|
||||
const { recordId } = useContext(RecordBoardCardContext);
|
||||
|
||||
const { objectMetadataItem, recordBoardId } = useContext(RecordBoardContext);
|
||||
@@ -30,10 +50,14 @@ export const RecordBoardCardHeader = ({
|
||||
const { activateBoardCard } = useActiveRecordBoardCard(recordBoardId);
|
||||
const { unfocusBoardCard } = useFocusedRecordBoardCard(recordBoardId);
|
||||
|
||||
const showCompactView = useRecoilComponentValue(
|
||||
const isCompactModeActive = useRecoilComponentValue(
|
||||
isRecordBoardCompactModeActiveComponentState,
|
||||
);
|
||||
|
||||
const [isCardExpanded, setIsCardExpanded] = useRecoilComponentState(
|
||||
recordBoardCardIsExpandedComponentState,
|
||||
);
|
||||
|
||||
const { checkIfLastUnselectAndCloseDropdown } =
|
||||
useRecordBoardSelection(recordBoardId);
|
||||
|
||||
@@ -47,26 +71,59 @@ export const RecordBoardCardHeader = ({
|
||||
|
||||
const recordIndexOpenRecordIn = useRecoilValue(recordIndexOpenRecordInState);
|
||||
|
||||
const record = useRecoilValue(recordStoreFamilyState(recordId));
|
||||
|
||||
const triggerEvent =
|
||||
recordIndexOpenRecordIn === ViewOpenRecordInType.SIDE_PANEL
|
||||
? 'CLICK'
|
||||
: 'MOUSE_DOWN';
|
||||
|
||||
return (
|
||||
<RecordCardHeader
|
||||
isCompactView={showCompactView}
|
||||
onTitleClick={() => {
|
||||
activateBoardCard({ rowIndex, columnIndex });
|
||||
unfocusBoardCard();
|
||||
openRecordFromIndexView({ recordId });
|
||||
}}
|
||||
onCompactIconClick={() => {
|
||||
setIsCardExpanded?.((prev) => !prev);
|
||||
}}
|
||||
onCheckboxChange={() => {
|
||||
setIsCurrentCardSelected(!isCurrentCardSelected);
|
||||
checkIfLastUnselectAndCloseDropdown();
|
||||
}}
|
||||
objectMetadataItem={objectMetadataItem}
|
||||
recordId={recordId}
|
||||
isCurrentCardSelected={isCurrentCardSelected}
|
||||
recordIndexOpenRecordIn={recordIndexOpenRecordIn}
|
||||
isCardExpanded={isCardExpanded}
|
||||
/>
|
||||
<RecordCardHeaderContainer isCompact={isCompactModeActive}>
|
||||
<StyledRecordChipContainer>
|
||||
<StopPropagationContainer>
|
||||
{isDefined(record) && (
|
||||
<RecordChip
|
||||
objectNameSingular={objectMetadataItem.nameSingular}
|
||||
record={record}
|
||||
variant={ChipVariant.Transparent}
|
||||
onClick={() => {
|
||||
activateBoardCard({ rowIndex, columnIndex });
|
||||
unfocusBoardCard();
|
||||
openRecordFromIndexView({ recordId });
|
||||
}}
|
||||
triggerEvent={triggerEvent}
|
||||
/>
|
||||
)}
|
||||
</StopPropagationContainer>
|
||||
</StyledRecordChipContainer>
|
||||
|
||||
{isCompactModeActive && (
|
||||
<StyledCompactIconContainer className="compact-icon-container">
|
||||
<StopPropagationContainer>
|
||||
<LightIconButton
|
||||
Icon={isCardExpanded ? IconEyeOff : IconEye}
|
||||
accent="tertiary"
|
||||
onClick={() => {
|
||||
setIsCardExpanded(!isCardExpanded);
|
||||
}}
|
||||
/>
|
||||
</StopPropagationContainer>
|
||||
</StyledCompactIconContainer>
|
||||
)}
|
||||
<StyledCheckboxContainer className="checkbox-container">
|
||||
<StopPropagationContainer>
|
||||
<Checkbox
|
||||
hoverable
|
||||
checked={isCurrentCardSelected}
|
||||
onChange={(value) => {
|
||||
setIsCurrentCardSelected(value.target.checked);
|
||||
checkIfLastUnselectAndCloseDropdown();
|
||||
}}
|
||||
variant={CheckboxVariant.Secondary}
|
||||
/>
|
||||
</StopPropagationContainer>
|
||||
</StyledCheckboxContainer>
|
||||
</RecordCardHeaderContainer>
|
||||
);
|
||||
};
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import { RecordBoardCardComponentInstanceContext } from '@/object-record/record-board/record-board-card/states/contexts/RecordBoardCardComponentInstanceContext';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
|
||||
export const recordBoardCardIsExpandedComponentState =
|
||||
createComponentState<boolean>({
|
||||
key: 'recordBoardCardIsExpandedComponentState',
|
||||
defaultValue: false,
|
||||
componentInstanceContext: RecordBoardCardComponentInstanceContext,
|
||||
});
|
||||
+6
-6
@@ -3,8 +3,8 @@ import styled from '@emotion/styled';
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
|
||||
import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader';
|
||||
import { RecordBoardCardBodyContainer } from '@/object-record/record-board/record-board-card/components/RecordBoardCardBodyContainer';
|
||||
import { StyledBoardCardHeader } from '@/object-record/record-card/components/RecordCardHeader';
|
||||
import { RecordCardBodyContainer } from '@/object-record/record-card/components/RecordCardBodyContainer';
|
||||
import { RecordCardHeaderContainer } from '@/object-record/record-card/components/RecordCardHeaderContainer';
|
||||
const StyledSkeletonIconAndText = styled.div`
|
||||
display: flex;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
@@ -39,18 +39,18 @@ export const RecordBoardColumnCardContainerSkeletonLoader = ({
|
||||
highlightColor={theme.background.transparent.lighter}
|
||||
borderRadius={4}
|
||||
>
|
||||
<StyledBoardCardHeader showCompactView={isCompactModeActive}>
|
||||
<RecordCardHeaderContainer isCompact={isCompactModeActive}>
|
||||
<StyledSkeletonTitle>
|
||||
<Skeleton
|
||||
width={titleSkeletonWidth}
|
||||
height={SKELETON_LOADER_HEIGHT_SIZES.standard.s}
|
||||
/>
|
||||
</StyledSkeletonTitle>
|
||||
</StyledBoardCardHeader>
|
||||
</RecordCardHeaderContainer>
|
||||
<StyledSeparator />
|
||||
{!isCompactModeActive &&
|
||||
skeletonItems.map(({ id }) => (
|
||||
<RecordBoardCardBodyContainer key={id}>
|
||||
<RecordCardBodyContainer key={id}>
|
||||
<StyledSkeletonIconAndText>
|
||||
<Skeleton
|
||||
width={16}
|
||||
@@ -61,7 +61,7 @@ export const RecordBoardColumnCardContainerSkeletonLoader = ({
|
||||
height={SKELETON_LOADER_HEIGHT_SIZES.standard.s}
|
||||
/>
|
||||
</StyledSkeletonIconAndText>
|
||||
</RecordBoardCardBodyContainer>
|
||||
</RecordCardBodyContainer>
|
||||
))}
|
||||
</SkeletonTheme>
|
||||
);
|
||||
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
import { isRecordFieldReadOnly } from '@/object-record/read-only/utils/isRecordFieldReadOnly';
|
||||
import { StopPropagationContainer } from '@/object-record/record-board/record-board-card/components/StopPropagationContainer';
|
||||
import { RECORD_BOARD_CARD_INPUT_ID_PREFIX } from '@/object-record/record-board/record-board-card/constants/RecordBoardCardInputIdPrefix';
|
||||
import { useRecordCalendarContextOrThrow } from '@/object-record/record-calendar/contexts/RecordCalendarContext';
|
||||
import { RecordCardBodyContainer } from '@/object-record/record-card/components/RecordCardBodyContainer';
|
||||
import { visibleRecordFieldsComponentSelector } from '@/object-record/record-field/states/visibleRecordFieldsComponentSelector';
|
||||
import { FieldContext } from '@/object-record/record-field/ui/contexts/FieldContext';
|
||||
import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/ui/states/contexts/RecordFieldComponentInstanceContext';
|
||||
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
|
||||
import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell';
|
||||
import { getRecordFieldInputInstanceId } from '@/object-record/utils/getRecordFieldInputId';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
|
||||
type RecordCalendarCardBodyProps = {
|
||||
recordId: string;
|
||||
isRecordReadOnly: boolean;
|
||||
};
|
||||
|
||||
export const RecordCalendarCardBody = ({
|
||||
recordId,
|
||||
isRecordReadOnly,
|
||||
}: RecordCalendarCardBodyProps) => {
|
||||
const { objectPermissions } = useRecordCalendarContextOrThrow();
|
||||
|
||||
const {
|
||||
labelIdentifierFieldMetadataItem,
|
||||
fieldDefinitionByFieldMetadataItemId,
|
||||
} = useRecordIndexContextOrThrow();
|
||||
|
||||
const visibleRecordFields = useRecoilComponentValue(
|
||||
visibleRecordFieldsComponentSelector,
|
||||
);
|
||||
|
||||
const visibleRecordFieldsExceptLabelIdentifier = visibleRecordFields.filter(
|
||||
(recordField) =>
|
||||
recordField.fieldMetadataItemId !== labelIdentifierFieldMetadataItem?.id,
|
||||
);
|
||||
|
||||
return (
|
||||
<RecordCardBodyContainer>
|
||||
{visibleRecordFieldsExceptLabelIdentifier.map((recordField) => {
|
||||
const correspondingFieldDefinition =
|
||||
fieldDefinitionByFieldMetadataItemId[recordField.fieldMetadataItemId];
|
||||
|
||||
return (
|
||||
<StopPropagationContainer key={recordField.fieldMetadataItemId}>
|
||||
<FieldContext.Provider
|
||||
value={{
|
||||
recordId,
|
||||
maxWidth: 156,
|
||||
isLabelIdentifier: false,
|
||||
isRecordFieldReadOnly: isRecordFieldReadOnly({
|
||||
isRecordReadOnly,
|
||||
objectPermissions,
|
||||
fieldMetadataItem: {
|
||||
id: recordField.fieldMetadataItemId,
|
||||
isUIReadOnly:
|
||||
correspondingFieldDefinition.metadata.isUIReadOnly ??
|
||||
false,
|
||||
},
|
||||
}),
|
||||
fieldDefinition: correspondingFieldDefinition,
|
||||
useUpdateRecord: () => [() => undefined, { loading: false }],
|
||||
isDisplayModeFixHeight: true,
|
||||
triggerEvent: 'CLICK',
|
||||
anchorId: `${RECORD_BOARD_CARD_INPUT_ID_PREFIX}-${recordId}-${correspondingFieldDefinition.metadata.fieldName}`,
|
||||
onMouseEnter: () => {},
|
||||
}}
|
||||
>
|
||||
<RecordFieldComponentInstanceContext.Provider
|
||||
value={{
|
||||
instanceId: getRecordFieldInputInstanceId({
|
||||
recordId,
|
||||
fieldName: correspondingFieldDefinition.metadata.fieldName,
|
||||
prefix: RECORD_BOARD_CARD_INPUT_ID_PREFIX,
|
||||
}),
|
||||
}}
|
||||
>
|
||||
<RecordInlineCell
|
||||
instanceIdPrefix={RECORD_BOARD_CARD_INPUT_ID_PREFIX}
|
||||
/>
|
||||
</RecordFieldComponentInstanceContext.Provider>
|
||||
</FieldContext.Provider>
|
||||
</StopPropagationContainer>
|
||||
);
|
||||
})}
|
||||
</RecordCardBodyContainer>
|
||||
);
|
||||
};
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
import { RecordChip } from '@/object-record/components/RecordChip';
|
||||
import { StopPropagationContainer } from '@/object-record/record-board/record-board-card/components/StopPropagationContainer';
|
||||
import { useRecordCalendarContextOrThrow } from '@/object-record/record-calendar/contexts/RecordCalendarContext';
|
||||
import { RecordCardHeaderContainer } from '@/object-record/record-card/components/RecordCardHeaderContainer';
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { ChipVariant } from 'twenty-ui/components';
|
||||
import { Checkbox, CheckboxVariant } from 'twenty-ui/input';
|
||||
|
||||
const StyledCheckboxContainer = styled.div`
|
||||
margin-left: auto;
|
||||
`;
|
||||
|
||||
const StyledRecordChipContainer = styled.div`
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
overflow: hidden;
|
||||
`;
|
||||
|
||||
type RecordCalendarCardHeaderProps = {
|
||||
recordId: string;
|
||||
};
|
||||
|
||||
export const RecordCalendarCardHeader = ({
|
||||
recordId,
|
||||
}: RecordCalendarCardHeaderProps) => {
|
||||
const { objectMetadataItem } = useRecordCalendarContextOrThrow();
|
||||
const record = useRecoilValue(recordStoreFamilyState(recordId));
|
||||
|
||||
if (!isDefined(record)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<RecordCardHeaderContainer isCompact={true}>
|
||||
<StyledRecordChipContainer>
|
||||
<StopPropagationContainer>
|
||||
<RecordChip
|
||||
objectNameSingular={objectMetadataItem.nameSingular}
|
||||
record={record}
|
||||
variant={ChipVariant.Transparent}
|
||||
isIconHidden={true}
|
||||
/>
|
||||
</StopPropagationContainer>
|
||||
</StyledRecordChipContainer>
|
||||
<StyledCheckboxContainer className="checkbox-container">
|
||||
<StopPropagationContainer>
|
||||
<Checkbox
|
||||
hoverable
|
||||
checked={false}
|
||||
onChange={() => {}}
|
||||
variant={CheckboxVariant.Secondary}
|
||||
/>
|
||||
</StopPropagationContainer>
|
||||
</StyledCheckboxContainer>
|
||||
</RecordCardHeaderContainer>
|
||||
);
|
||||
};
|
||||
+4
-17
@@ -1,7 +1,6 @@
|
||||
import { useRecordCalendarContextOrThrow } from '@/object-record/record-calendar/contexts/RecordCalendarContext';
|
||||
import { RecordCalendarCardBody } from '@/object-record/record-calendar/card/components/RecordCalendarCardBody';
|
||||
import { RecordCalendarCardHeader } from '@/object-record/record-calendar/card/components/RecordCalendarCardHeader';
|
||||
import { RecordCard } from '@/object-record/record-card/components/RecordCard';
|
||||
import { RecordCardHeader } from '@/object-record/record-card/components/RecordCardHeader';
|
||||
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
@@ -19,23 +18,11 @@ type RecordCalendarMonthBodyCardProps = {
|
||||
export const RecordCalendarMonthBodyCard = ({
|
||||
recordId,
|
||||
}: RecordCalendarMonthBodyCardProps) => {
|
||||
const { objectMetadataItem } = useRecordCalendarContextOrThrow();
|
||||
|
||||
return (
|
||||
<StyledContainer>
|
||||
<StyledRecordCard>
|
||||
<RecordCardHeader
|
||||
objectMetadataItem={objectMetadataItem}
|
||||
recordId={recordId}
|
||||
onTitleClick={() => {}}
|
||||
onCompactIconClick={() => {}}
|
||||
onCheckboxChange={() => {}}
|
||||
isCompactView={true}
|
||||
isCurrentCardSelected={false}
|
||||
isCompactViewToggleable={false}
|
||||
isIconHidden={true}
|
||||
recordIndexOpenRecordIn={ViewOpenRecordInType.SIDE_PANEL}
|
||||
/>
|
||||
<RecordCalendarCardHeader recordId={recordId} />
|
||||
<RecordCalendarCardBody recordId={recordId} isRecordReadOnly={false} />
|
||||
</StyledRecordCard>
|
||||
</StyledContainer>
|
||||
);
|
||||
|
||||
+1
-1
@@ -18,4 +18,4 @@ const StyledBoardCardBody = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
export { StyledBoardCardBody as RecordBoardCardBodyContainer };
|
||||
export { StyledBoardCardBody as RecordCardBodyContainer };
|
||||
-137
@@ -1,137 +0,0 @@
|
||||
import { RecordChip } from '@/object-record/components/RecordChip';
|
||||
import { StopPropagationContainer } from '@/object-record/record-board/record-board-card/components/StopPropagationContainer';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { ChipVariant } from 'twenty-ui/components';
|
||||
import { IconEye, IconEyeOff } from 'twenty-ui/display';
|
||||
import { Checkbox, CheckboxVariant, LightIconButton } from 'twenty-ui/input';
|
||||
|
||||
export const StyledBoardCardHeader = styled.div<{
|
||||
showCompactView: boolean;
|
||||
}>`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
font-weight: ${({ theme }) => theme.font.weight.medium};
|
||||
height: 24px;
|
||||
padding-bottom: ${({ theme, showCompactView }) =>
|
||||
theme.spacing(showCompactView ? 2 : 1)};
|
||||
padding-left: ${({ theme }) => theme.spacing(2)};
|
||||
padding-right: ${({ theme }) => theme.spacing(2)};
|
||||
padding-top: ${({ theme }) => theme.spacing(2)};
|
||||
transition: padding ease-in-out 160ms;
|
||||
|
||||
img {
|
||||
height: ${({ theme }) => theme.icon.size.md}px;
|
||||
object-fit: cover;
|
||||
width: ${({ theme }) => theme.icon.size.md}px;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledCompactIconContainer = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-left: ${({ theme }) => theme.spacing(1)};
|
||||
`;
|
||||
|
||||
const StyledCheckboxContainer = styled.div`
|
||||
margin-left: auto;
|
||||
`;
|
||||
|
||||
const StyledRecordChipContainer = styled.div`
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
overflow: hidden;
|
||||
`;
|
||||
|
||||
type RecordCardHeaderProps = {
|
||||
recordId: string;
|
||||
objectMetadataItem: ObjectMetadataItem;
|
||||
|
||||
onTitleClick?: () => void;
|
||||
onCheckboxChange?: (value: boolean) => void;
|
||||
isCurrentCardSelected: boolean;
|
||||
recordIndexOpenRecordIn: ViewOpenRecordInType;
|
||||
|
||||
onCompactIconClick?: () => void;
|
||||
isCompactView: boolean;
|
||||
isCardExpanded?: boolean;
|
||||
isCompactViewToggleable?: boolean;
|
||||
recordChipMaxWidth?: number;
|
||||
isIconHidden?: boolean;
|
||||
};
|
||||
|
||||
export const RecordCardHeader = ({
|
||||
objectMetadataItem,
|
||||
recordId,
|
||||
onTitleClick,
|
||||
onCheckboxChange,
|
||||
isCurrentCardSelected,
|
||||
isIconHidden,
|
||||
recordIndexOpenRecordIn,
|
||||
isCompactView,
|
||||
isCompactViewToggleable = true,
|
||||
onCompactIconClick,
|
||||
isCardExpanded,
|
||||
}: RecordCardHeaderProps) => {
|
||||
const record = useRecoilValue(recordStoreFamilyState(recordId));
|
||||
|
||||
const triggerEvent =
|
||||
recordIndexOpenRecordIn === ViewOpenRecordInType.SIDE_PANEL
|
||||
? 'CLICK'
|
||||
: 'MOUSE_DOWN';
|
||||
|
||||
return (
|
||||
<StyledBoardCardHeader showCompactView={isCompactView}>
|
||||
<StyledRecordChipContainer>
|
||||
<StopPropagationContainer>
|
||||
{isDefined(record) && (
|
||||
<RecordChip
|
||||
objectNameSingular={objectMetadataItem.nameSingular}
|
||||
record={record}
|
||||
variant={ChipVariant.Transparent}
|
||||
isIconHidden={isIconHidden}
|
||||
onClick={() => {
|
||||
onTitleClick?.();
|
||||
}}
|
||||
triggerEvent={triggerEvent}
|
||||
/>
|
||||
)}
|
||||
</StopPropagationContainer>
|
||||
</StyledRecordChipContainer>
|
||||
|
||||
{isCompactView && isCompactViewToggleable && (
|
||||
<StyledCompactIconContainer className="compact-icon-container">
|
||||
<StopPropagationContainer>
|
||||
<LightIconButton
|
||||
Icon={isCardExpanded ? IconEyeOff : IconEye}
|
||||
accent="tertiary"
|
||||
onClick={() => {
|
||||
onCompactIconClick?.();
|
||||
}}
|
||||
/>
|
||||
</StopPropagationContainer>
|
||||
</StyledCompactIconContainer>
|
||||
)}
|
||||
<StyledCheckboxContainer className="checkbox-container">
|
||||
<StopPropagationContainer>
|
||||
<Checkbox
|
||||
hoverable
|
||||
checked={isCurrentCardSelected}
|
||||
onChange={(value) => {
|
||||
onCheckboxChange?.(value.target.checked);
|
||||
}}
|
||||
variant={CheckboxVariant.Secondary}
|
||||
/>
|
||||
</StopPropagationContainer>
|
||||
</StyledCheckboxContainer>
|
||||
</StyledBoardCardHeader>
|
||||
);
|
||||
};
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
export const StyledBoardCardHeaderContainer = styled.div<{
|
||||
isCompact: boolean;
|
||||
}>`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
font-weight: ${({ theme }) => theme.font.weight.medium};
|
||||
height: 24px;
|
||||
padding-bottom: ${({ theme, isCompact }) => theme.spacing(isCompact ? 2 : 1)};
|
||||
padding-left: ${({ theme }) => theme.spacing(2)};
|
||||
padding-right: ${({ theme }) => theme.spacing(2)};
|
||||
padding-top: ${({ theme }) => theme.spacing(2)};
|
||||
transition: padding ease-in-out 160ms;
|
||||
|
||||
img {
|
||||
height: ${({ theme }) => theme.icon.size.md}px;
|
||||
object-fit: cover;
|
||||
width: ${({ theme }) => theme.icon.size.md}px;
|
||||
}
|
||||
`;
|
||||
|
||||
export { StyledBoardCardHeaderContainer as RecordCardHeaderContainer };
|
||||
Reference in New Issue
Block a user