refactor: move Checkmark, Avatar, Chip and Tooltip to twenty-ui (#4946)

Split from https://github.com/twentyhq/twenty/pull/4518

Part of #4766
This commit is contained in:
Thaïs
2024-04-15 12:05:06 +02:00
committed by GitHub
parent acc2092b95
commit b6d0b8a895
93 changed files with 225 additions and 189 deletions
@@ -107,7 +107,7 @@ Handles overflowing text and displays a tooltip when the text overflows.
<SandpackEditor <SandpackEditor
availableComponentPaths={['@/ui/display/tooltip/OverflowingTextWithTooltip']} availableComponentPaths={['twenty-ui']}
componentCode={overflowingTextWithTooltipCode} componentCode={overflowingTextWithTooltipCode}
/> />
@@ -17,7 +17,7 @@ Represents a successful or completed action.
<TabItem value="usage" label="Usage" default> <TabItem value="usage" label="Usage" default>
<SandpackEditor <SandpackEditor
availableComponentPaths={['@/ui/display/checkmark/components/Checkmark']} availableComponentPaths={['twenty-ui']}
componentCode={checkmarkCode} componentCode={checkmarkCode}
/> />
@@ -40,7 +40,7 @@ Represents a checkmark icon with the added feature of animation.
<TabItem value="usage" label="Usage" default> <TabItem value="usage" label="Usage" default>
<SandpackEditor <SandpackEditor
availableComponentPaths={['@/ui/display/checkmark/components/AnimatedCheckmark']} availableComponentPaths={['twenty-ui']}
componentCode={animatedCheckmarkCode} componentCode={animatedCheckmarkCode}
/> />
@@ -18,7 +18,7 @@ A visual element that you can use as a clickable or non-clickable container with
<TabItem value="usage" label="Usage" default> <TabItem value="usage" label="Usage" default>
<SandpackEditor <SandpackEditor
availableComponentPaths={['@/ui/display/chip/components/Chip']} availableComponentPaths={['twenty-ui']}
componentCode={chipCode} componentCode={chipCode}
/> />
</TabItem> </TabItem>
@@ -117,8 +117,8 @@ A visual element that you can use as a clickable or non-clickable container with
### Transparent Disabled Chip ### Transparent Disabled Chip
<SandpackEditor <SandpackEditor
availableComponentPaths={['@/ui/display/chip/components/Chip']} availableComponentPaths={['twenty-ui']}
componentCode={`import { Chip } from "@/ui/display/chip/components/Chip"; componentCode={`import { Chip } from "twenty-ui";
export const MyComponent = () => { export const MyComponent = () => {
return ( return (
@@ -144,8 +144,8 @@ export const MyComponent = () => {
### Disabled Chip with Tooltip ### Disabled Chip with Tooltip
<SandpackEditor <SandpackEditor
availableComponentPaths={['@/ui/display/chip/components/Chip']} availableComponentPaths={['twenty-ui']}
componentCode={`import { Chip } from "@/ui/display/chip/components/Chip"; componentCode={`import { Chip } from "twenty-ui";
export const MyComponent = () => { export const MyComponent = () => {
return ( return (
@@ -176,7 +176,7 @@ A Chip-like element to display information about an entity.
<TabItem value="usage" label="Usage" default> <TabItem value="usage" label="Usage" default>
<SandpackEditor <SandpackEditor
availableComponentPaths={['@/ui/display/chip/components/EntityChip', 'twenty-ui']} availableComponentPaths={['twenty-ui']}
componentCode={entityChipCode} componentCode={entityChipCode}
/> />
</TabItem > </TabItem >
@@ -1,4 +1,4 @@
import { AnimatedCheckmark } from "@/ui/display/checkmark/components/AnimatedCheckmark"; import { AnimatedCheckmark } from 'twenty-ui';
export const MyComponent = () => { export const MyComponent = () => {
return ( return (
@@ -9,6 +9,4 @@ export const MyComponent = () => {
size={30} size={30}
/> />
); );
}; };
@@ -1,4 +1,4 @@
import { Checkmark } from "@/ui/display/checkmark/components/Checkmark"; import { Checkmark } from 'twenty-ui';
export const MyComponent = () => { export const MyComponent = () => {
return <Checkmark />; return <Checkmark />;
@@ -1,4 +1,4 @@
import { Chip } from "@/ui/display/chip/components/Chip"; import { Chip } from 'twenty-ui';
export const MyComponent = () => { export const MyComponent = () => {
return ( return (
@@ -1,7 +1,5 @@
import { BrowserRouter as Router } from 'react-router-dom'; import { BrowserRouter as Router } from 'react-router-dom';
import { IconTwentyStar } from 'twenty-ui'; import { EntityChip, IconTwentyStar } from 'twenty-ui';
import { EntityChip } from '@/ui/display/chip/components/EntityChip';
export const MyComponent = () => { export const MyComponent = () => {
return ( return (
@@ -1,8 +1,8 @@
import { OverflowingTextWithTooltip } from "@/ui/display/tooltip/OverflowingTextWithTooltip"; import { OverflowingTextWithTooltip } from 'twenty-ui';
export const MyComponent = () => { export const MyComponent = () => {
const crmTaskDescription = const crmTaskDescription =
"Follow up with client regarding their recent product inquiry. Discuss pricing options, address any concerns, and provide additional product information. Record the details of the conversation in the CRM for future reference."; 'Follow up with client regarding their recent product inquiry. Discuss pricing options, address any concerns, and provide additional product information. Record the details of the conversation in the CRM for future reference.';
return <OverflowingTextWithTooltip text={crmTaskDescription} />; return <OverflowingTextWithTooltip text={crmTaskDescription} />;
}; };
@@ -1,7 +1,13 @@
import React from 'react'; import React from 'react';
import { css, useTheme } from '@emotion/react'; import { css, useTheme } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { IconCalendarEvent } from 'twenty-ui'; import {
Chip,
ChipAccent,
ChipSize,
ChipVariant,
IconCalendarEvent,
} from 'twenty-ui';
import { CalendarEventParticipantsResponseStatus } from '@/activities/calendar/components/CalendarEventParticipantsResponseStatus'; import { CalendarEventParticipantsResponseStatus } from '@/activities/calendar/components/CalendarEventParticipantsResponseStatus';
import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent'; import { CalendarEvent } from '@/activities/calendar/types/CalendarEvent';
@@ -11,12 +17,6 @@ import { formatFieldMetadataItemAsFieldDefinition } from '@/object-metadata/util
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext'; import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell'; import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell';
import { PropertyBox } from '@/object-record/record-inline-cell/property-box/components/PropertyBox'; import { PropertyBox } from '@/object-record/record-inline-cell/property-box/components/PropertyBox';
import {
Chip,
ChipAccent,
ChipSize,
ChipVariant,
} from '@/ui/display/chip/components/Chip';
import { mapArrayToObject } from '~/utils/array/mapArrayToObject'; import { mapArrayToObject } from '~/utils/array/mapArrayToObject';
import { beautifyPastDateRelativeToNow } from '~/utils/date-utils'; import { beautifyPastDateRelativeToNow } from '~/utils/date-utils';
@@ -3,7 +3,7 @@ import { css, useTheme } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { format } from 'date-fns'; import { format } from 'date-fns';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { IconArrowRight, IconLock } from 'twenty-ui'; import { Avatar, AvatarGroup, IconArrowRight, IconLock } from 'twenty-ui';
import { CalendarCurrentEventCursor } from '@/activities/calendar/components/CalendarCurrentEventCursor'; import { CalendarCurrentEventCursor } from '@/activities/calendar/components/CalendarCurrentEventCursor';
import { CalendarContext } from '@/activities/calendar/contexts/CalendarContext'; import { CalendarContext } from '@/activities/calendar/contexts/CalendarContext';
@@ -14,9 +14,8 @@ import { hasCalendarEventEnded } from '@/activities/calendar/utils/hasCalendarEv
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { Card } from '@/ui/layout/card/components/Card'; import { Card } from '@/ui/layout/card/components/Card';
import { CardContent } from '@/ui/layout/card/components/CardContent'; import { CardContent } from '@/ui/layout/card/components/CardContent';
import { Avatar } from '@/users/components/Avatar';
import { AvatarGroup } from '@/users/components/AvatarGroup';
import { TimelineCalendarEvent } from '~/generated-metadata/graphql'; import { TimelineCalendarEvent } from '~/generated-metadata/graphql';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
import { isDefined } from '~/utils/isDefined'; import { isDefined } from '~/utils/isDefined';
type CalendarEventRowProps = { type CalendarEventRowProps = {
@@ -161,7 +160,7 @@ export const CalendarEventRow = ({
key={[participant.workspaceMemberId, participant.displayName] key={[participant.workspaceMemberId, participant.displayName]
.filter(isDefined) .filter(isDefined)
.join('-')} .join('-')}
avatarUrl={participant.avatarUrl} avatarUrl={getImageAbsoluteURIOrBase64(participant.avatarUrl)}
placeholder={ placeholder={
participant.firstName && participant.lastName participant.firstName && participant.lastName
? `${participant.firstName} ${participant.lastName}` ? `${participant.firstName} ${participant.lastName}`
@@ -1,12 +1,13 @@
import { Tooltip } from 'react-tooltip'; import { Tooltip } from 'react-tooltip';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { Avatar } from 'twenty-ui';
import { Comment } from '@/activities/types/Comment'; import { Comment } from '@/activities/types/Comment';
import { Avatar } from '@/users/components/Avatar';
import { import {
beautifyExactDateTime, beautifyExactDateTime,
beautifyPastDateRelativeToNow, beautifyPastDateRelativeToNow,
} from '~/utils/date-utils'; } from '~/utils/date-utils';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
const StyledContainer = styled.div` const StyledContainer = styled.div`
align-items: center; align-items: center;
@@ -75,7 +76,7 @@ export const CommentHeader = ({ comment, actionBar }: CommentHeaderProps) => {
<StyledContainer> <StyledContainer>
<StyledLeftContainer> <StyledLeftContainer>
<Avatar <Avatar
avatarUrl={avatarUrl} avatarUrl={getImageAbsoluteURIOrBase64(avatarUrl)}
size="md" size="md"
entityId={author?.id} entityId={author?.id}
placeholder={authorName} placeholder={authorName}
@@ -1,10 +1,10 @@
import { useMemo } from 'react'; import { useMemo } from 'react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { Chip, ChipVariant } from 'twenty-ui';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
import { ActivityTargetWithTargetRecord } from '@/activities/types/ActivityTargetObject'; import { ActivityTargetWithTargetRecord } from '@/activities/types/ActivityTargetObject';
import { RecordChip } from '@/object-record/components/RecordChip'; import { RecordChip } from '@/object-record/components/RecordChip';
import { Chip, ChipVariant } from '@/ui/display/chip/components/Chip';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { RGBA } from '@/ui/theme/constants/Rgba'; import { RGBA } from '@/ui/theme/constants/Rgba';
@@ -1,14 +1,15 @@
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import { useRecoilState } from 'recoil'; import { useRecoilState } from 'recoil';
import { IconCheckbox, IconNotes } from 'twenty-ui';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { import {
Chip, Chip,
ChipAccent, ChipAccent,
ChipSize, ChipSize,
ChipVariant, ChipVariant,
} from '@/ui/display/chip/components/Chip'; IconCheckbox,
IconNotes,
} from 'twenty-ui';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
type ActivityTypeDropdownProps = { type ActivityTypeDropdownProps = {
activityId: string; activityId: string;
@@ -1,9 +1,10 @@
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { Avatar } from 'twenty-ui';
import { getDisplayNameFromParticipant } from '@/activities/emails/utils/getDisplayNameFromParticipant'; import { getDisplayNameFromParticipant } from '@/activities/emails/utils/getDisplayNameFromParticipant';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { RecordChip } from '@/object-record/components/RecordChip'; import { RecordChip } from '@/object-record/components/RecordChip';
import { Avatar } from '@/users/components/Avatar'; import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
const StyledAvatar = styled(Avatar)` const StyledAvatar = styled(Avatar)`
margin-right: ${({ theme }) => theme.spacing(1)}; margin-right: ${({ theme }) => theme.spacing(1)};
@@ -67,7 +68,7 @@ export const ParticipantChip = ({
) : ( ) : (
<StyledChip> <StyledChip>
<StyledAvatar <StyledAvatar
avatarUrl={avatarUrl} avatarUrl={getImageAbsoluteURIOrBase64(avatarUrl)}
type="rounded" type="rounded"
placeholder={displayName} placeholder={displayName}
size="sm" size="sm"
@@ -1,8 +1,8 @@
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { OverflowingTextWithTooltip } from 'twenty-ui';
import { EmailThreadMessageParticipant } from '@/activities/emails/types/EmailThreadMessageParticipant'; import { EmailThreadMessageParticipant } from '@/activities/emails/types/EmailThreadMessageParticipant';
import { getDisplayNameFromParticipant } from '@/activities/emails/utils/getDisplayNameFromParticipant'; import { getDisplayNameFromParticipant } from '@/activities/emails/utils/getDisplayNameFromParticipant';
import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip';
type EmailThreadMessageReceiversProps = { type EmailThreadMessageReceiversProps = {
receivers: EmailThreadMessageParticipant[]; receivers: EmailThreadMessageParticipant[];
@@ -1,6 +1,7 @@
import { useRef } from 'react'; import { useRef } from 'react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { Avatar } from 'twenty-ui';
import { EmailThreadNotShared } from '@/activities/emails/components/EmailThreadNotShared'; import { EmailThreadNotShared } from '@/activities/emails/components/EmailThreadNotShared';
import { useEmailThread } from '@/activities/emails/hooks/useEmailThread'; import { useEmailThread } from '@/activities/emails/hooks/useEmailThread';
@@ -8,9 +9,9 @@ import { emailThreadIdWhenEmailThreadWasClosedState } from '@/activities/emails/
import { CardContent } from '@/ui/layout/card/components/CardContent'; import { CardContent } from '@/ui/layout/card/components/CardContent';
import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer'; import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer';
import { GRAY_SCALE } from '@/ui/theme/constants/GrayScale'; import { GRAY_SCALE } from '@/ui/theme/constants/GrayScale';
import { Avatar } from '@/users/components/Avatar';
import { TimelineThread } from '~/generated/graphql'; import { TimelineThread } from '~/generated/graphql';
import { formatToHumanReadableDate } from '~/utils'; import { formatToHumanReadableDate } from '~/utils';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
const StyledCardContent = styled(CardContent)<{ visibility: string }>` const StyledCardContent = styled(CardContent)<{ visibility: string }>`
align-items: center; align-items: center;
@@ -152,20 +153,24 @@ export const EmailThreadPreview = ({
<StyledHeading unread={!thread.read}> <StyledHeading unread={!thread.read}>
<StyledParticipantsContainer> <StyledParticipantsContainer>
<Avatar <Avatar
avatarUrl={thread?.firstParticipant?.avatarUrl} avatarUrl={getImageAbsoluteURIOrBase64(
thread?.firstParticipant?.avatarUrl,
)}
placeholder={thread.firstParticipant.displayName} placeholder={thread.firstParticipant.displayName}
type="rounded" type="rounded"
/> />
{thread?.lastTwoParticipants?.[0] && ( {thread?.lastTwoParticipants?.[0] && (
<StyledAvatar <StyledAvatar
avatarUrl={thread.lastTwoParticipants[0].avatarUrl} avatarUrl={getImageAbsoluteURIOrBase64(
thread.lastTwoParticipants[0].avatarUrl,
)}
placeholder={thread.lastTwoParticipants[0].displayName} placeholder={thread.lastTwoParticipants[0].displayName}
type="rounded" type="rounded"
/> />
)} )}
{finalDisplayedName && ( {finalDisplayedName && (
<StyledAvatar <StyledAvatar
avatarUrl={finalAvatarUrl} avatarUrl={getImageAbsoluteURIOrBase64(finalAvatarUrl)}
placeholder={finalDisplayedName} placeholder={finalDisplayedName}
type="rounded" type="rounded"
color={isCountIcon ? GRAY_SCALE.gray50 : undefined} color={isCountIcon ? GRAY_SCALE.gray50 : undefined}
@@ -1,5 +1,6 @@
import { useApolloClient } from '@apollo/client'; import { useApolloClient } from '@apollo/client';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { Nullable } from 'twenty-ui';
import { Activity } from '@/activities/types/Activity'; import { Activity } from '@/activities/types/Activity';
import { ActivityTarget } from '@/activities/types/ActivityTarget'; import { ActivityTarget } from '@/activities/types/ActivityTarget';
@@ -7,7 +8,6 @@ import { ActivityTargetWithTargetRecord } from '@/activities/types/ActivityTarge
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useGetRecordFromCache } from '@/object-record/cache/hooks/useGetRecordFromCache'; import { useGetRecordFromCache } from '@/object-record/cache/hooks/useGetRecordFromCache';
import { Nullable } from '~/types/Nullable';
import { isDefined } from '~/utils/isDefined'; import { isDefined } from '~/utils/isDefined';
export const useActivityTargetObjectRecords = (activity: Activity) => { export const useActivityTargetObjectRecords = (activity: Activity) => {
@@ -1,13 +1,16 @@
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { IconCalendar, IconComment } from 'twenty-ui'; import {
IconCalendar,
IconComment,
OverflowingTextWithTooltip,
} from 'twenty-ui';
import { ActivityTargetChips } from '@/activities/components/ActivityTargetChips'; import { ActivityTargetChips } from '@/activities/components/ActivityTargetChips';
import { useActivityTargetObjectRecords } from '@/activities/hooks/useActivityTargetObjectRecords'; import { useActivityTargetObjectRecords } from '@/activities/hooks/useActivityTargetObjectRecords';
import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer'; import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer';
import { Activity } from '@/activities/types/Activity'; import { Activity } from '@/activities/types/Activity';
import { getActivitySummary } from '@/activities/utils/getActivitySummary'; import { getActivitySummary } from '@/activities/utils/getActivitySummary';
import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip';
import { Checkbox, CheckboxShape } from '@/ui/input/components/Checkbox'; import { Checkbox, CheckboxShape } from '@/ui/input/components/Checkbox';
import { beautifyExactDate, hasDatePassed } from '~/utils/date-utils'; import { beautifyExactDate, hasDatePassed } from '~/utils/date-utils';
@@ -2,17 +2,17 @@ import { Tooltip } from 'react-tooltip';
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { IconCheckbox, IconNotes } from 'twenty-ui'; import { Avatar, IconCheckbox, IconNotes } from 'twenty-ui';
import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer'; import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer';
import { timelineActivityWithoutTargetsFamilyState } from '@/activities/timeline/states/timelineActivityWithoutTargetsFamilyState'; import { timelineActivityWithoutTargetsFamilyState } from '@/activities/timeline/states/timelineActivityWithoutTargetsFamilyState';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { Avatar } from '@/users/components/Avatar';
import { import {
beautifyExactDateTime, beautifyExactDateTime,
beautifyPastDateRelativeToNow, beautifyPastDateRelativeToNow,
} from '~/utils/date-utils'; } from '~/utils/date-utils';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
const StyledAvatarContainer = styled.div` const StyledAvatarContainer = styled.div`
align-items: center; align-items: center;
@@ -170,7 +170,9 @@ export const TimelineActivity = ({
<StyledTimelineItemContainer> <StyledTimelineItemContainer>
<StyledAvatarContainer> <StyledAvatarContainer>
<Avatar <Avatar
avatarUrl={activityForTimeline.author?.avatarUrl} avatarUrl={getImageAbsoluteURIOrBase64(
activityForTimeline.author?.avatarUrl,
)}
placeholder={activityForTimeline.author?.name.firstName ?? ''} placeholder={activityForTimeline.author?.name.firstName ?? ''}
size="sm" size="sm"
type="rounded" type="rounded"
@@ -1,7 +1,7 @@
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { OverflowingTextWithTooltip } from 'twenty-ui';
import { ActivityType } from '@/activities/types/Activity'; import { ActivityType } from '@/activities/types/Activity';
import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip';
import { Checkbox, CheckboxShape } from '@/ui/input/components/Checkbox'; import { Checkbox, CheckboxShape } from '@/ui/input/components/Checkbox';
const StyledTitleContainer = styled.div` const StyledTitleContainer = styled.div`
@@ -1,6 +1,6 @@
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { getImageAbsoluteURIOrBase64 } from '@/users/utils/getProfilePictureAbsoluteURI'; import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
type LogoProps = { type LogoProps = {
workspaceLogo?: string | null; workspaceLogo?: string | null;
@@ -3,7 +3,7 @@ import styled from '@emotion/styled';
import { isNonEmptyString } from '@sniptt/guards'; import { isNonEmptyString } from '@sniptt/guards';
import { useRecoilState, useRecoilValue } from 'recoil'; import { useRecoilState, useRecoilValue } from 'recoil';
import { Key } from 'ts-key-enum'; import { Key } from 'ts-key-enum';
import { IconNotes } from 'twenty-ui'; import { Avatar, IconNotes } from 'twenty-ui';
import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer'; import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer';
import { Activity } from '@/activities/types/Activity'; import { Activity } from '@/activities/types/Activity';
@@ -21,7 +21,6 @@ import { AppHotkeyScope } from '@/ui/utilities/hotkey/types/AppHotkeyScope';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside'; import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
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';
import { Avatar } from '@/users/components/Avatar';
import { getLogoUrlFromDomainName } from '~/utils'; import { getLogoUrlFromDomainName } from '~/utils';
import { isDefined } from '~/utils/isDefined'; import { isDefined } from '~/utils/isDefined';
@@ -1,11 +1,12 @@
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { Avatar } from 'twenty-ui';
import { DraggableItem } from '@/ui/layout/draggable-list/components/DraggableItem'; import { DraggableItem } from '@/ui/layout/draggable-list/components/DraggableItem';
import { DraggableList } from '@/ui/layout/draggable-list/components/DraggableList'; import { DraggableList } from '@/ui/layout/draggable-list/components/DraggableList';
import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem'; import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem';
import { NavigationDrawerSection } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSection'; import { NavigationDrawerSection } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSection';
import { NavigationDrawerSectionTitle } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSectionTitle'; import { NavigationDrawerSectionTitle } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSectionTitle';
import { Avatar } from '@/users/components/Avatar'; import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
import { useFavorites } from '../hooks/useFavorites'; import { useFavorites } from '../hooks/useFavorites';
@@ -63,7 +64,7 @@ export const Favorites = () => {
Icon={() => ( Icon={() => (
<StyledAvatar <StyledAvatar
entityId={recordId} entityId={recordId}
avatarUrl={avatarUrl} avatarUrl={getImageAbsoluteURIOrBase64(avatarUrl)}
type={avatarType} type={avatarType}
placeholder={labelIdentifier} placeholder={labelIdentifier}
className="fav-avatar" className="fav-avatar"
@@ -1,6 +1,6 @@
import { gql } from '@apollo/client'; import { gql } from '@apollo/client';
import { AvatarType } from 'twenty-ui';
import { AvatarType } from '@/users/components/Avatar';
import { ColorScheme } from '@/workspace-member/types/WorkspaceMember'; import { ColorScheme } from '@/workspace-member/types/WorkspaceMember';
export const mockId = '8f3b2121-f194-4ba4-9fbf-2d5a37126806'; export const mockId = '8f3b2121-f194-4ba4-9fbf-2d5a37126806';
@@ -1,4 +1,4 @@
import { AvatarType } from '@/users/components/Avatar'; import { AvatarType } from 'twenty-ui';
export type Favorite = { export type Favorite = {
id: string; id: string;
@@ -11,7 +11,7 @@ import {
} from '@/ui/navigation/navigation-drawer/components/NavigationDrawer'; } from '@/ui/navigation/navigation-drawer/components/NavigationDrawer';
import { isNavigationDrawerOpenState } from '@/ui/navigation/states/isNavigationDrawerOpenState'; import { isNavigationDrawerOpenState } from '@/ui/navigation/states/isNavigationDrawerOpenState';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { getImageAbsoluteURIOrBase64 } from '@/users/utils/getProfilePictureAbsoluteURI'; import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
import { useIsSettingsPage } from '../hooks/useIsSettingsPage'; import { useIsSettingsPage } from '../hooks/useIsSettingsPage';
import { currentMobileNavigationDrawerState } from '../states/currentMobileNavigationDrawerState'; import { currentMobileNavigationDrawerState } from '../states/currentMobileNavigationDrawerState';
@@ -1,9 +1,9 @@
import { renderHook } from '@testing-library/react'; import { renderHook } from '@testing-library/react';
import { Nullable } from 'twenty-ui';
import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata'; import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock'; import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
import { Nullable } from '~/types/Nullable';
describe('useColumnDefinitionsFromFieldMetadata', () => { describe('useColumnDefinitionsFromFieldMetadata', () => {
it('should return empty definitions if no object is passed', () => { it('should return empty definitions if no object is passed', () => {
@@ -1,10 +1,10 @@
import { useMemo } from 'react'; import { useMemo } from 'react';
import { Nullable } from 'twenty-ui';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata'; import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition'; import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
import { filterAvailableTableColumns } from '@/object-record/utils/filterAvailableTableColumns'; import { filterAvailableTableColumns } from '@/object-record/utils/filterAvailableTableColumns';
import { Nullable } from '~/types/Nullable';
import { formatFieldMetadataItemAsColumnDefinition } from '../utils/formatFieldMetadataItemAsColumnDefinition'; import { formatFieldMetadataItemAsColumnDefinition } from '../utils/formatFieldMetadataItemAsColumnDefinition';
import { formatFieldMetadataItemsAsFilterDefinitions } from '../utils/formatFieldMetadataItemsAsFilterDefinitions'; import { formatFieldMetadataItemsAsFilterDefinitions } from '../utils/formatFieldMetadataItemsAsFilterDefinitions';
@@ -1,8 +1,8 @@
import * as React from 'react'; import { EntityChip } from 'twenty-ui';
import { useMapToObjectRecordIdentifier } from '@/object-metadata/hooks/useMapToObjectRecordIdentifier'; import { useMapToObjectRecordIdentifier } from '@/object-metadata/hooks/useMapToObjectRecordIdentifier';
import { ObjectRecord } from '@/object-record/types/ObjectRecord'; import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { EntityChip } from '@/ui/display/chip/components/EntityChip'; import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
export type RecordChipProps = { export type RecordChipProps = {
objectNameSingular: string; objectNameSingular: string;
@@ -28,7 +28,9 @@ export const RecordChip = ({
entityId={record.id} entityId={record.id}
name={objectRecordIdentifier.name} name={objectRecordIdentifier.name}
avatarType={objectRecordIdentifier.avatarType} avatarType={objectRecordIdentifier.avatarType}
avatarUrl={objectRecordIdentifier.avatarUrl} avatarUrl={
getImageAbsoluteURIOrBase64(objectRecordIdentifier.avatarUrl) || ''
}
linkToEntity={objectRecordIdentifier.linkToShowPage} linkToEntity={objectRecordIdentifier.linkToShowPage}
maxWidth={maxWidth} maxWidth={maxWidth}
className={className} className={className}
@@ -1,6 +1,6 @@
import { IconComponent } from 'twenty-ui'; import { EntityChip, IconComponent } from 'twenty-ui';
import { EntityChip } from '@/ui/display/chip/components/EntityChip'; import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
import { Filter } from '../types/Filter'; import { Filter } from '../types/Filter';
@@ -17,7 +17,7 @@ export const GenericEntityFilterChip = ({
entityId={filter.value} entityId={filter.value}
name={filter.displayValue} name={filter.displayValue}
avatarType="rounded" avatarType="rounded"
avatarUrl={filter.displayAvatarUrl} avatarUrl={getImageAbsoluteURIOrBase64(filter.displayAvatarUrl) || ''}
LeftIcon={Icon} LeftIcon={Icon}
/> />
); );
@@ -1,6 +1,7 @@
import { Nullable } from 'twenty-ui';
import { useDateField } from '@/object-record/record-field/meta-types/hooks/useDateField'; import { useDateField } from '@/object-record/record-field/meta-types/hooks/useDateField';
import { DateInput } from '@/ui/field/input/components/DateInput'; import { DateInput } from '@/ui/field/input/components/DateInput';
import { Nullable } from '~/types/Nullable';
import { usePersistField } from '../../../hooks/usePersistField'; import { usePersistField } from '../../../hooks/usePersistField';
@@ -1,5 +1,6 @@
import { Nullable } from 'twenty-ui';
import { DateInput } from '@/ui/field/input/components/DateInput'; import { DateInput } from '@/ui/field/input/components/DateInput';
import { Nullable } from '~/types/Nullable';
import { usePersistField } from '../../../hooks/usePersistField'; import { usePersistField } from '../../../hooks/usePersistField';
import { useDateTimeField } from '../../hooks/useDateTimeField'; import { useDateTimeField } from '../../hooks/useDateTimeField';
@@ -1,5 +1,6 @@
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { Avatar } from 'twenty-ui';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
import { MULTI_OBJECT_RECORD_SELECT_SELECTABLE_LIST_ID } from '@/object-record/relation-picker/constants/MultiObjectRecordSelectSelectableListId'; import { MULTI_OBJECT_RECORD_SELECT_SELECTABLE_LIST_ID } from '@/object-record/relation-picker/constants/MultiObjectRecordSelectSelectableListId';
@@ -7,7 +8,7 @@ import { ObjectRecordForSelect } from '@/object-record/relation-picker/hooks/use
import { SelectableItem } from '@/ui/layout/selectable-list/components/SelectableItem'; import { SelectableItem } from '@/ui/layout/selectable-list/components/SelectableItem';
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList'; import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
import { MenuItemMultiSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemMultiSelectAvatar'; import { MenuItemMultiSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemMultiSelectAvatar';
import { Avatar } from '@/users/components/Avatar'; import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
export const StyledSelectableItem = styled(SelectableItem)` export const StyledSelectableItem = styled(SelectableItem)`
height: 100%; height: 100%;
@@ -42,7 +43,9 @@ export const MultipleObjectRecordSelectItem = ({
isKeySelected={isSelectedByKeyboard} isKeySelected={isSelectedByKeyboard}
avatar={ avatar={
<Avatar <Avatar
avatarUrl={objectRecordForSelect.recordIdentifier.avatarUrl} avatarUrl={getImageAbsoluteURIOrBase64(
objectRecordForSelect.recordIdentifier.avatarUrl,
)}
entityId={objectRecordForSelect.record.id} entityId={objectRecordForSelect.record.id}
placeholder={objectRecordForSelect.recordIdentifier.name} placeholder={objectRecordForSelect.recordIdentifier.name}
size="md" size="md"
@@ -1,11 +1,12 @@
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { Avatar } from 'twenty-ui';
import { EntityForSelect } from '@/object-record/relation-picker/types/EntityForSelect'; import { EntityForSelect } from '@/object-record/relation-picker/types/EntityForSelect';
import { SelectableItem } from '@/ui/layout/selectable-list/components/SelectableItem'; import { SelectableItem } from '@/ui/layout/selectable-list/components/SelectableItem';
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList'; import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
import { MenuItemSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemSelectAvatar'; import { MenuItemSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemSelectAvatar';
import { Avatar } from '@/users/components/Avatar'; import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
type SelectableMenuItemSelectProps = { type SelectableMenuItemSelectProps = {
entity: EntityForSelect; entity: EntityForSelect;
@@ -39,7 +40,7 @@ export const SelectableMenuItemSelect = ({
hovered={isSelectedItemId} hovered={isSelectedItemId}
avatar={ avatar={
<Avatar <Avatar
avatarUrl={entity.avatarUrl} avatarUrl={getImageAbsoluteURIOrBase64(entity.avatarUrl)}
entityId={entity.id} entityId={entity.id}
placeholder={entity.name} placeholder={entity.name}
size="md" size="md"
@@ -1,11 +1,12 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { Avatar } from 'twenty-ui';
import { SelectableRecord } from '@/object-record/select/types/SelectableRecord'; import { SelectableRecord } from '@/object-record/select/types/SelectableRecord';
import { DropdownMenuSkeletonItem } from '@/ui/input/relation-picker/components/skeletons/DropdownMenuSkeletonItem'; import { DropdownMenuSkeletonItem } from '@/ui/input/relation-picker/components/skeletons/DropdownMenuSkeletonItem';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
import { MenuItemMultiSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemMultiSelectAvatar'; import { MenuItemMultiSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemMultiSelectAvatar';
import { Avatar } from '@/users/components/Avatar'; import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
export const MultipleRecordSelectDropdown = ({ export const MultipleRecordSelectDropdown = ({
recordsToSelect, recordsToSelect,
@@ -68,7 +69,7 @@ export const MultipleRecordSelectDropdown = ({
} }
avatar={ avatar={
<Avatar <Avatar
avatarUrl={record.avatarUrl} avatarUrl={getImageAbsoluteURIOrBase64(record.avatarUrl)}
entityId={record.id} entityId={record.id}
placeholder={record.name} placeholder={record.name}
size="md" size="md"
@@ -1,4 +1,4 @@
import { AvatarType } from '@/users/components/Avatar'; import { AvatarType } from 'twenty-ui';
export type SelectableRecord = { export type SelectableRecord = {
id: string; id: string;
@@ -1,6 +1,7 @@
import { Nullable } from 'twenty-ui';
import { ObjectRecord } from '@/object-record/types/ObjectRecord'; import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { ObjectRecordEdge } from '@/object-record/types/ObjectRecordEdge'; import { ObjectRecordEdge } from '@/object-record/types/ObjectRecordEdge';
import { Nullable } from '~/types/Nullable';
export type ObjectRecordConnection<T extends ObjectRecord = ObjectRecord> = { export type ObjectRecordConnection<T extends ObjectRecord = ObjectRecord> = {
__typename?: string; __typename?: string;
@@ -1,4 +1,4 @@
import { AvatarType } from '@/users/components/Avatar'; import { AvatarType } from 'twenty-ui';
export type ObjectRecordIdentifier = { export type ObjectRecordIdentifier = {
id: string; id: string;
@@ -1,7 +1,6 @@
import { import { EntityChip, EntityChipVariant } from 'twenty-ui';
EntityChip,
EntityChipVariant, import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
} from '@/ui/display/chip/components/EntityChip';
export type PersonChipProps = { export type PersonChipProps = {
id: string; id: string;
@@ -21,7 +20,7 @@ export const PersonChip = ({
linkToEntity={`/person/${id}`} linkToEntity={`/person/${id}`}
name={name} name={name}
avatarType="rounded" avatarType="rounded"
avatarUrl={avatarUrl} avatarUrl={getImageAbsoluteURIOrBase64(avatarUrl) || ''}
variant={variant} variant={variant}
/> />
); );
@@ -2,7 +2,7 @@ import { ReactNode, useMemo } from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { useIcons } from 'twenty-ui'; import { Nullable, useIcons } from 'twenty-ui';
import { useGetRelationMetadata } from '@/object-metadata/hooks/useGetRelationMetadata'; import { useGetRelationMetadata } from '@/object-metadata/hooks/useGetRelationMetadata';
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
@@ -11,7 +11,6 @@ import { FieldIdentifierType } from '@/settings/data-model/types/FieldIdentifier
import { isFieldTypeSupportedInSettings } from '@/settings/data-model/utils/isFieldTypeSupportedInSettings'; import { isFieldTypeSupportedInSettings } from '@/settings/data-model/utils/isFieldTypeSupportedInSettings';
import { TableCell } from '@/ui/layout/table/components/TableCell'; import { TableCell } from '@/ui/layout/table/components/TableCell';
import { TableRow } from '@/ui/layout/table/components/TableRow'; import { TableRow } from '@/ui/layout/table/components/TableRow';
import { Nullable } from '~/types/Nullable';
import { RELATION_TYPES } from '../../constants/RelationTypes'; import { RELATION_TYPES } from '../../constants/RelationTypes';
@@ -5,8 +5,8 @@ import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMembe
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import { ImageInput } from '@/ui/input/components/ImageInput'; import { ImageInput } from '@/ui/input/components/ImageInput';
import { getImageAbsoluteURIOrBase64 } from '@/users/utils/getProfilePictureAbsoluteURI';
import { useUploadProfilePictureMutation } from '~/generated/graphql'; import { useUploadProfilePictureMutation } from '~/generated/graphql';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
import { isDefined } from '~/utils/isDefined'; import { isDefined } from '~/utils/isDefined';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
@@ -2,11 +2,11 @@ import { useRecoilState } from 'recoil';
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState'; import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { ImageInput } from '@/ui/input/components/ImageInput'; import { ImageInput } from '@/ui/input/components/ImageInput';
import { getImageAbsoluteURIOrBase64 } from '@/users/utils/getProfilePictureAbsoluteURI';
import { import {
useUpdateWorkspaceMutation, useUpdateWorkspaceMutation,
useUploadWorkspaceLogoMutation, useUploadWorkspaceLogoMutation,
} from '~/generated/graphql'; } from '~/generated/graphql';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull'; import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
export const WorkspaceLogoUploader = () => { export const WorkspaceLogoUploader = () => {
@@ -9,11 +9,11 @@ import {
size, size,
useFloating, useFloating,
} from '@floating-ui/react'; } from '@floating-ui/react';
import { AppTooltip } from 'twenty-ui';
import { ReadonlyDeep } from 'type-fest'; import { ReadonlyDeep } from 'type-fest';
import { useDebouncedCallback } from 'use-debounce'; import { useDebouncedCallback } from 'use-debounce';
import { SelectOption } from '@/spreadsheet-import/types'; import { SelectOption } from '@/spreadsheet-import/types';
import { AppTooltip } from '@/ui/display/tooltip/AppTooltip';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu'; import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput'; import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
@@ -2,9 +2,9 @@
import { Column } from 'react-data-grid'; import { Column } from 'react-data-grid';
import { createPortal } from 'react-dom'; import { createPortal } from 'react-dom';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { AppTooltip } from 'twenty-ui';
import { Fields } from '@/spreadsheet-import/types'; import { Fields } from '@/spreadsheet-import/types';
import { AppTooltip } from '@/ui/display/tooltip/AppTooltip';
const StyledHeaderContainer = styled.div` const StyledHeaderContainer = styled.div`
align-items: center; align-items: center;
@@ -2,10 +2,10 @@
import { Column, useRowSelection } from 'react-data-grid'; import { Column, useRowSelection } from 'react-data-grid';
import { createPortal } from 'react-dom'; import { createPortal } from 'react-dom';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { AppTooltip } from 'twenty-ui';
import { MatchColumnSelect } from '@/spreadsheet-import/components/MatchColumnSelect'; import { MatchColumnSelect } from '@/spreadsheet-import/components/MatchColumnSelect';
import { Data, Fields } from '@/spreadsheet-import/types'; import { Data, Fields } from '@/spreadsheet-import/types';
import { AppTooltip } from '@/ui/display/tooltip/AppTooltip';
import { Checkbox, CheckboxVariant } from '@/ui/input/components/Checkbox'; import { Checkbox, CheckboxVariant } from '@/ui/input/components/Checkbox';
import { TextInput } from '@/ui/input/components/TextInput'; import { TextInput } from '@/ui/input/components/TextInput';
import { Toggle } from '@/ui/input/components/Toggle'; import { Toggle } from '@/ui/input/components/Toggle';
@@ -1,8 +1,8 @@
import React, { ReactElement, useRef, useState } from 'react'; import React, { ReactElement, useRef, useState } from 'react';
import { createPortal } from 'react-dom'; import { createPortal } from 'react-dom';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { Chip, ChipVariant } from 'twenty-ui';
import { Chip, ChipVariant } from '@/ui/display/chip/components/Chip';
import { IntersectionObserverWrapper } from '@/ui/display/expandable-list/IntersectionObserverWrapper'; import { IntersectionObserverWrapper } from '@/ui/display/expandable-list/IntersectionObserverWrapper';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
@@ -1,12 +1,10 @@
import { Meta, StoryObj } from '@storybook/react'; import { Meta, StoryObj } from '@storybook/react';
import { CatalogDecorator, CatalogStory, ComponentDecorator } from 'twenty-ui';
import { Info, InfoAccent } from '@/ui/display/info/components/Info.tsx'; import { Info, InfoAccent } from '@/ui/display/info/components/Info';
import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator.tsx';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator.tsx';
import { CatalogStory } from '~/testing/types.ts';
const meta: Meta<typeof Info> = { const meta: Meta<typeof Info> = {
title: 'UI/Display/Info/Info', title: 'UI/Display/Info',
component: Info, component: Info,
}; };
@@ -1,4 +1,4 @@
import { OverflowingTextWithTooltip } from '../../../display/tooltip/OverflowingTextWithTooltip'; import { OverflowingTextWithTooltip } from 'twenty-ui';
import { EllipsisDisplay } from './EllipsisDisplay'; import { EllipsisDisplay } from './EllipsisDisplay';
@@ -2,11 +2,11 @@ import { useRef, useState } from 'react';
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { flip, offset, useFloating } from '@floating-ui/react'; import { flip, offset, useFloating } from '@floating-ui/react';
import { Nullable } from 'twenty-ui';
import { useRegisterInputEvents } from '@/object-record/record-field/meta-types/input/hooks/useRegisterInputEvents'; import { useRegisterInputEvents } from '@/object-record/record-field/meta-types/input/hooks/useRegisterInputEvents';
import { DateDisplay } from '@/ui/field/display/components/DateDisplay'; import { DateDisplay } from '@/ui/field/display/components/DateDisplay';
import { InternalDatePicker } from '@/ui/input/components/internal/date/components/InternalDatePicker'; import { InternalDatePicker } from '@/ui/input/components/internal/date/components/InternalDatePicker';
import { Nullable } from '~/types/Nullable';
const StyledCalendarContainer = styled.div` const StyledCalendarContainer = styled.div`
background: ${({ theme }) => theme.background.secondary}; background: ${({ theme }) => theme.background.secondary};
@@ -6,8 +6,8 @@ import {
motion, motion,
useAnimation, useAnimation,
} from 'framer-motion'; } from 'framer-motion';
import { Checkmark } from 'twenty-ui';
import { Checkmark } from '@/ui/display/checkmark/components/Checkmark';
import { ColorScheme } from '@/workspace-member/types/WorkspaceMember'; import { ColorScheme } from '@/workspace-member/types/WorkspaceMember';
const StyledColorSchemeBackground = styled.div< const StyledColorSchemeBackground = styled.div<
@@ -3,14 +3,13 @@ import styled from '@emotion/styled';
import { Decorator, Meta, StoryObj } from '@storybook/react'; import { Decorator, Meta, StoryObj } from '@storybook/react';
import { expect, userEvent, waitFor, within } from '@storybook/test'; import { expect, userEvent, waitFor, within } from '@storybook/test';
import { PlayFunction } from '@storybook/types'; import { PlayFunction } from '@storybook/types';
import { Avatar, ComponentDecorator } from 'twenty-ui';
import { Button } from '@/ui/input/button/components/Button'; import { Button } from '@/ui/input/button/components/Button';
import { DropdownMenuSkeletonItem } from '@/ui/input/relation-picker/components/skeletons/DropdownMenuSkeletonItem'; import { DropdownMenuSkeletonItem } from '@/ui/input/relation-picker/components/skeletons/DropdownMenuSkeletonItem';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
import { MenuItemMultiSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemMultiSelectAvatar'; import { MenuItemMultiSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemMultiSelectAvatar';
import { MenuItemSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemSelectAvatar'; import { MenuItemSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemSelectAvatar';
import { Avatar } from '@/users/components/Avatar';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { Dropdown } from '../Dropdown'; import { Dropdown } from '../Dropdown';
import { DropdownMenuHeader } from '../DropdownMenuHeader'; import { DropdownMenuHeader } from '../DropdownMenuHeader';
@@ -4,9 +4,12 @@ import { useNavigate } from 'react-router-dom';
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { IconChevronLeft, IconComponent } from 'twenty-ui'; import {
IconChevronLeft,
IconComponent,
OverflowingTextWithTooltip,
} from 'twenty-ui';
import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip';
import { IconButton } from '@/ui/input/button/components/IconButton'; import { IconButton } from '@/ui/input/button/components/IconButton';
import { NavigationDrawerCollapseButton } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerCollapseButton'; import { NavigationDrawerCollapseButton } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerCollapseButton';
import { isNavigationDrawerOpenState } from '@/ui/navigation/states/isNavigationDrawerOpenState'; import { isNavigationDrawerOpenState } from '@/ui/navigation/states/isNavigationDrawerOpenState';
@@ -1,9 +1,9 @@
import { ChangeEvent, ReactNode, useRef } from 'react'; import { ChangeEvent, ReactNode, useRef } from 'react';
import { Tooltip } from 'react-tooltip'; import { Tooltip } from 'react-tooltip';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { Avatar, AvatarType } from 'twenty-ui';
import { v4 as uuidV4 } from 'uuid'; import { v4 as uuidV4 } from 'uuid';
import { Avatar, AvatarType } from '@/users/components/Avatar';
import { import {
beautifyExactDateTime, beautifyExactDateTime,
beautifyPastDateRelativeToNow, beautifyPastDateRelativeToNow,
@@ -1,8 +1,7 @@
import * as React from 'react'; import * as React from 'react';
import { Link as ReactLink } from 'react-router-dom'; import { Link as ReactLink } from 'react-router-dom';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { Chip, ChipSize, ChipVariant } from 'twenty-ui';
import { Chip, ChipSize, ChipVariant } from '@/ui/display/chip/components/Chip';
type RoundedLinkProps = { type RoundedLinkProps = {
href: string; href: string;
@@ -1,7 +1,7 @@
import { ReactNode } from 'react'; import { ReactNode } from 'react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { OverflowingTextWithTooltip } from 'twenty-ui';
import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip';
import { Checkbox } from '@/ui/input/components/Checkbox'; import { Checkbox } from '@/ui/input/components/Checkbox';
import { import {
@@ -1,8 +1,6 @@
import { ReactNode } from 'react'; import { ReactNode } from 'react';
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import { IconCheck } from 'twenty-ui'; import { IconCheck, OverflowingTextWithTooltip } from 'twenty-ui';
import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip';
import { import {
StyledMenuItemLabel, StyledMenuItemLabel,
@@ -1,14 +1,14 @@
import { Meta, StoryObj } from '@storybook/react'; import { Meta, StoryObj } from '@storybook/react';
import { Avatar } from '@/users/components/Avatar';
import { import {
Avatar,
CatalogDecorator, CatalogDecorator,
CatalogDimension, CatalogDimension,
CatalogOptions, CatalogOptions,
} from '~/testing/decorators/CatalogDecorator'; CatalogStory,
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator'; ComponentDecorator,
} from 'twenty-ui';
import { avatarUrl } from '~/testing/mock-data/users'; import { avatarUrl } from '~/testing/mock-data/users';
import { CatalogStory } from '~/testing/types';
import { MenuItemMultiSelectAvatar } from '../MenuItemMultiSelectAvatar'; import { MenuItemMultiSelectAvatar } from '../MenuItemMultiSelectAvatar';
@@ -1,14 +1,14 @@
import { Meta, StoryObj } from '@storybook/react'; import { Meta, StoryObj } from '@storybook/react';
import { Avatar } from '@/users/components/Avatar';
import { import {
Avatar,
CatalogDecorator, CatalogDecorator,
CatalogDimension, CatalogDimension,
CatalogOptions, CatalogOptions,
} from '~/testing/decorators/CatalogDecorator'; CatalogStory,
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator'; ComponentDecorator,
} from 'twenty-ui';
import { avatarUrl } from '~/testing/mock-data/users'; import { avatarUrl } from '~/testing/mock-data/users';
import { CatalogStory } from '~/testing/types';
import { MenuItemSelectAvatar } from '../MenuItemSelectAvatar'; import { MenuItemSelectAvatar } from '../MenuItemSelectAvatar';
@@ -1,7 +1,9 @@
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import { IconComponent, IconGripVertical } from 'twenty-ui'; import {
IconComponent,
import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip'; IconGripVertical,
OverflowingTextWithTooltip,
} from 'twenty-ui';
import { import {
StyledMenuItemLabel, StyledMenuItemLabel,
@@ -1,8 +1,8 @@
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import { AnimatedCheckmark } from 'twenty-ui';
import { AnimatedCheckmark } from '@/ui/display/checkmark/components/AnimatedCheckmark';
import { MOBILE_VIEWPORT } from '@/ui/theme/constants/MobileViewport'; import { MOBILE_VIEWPORT } from '@/ui/theme/constants/MobileViewport';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
@@ -1,4 +1,6 @@
import { EntityChip } from '@/ui/display/chip/components/EntityChip'; import { EntityChip } from 'twenty-ui';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
export type UserChipProps = { export type UserChipProps = {
id: string; id: string;
@@ -11,6 +13,6 @@ export const UserChip = ({ id, name, avatarUrl }: UserChipProps) => (
entityId={id} entityId={id}
name={name} name={name}
avatarType="rounded" avatarType="rounded"
avatarUrl={avatarUrl} avatarUrl={getImageAbsoluteURIOrBase64(avatarUrl) || ''}
/> />
); );
@@ -5,11 +5,16 @@ import {
OnDragEndResponder, OnDragEndResponder,
ResponderProvided, ResponderProvided,
} from '@hello-pangea/dnd'; } from '@hello-pangea/dnd';
import { IconInfoCircle, IconMinus, IconPlus, useIcons } from 'twenty-ui'; import {
AppTooltip,
IconInfoCircle,
IconMinus,
IconPlus,
useIcons,
} from 'twenty-ui';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata'; import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition'; import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
import { AppTooltip } from '@/ui/display/tooltip/AppTooltip';
import { DraggableItem } from '@/ui/layout/draggable-list/components/DraggableItem'; import { DraggableItem } from '@/ui/layout/draggable-list/components/DraggableItem';
import { DraggableList } from '@/ui/layout/draggable-list/components/DraggableList'; import { DraggableList } from '@/ui/layout/draggable-list/components/DraggableList';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
@@ -1,8 +1,8 @@
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { Avatar, OverflowingTextWithTooltip } from 'twenty-ui';
import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip';
import { Avatar } from '@/users/components/Avatar';
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember'; import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
const StyledContainer = styled.div` const StyledContainer = styled.div`
background: ${({ theme }) => theme.background.secondary}; background: ${({ theme }) => theme.background.secondary};
@@ -39,7 +39,7 @@ export const WorkspaceMemberCard = ({
}: WorkspaceMemberCardProps) => ( }: WorkspaceMemberCardProps) => (
<StyledContainer> <StyledContainer>
<Avatar <Avatar
avatarUrl={workspaceMember.avatarUrl} avatarUrl={getImageAbsoluteURIOrBase64(workspaceMember.avatarUrl)}
entityId={workspaceMember.id} entityId={workspaceMember.id}
placeholder={workspaceMember.name.firstName || ''} placeholder={workspaceMember.name.firstName || ''}
type="squared" type="squared"
@@ -1,13 +0,0 @@
import { Decorator } from '@storybook/react';
import { ComponentStorybookLayout } from '../ComponentStorybookLayout';
export const ComponentDecorator: Decorator = (Story, context) => {
const { container } = context.parameters;
return (
<ComponentStorybookLayout width={container?.width}>
<Story />
</ComponentStorybookLayout>
);
};
@@ -5,11 +5,7 @@ export const getImageAbsoluteURIOrBase64 = (imageUrl?: string | null) => {
return null; return null;
} }
if (imageUrl?.startsWith('data:')) { if (imageUrl?.startsWith('data:') || imageUrl?.startsWith('https:')) {
return imageUrl;
}
if (imageUrl?.startsWith('https:')) {
return imageUrl; return imageUrl;
} }
+2 -2
View File
@@ -14,13 +14,13 @@ module.exports = {
patterns: [ patterns: [
{ {
group: ['@tabler/icons-react'], group: ['@tabler/icons-react'],
message: 'Please import icons from `src/display`', message: 'Please import icons from `@ui/display`',
}, },
{ {
group: ['react-hotkeys-web-hook'], group: ['react-hotkeys-web-hook'],
importNames: ['useHotkeys'], importNames: ['useHotkeys'],
message: message:
'Please use the custom wrapper: `useScopedHotkeys` from `src/utilities`', 'Please use the custom wrapper: `useScopedHotkeys` from `@ui/utilities`',
}, },
], ],
}, },
+2 -2
View File
@@ -2,10 +2,10 @@
"name": "twenty-ui", "name": "twenty-ui",
"version": "0.4.0", "version": "0.4.0",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./src/index.ts",
"types": "./dist/index.d.ts",
"exports": { "exports": {
".": { ".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js", "import": "./dist/index.js",
"require": "./dist/index.cjs" "require": "./dist/index.cjs"
} }
@@ -2,10 +2,7 @@ import { useEffect, useState } from 'react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { isNonEmptyString } from '@sniptt/guards'; import { isNonEmptyString } from '@sniptt/guards';
import { Nullable } from '~/types/Nullable'; import { Nullable, stringToHslColor } from '@ui/utilities';
import { stringToHslColor } from '~/utils/string-to-hsl';
import { getImageAbsoluteURIOrBase64 } from '../utils/getProfilePictureAbsoluteURI';
export type AvatarType = 'squared' | 'rounded'; export type AvatarType = 'squared' | 'rounded';
@@ -93,7 +90,7 @@ export const Avatar = ({
const img = new Image(); const img = new Image();
img.onload = () => resolve(false); img.onload = () => resolve(false);
img.onerror = () => resolve(true); img.onerror = () => resolve(true);
img.src = getImageAbsoluteURIOrBase64(avatarUrl) as string; img.src = avatarUrl;
}).then((res) => { }).then((res) => {
setIsInvalidAvatarUrl(res as boolean); setIsInvalidAvatarUrl(res as boolean);
}); });
@@ -110,7 +107,7 @@ export const Avatar = ({
return ( return (
<StyledAvatar <StyledAvatar
className={className} className={className}
avatarUrl={getImageAbsoluteURIOrBase64(avatarUrl)} avatarUrl={avatarUrl}
placeholder={placeholder} placeholder={placeholder}
size={size} size={size}
type={type} type={type}
@@ -1,7 +1,6 @@
import { Meta, StoryObj } from '@storybook/react'; import { Meta, StoryObj } from '@storybook/react';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator'; import { AVATAR_URL_MOCK, ComponentDecorator } from '@ui/testing';
import { avatarUrl } from '~/testing/mock-data/users';
import { Avatar } from '../Avatar'; import { Avatar } from '../Avatar';
@@ -9,7 +8,12 @@ const meta: Meta<typeof Avatar> = {
title: 'Modules/Users/Avatar', title: 'Modules/Users/Avatar',
component: Avatar, component: Avatar,
decorators: [ComponentDecorator], decorators: [ComponentDecorator],
args: { avatarUrl, size: 'md', placeholder: 'L', type: 'rounded' }, args: {
avatarUrl: AVATAR_URL_MOCK,
size: 'md',
placeholder: 'L',
type: 'rounded',
},
}; };
export default meta; export default meta;
@@ -5,10 +5,12 @@ import {
AvatarProps, AvatarProps,
AvatarSize, AvatarSize,
AvatarType, AvatarType,
} from '@/users/components/Avatar'; } from '@ui/display/avatar/components/Avatar';
import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator'; import {
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator'; AVATAR_URL_MOCK,
import { avatarUrl } from '~/testing/mock-data/users'; CatalogDecorator,
ComponentDecorator,
} from '@ui/testing';
import { AvatarGroup, AvatarGroupProps } from '../AvatarGroup'; import { AvatarGroup, AvatarGroupProps } from '../AvatarGroup';
@@ -18,7 +20,7 @@ const makeAvatar = (userName: string, props: Partial<AvatarProps> = {}) => (
); );
const getAvatars = (commonProps: Partial<AvatarProps> = {}) => [ const getAvatars = (commonProps: Partial<AvatarProps> = {}) => [
makeAvatar('Matthew', { avatarUrl, ...commonProps }), makeAvatar('Matthew', { avatarUrl: AVATAR_URL_MOCK, ...commonProps }),
makeAvatar('Sophie', commonProps), makeAvatar('Sophie', commonProps),
makeAvatar('Jane', commonProps), makeAvatar('Jane', commonProps),
makeAvatar('Lily', commonProps), makeAvatar('Lily', commonProps),
@@ -1,7 +1,8 @@
import React from 'react'; import React from 'react';
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { IconCheck } from 'twenty-ui';
import { IconCheck } from '@ui/display/icon/components/TablerIcons';
const StyledContainer = styled.div` const StyledContainer = styled.div`
align-items: center; align-items: center;
@@ -1,11 +1,11 @@
import { Meta, StoryObj } from '@storybook/react'; import { Meta, StoryObj } from '@storybook/react';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator'; import { ComponentDecorator } from '@ui/testing/decorators/ComponentDecorator';
import { Checkmark } from '../Checkmark'; import { Checkmark } from '../Checkmark';
const meta: Meta<typeof Checkmark> = { const meta: Meta<typeof Checkmark> = {
title: 'UI/Display/Checkmark/Checkmark', title: 'UI/Display/Checkmark',
component: Checkmark, component: Checkmark,
decorators: [ComponentDecorator], decorators: [ComponentDecorator],
}; };
@@ -2,7 +2,7 @@ import { MouseEvent, ReactNode } from 'react';
import { css } from '@emotion/react'; import { css } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { OverflowingTextWithTooltip } from '../../tooltip/OverflowingTextWithTooltip'; import { OverflowingTextWithTooltip } from '@ui/display/tooltip/OverflowingTextWithTooltip';
export enum ChipSize { export enum ChipSize {
Large = 'large', Large = 'large',
@@ -2,10 +2,10 @@ import * as React from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import { isNonEmptyString } from '@sniptt/guards'; import { isNonEmptyString } from '@sniptt/guards';
import { IconComponent } from 'twenty-ui';
import { Avatar, AvatarType } from '@/users/components/Avatar'; import { Avatar, AvatarType } from '@ui/display/avatar/components/Avatar';
import { Nullable } from '~/types/Nullable'; import { IconComponent } from '@ui/display/icon/types/IconComponent';
import { Nullable } from '@ui/utilities/types/Nullable';
import { Chip, ChipVariant } from './Chip'; import { Chip, ChipVariant } from './Chip';
@@ -1,8 +1,10 @@
import { Meta, StoryObj } from '@storybook/react'; import { Meta, StoryObj } from '@storybook/react';
import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator'; import {
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator'; CatalogDecorator,
import { CatalogStory } from '~/testing/types'; CatalogStory,
ComponentDecorator,
} from '@ui/testing';
import { Chip, ChipAccent, ChipSize, ChipVariant } from '../Chip'; import { Chip, ChipAccent, ChipSize, ChipVariant } from '../Chip';
@@ -1,13 +1,13 @@
import { Meta, StoryObj } from '@storybook/react'; import { Meta, StoryObj } from '@storybook/react';
import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator'; import { ComponentDecorator, RouterDecorator } from '@ui/testing';
import { EntityChip } from '../EntityChip'; import { EntityChip } from '../EntityChip';
const meta: Meta<typeof EntityChip> = { const meta: Meta<typeof EntityChip> = {
title: 'UI/Display/Chip/EntityChip', title: 'UI/Display/Chip/EntityChip',
component: EntityChip, component: EntityChip,
decorators: [ComponentWithRouterDecorator], decorators: [RouterDecorator, ComponentDecorator],
args: { args: {
name: 'Entity name', name: 'Entity name',
linkToEntity: '/entity-link', linkToEntity: '/entity-link',
+8
View File
@@ -1,3 +1,9 @@
export * from './avatar/components/Avatar';
export * from './avatar/components/AvatarGroup';
export * from './checkmark/components/AnimatedCheckmark';
export * from './checkmark/components/Checkmark';
export * from './chip/components/Chip';
export * from './chip/components/EntityChip';
export * from './icon/components/IconAddressBook'; export * from './icon/components/IconAddressBook';
export * from './icon/components/IconGmail'; export * from './icon/components/IconGmail';
export * from './icon/components/IconGoogle'; export * from './icon/components/IconGoogle';
@@ -9,3 +15,5 @@ export * from './icon/hooks/useIcons';
export * from './icon/providers/IconsProvider'; export * from './icon/providers/IconsProvider';
export * from './icon/states/iconsState'; export * from './icon/states/iconsState';
export * from './icon/types/IconComponent'; export * from './icon/types/IconComponent';
export * from './tooltip/AppTooltip';
export * from './tooltip/OverflowingTextWithTooltip';
@@ -1,7 +1,7 @@
import { PlacesType, PositionStrategy, Tooltip } from 'react-tooltip'; import { PlacesType, PositionStrategy, Tooltip } from 'react-tooltip';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { RGBA } from '@/ui/theme/constants/Rgba'; import { RGBA } from '@ui/theme/constants/Rgba';
export enum TooltipPosition { export enum TooltipPosition {
Top = 'top', Top = 'top',
@@ -1,7 +1,7 @@
import { Meta, StoryObj } from '@storybook/react'; import { Meta, StoryObj } from '@storybook/react';
import { userEvent, within } from '@storybook/test'; import { userEvent, within } from '@storybook/test';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator'; import { ComponentDecorator } from '@ui/testing';
import { OverflowingTextWithTooltip } from '../OverflowingTextWithTooltip'; import { OverflowingTextWithTooltip } from '../OverflowingTextWithTooltip';
@@ -1,13 +1,15 @@
import { Meta, StoryObj } from '@storybook/react'; import { Meta, StoryObj } from '@storybook/react';
import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator'; import {
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator'; CatalogDecorator,
import { CatalogStory } from '~/testing/types'; CatalogStory,
ComponentDecorator,
} from '@ui/testing';
import { AppTooltip as Tooltip, TooltipPosition } from '../AppTooltip'; import { AppTooltip as Tooltip, TooltipPosition } from '../AppTooltip';
const meta: Meta<typeof Tooltip> = { const meta: Meta<typeof Tooltip> = {
title: 'UI/Display/Tooltip/Tooltip', title: 'UI/Display/Tooltip',
component: Tooltip, component: Tooltip,
}; };
@@ -0,0 +1,8 @@
import { MemoryRouter } from 'react-router-dom';
import { Decorator } from '@storybook/react';
export const RouterDecorator: Decorator = (Story) => (
<MemoryRouter>
<Story />
</MemoryRouter>
);
+4
View File
@@ -1,2 +1,6 @@
export * from './ComponentStorybookLayout'; export * from './ComponentStorybookLayout';
export * from './decorators/CatalogDecorator';
export * from './decorators/ComponentDecorator'; export * from './decorators/ComponentDecorator';
export * from './decorators/RouterDecorator';
export * from './mocks/avatarUrlMock';
export * from './types/CatalogStory';
@@ -0,0 +1,2 @@
export const AVATAR_URL_MOCK =
'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAYABgAAD/4QCMRXhpZgAATU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAABgAAAAAQAAAGAAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAABSgAwAEAAAAAQAAABQAAAAA/8AAEQgAFAAUAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/bAEMACwgICggHCwoJCg0MCw0RHBIRDw8RIhkaFBwpJCsqKCQnJy0yQDctMD0wJyc4TDk9Q0VISUgrNk9VTkZUQEdIRf/bAEMBDA0NEQ8RIRISIUUuJy5FRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRf/dAAQAAv/aAAwDAQACEQMRAD8Ava1q728otYY98joSCTgZrnbXWdTtrhrfVZXWLafmcAEkdgR/hVltQku9Q8+OIEBcGOT+ID0PY1ka1KH2u8ToqnPLbmIqG7u6LtbQ7RXBRec4Uck9eKXcPWsKDWVnhWSL5kYcFelSf2m3901POh8jP//QoyIAnTuKpXsY82NsksUyWPU5q/L9z8RVK++/F/uCsVsaEURwgA4HtT9x9TUcf3KfUGh//9k=';
@@ -4,7 +4,7 @@ import { StoryObj } from '@storybook/react';
import { import {
CatalogDimension, CatalogDimension,
CatalogOptions, CatalogOptions,
} from './decorators/CatalogDecorator'; } from '../decorators/CatalogDecorator';
export type CatalogStory< export type CatalogStory<
StoryType extends StoryObj<ComponentType>, StoryType extends StoryObj<ComponentType>,
@@ -1,4 +1,4 @@
import { stringToHslColor } from '../string-to-hsl'; import { stringToHslColor } from '../stringToHslColor';
describe('stringToHslColor', () => { describe('stringToHslColor', () => {
it('should return a color based on a string', () => { it('should return a color based on a string', () => {
@@ -1 +1,3 @@
export * from './color/utils/stringToHslColor';
export * from './state/utils/createState'; export * from './state/utils/createState';
export * from './types/Nullable';
+1 -2
View File
@@ -17,8 +17,7 @@
"baseUrl": ".", "baseUrl": ".",
"paths": { "paths": {
"twenty-emails": ["packages/twenty-emails/src/index.ts"], "twenty-emails": ["packages/twenty-emails/src/index.ts"],
"twenty-ui": ["packages/twenty-ui/src/index.ts"], "twenty-ui": ["packages/twenty-ui/src/index.ts"]
"@ui/*": ["packages/twenty-ui/src/*"]
} }
}, },
"exclude": ["node_modules", "tmp"] "exclude": ["node_modules", "tmp"]