mirror of
https://github.com/twentyhq/twenty.git
synced 2024-10-03 20:38:02 +03:00
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:
parent
acc2092b95
commit
b6d0b8a895
@ -107,7 +107,7 @@ Handles overflowing text and displays a tooltip when the text overflows.
|
||||
|
||||
|
||||
<SandpackEditor
|
||||
availableComponentPaths={['@/ui/display/tooltip/OverflowingTextWithTooltip']}
|
||||
availableComponentPaths={['twenty-ui']}
|
||||
componentCode={overflowingTextWithTooltipCode}
|
||||
/>
|
||||
|
||||
|
@ -17,7 +17,7 @@ Represents a successful or completed action.
|
||||
<TabItem value="usage" label="Usage" default>
|
||||
|
||||
<SandpackEditor
|
||||
availableComponentPaths={['@/ui/display/checkmark/components/Checkmark']}
|
||||
availableComponentPaths={['twenty-ui']}
|
||||
componentCode={checkmarkCode}
|
||||
/>
|
||||
|
||||
@ -40,7 +40,7 @@ Represents a checkmark icon with the added feature of animation.
|
||||
<TabItem value="usage" label="Usage" default>
|
||||
|
||||
<SandpackEditor
|
||||
availableComponentPaths={['@/ui/display/checkmark/components/AnimatedCheckmark']}
|
||||
availableComponentPaths={['twenty-ui']}
|
||||
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>
|
||||
|
||||
<SandpackEditor
|
||||
availableComponentPaths={['@/ui/display/chip/components/Chip']}
|
||||
availableComponentPaths={['twenty-ui']}
|
||||
componentCode={chipCode}
|
||||
/>
|
||||
</TabItem>
|
||||
@ -117,8 +117,8 @@ A visual element that you can use as a clickable or non-clickable container with
|
||||
### Transparent Disabled Chip
|
||||
|
||||
<SandpackEditor
|
||||
availableComponentPaths={['@/ui/display/chip/components/Chip']}
|
||||
componentCode={`import { Chip } from "@/ui/display/chip/components/Chip";
|
||||
availableComponentPaths={['twenty-ui']}
|
||||
componentCode={`import { Chip } from "twenty-ui";
|
||||
|
||||
export const MyComponent = () => {
|
||||
return (
|
||||
@ -144,8 +144,8 @@ export const MyComponent = () => {
|
||||
### Disabled Chip with Tooltip
|
||||
|
||||
<SandpackEditor
|
||||
availableComponentPaths={['@/ui/display/chip/components/Chip']}
|
||||
componentCode={`import { Chip } from "@/ui/display/chip/components/Chip";
|
||||
availableComponentPaths={['twenty-ui']}
|
||||
componentCode={`import { Chip } from "twenty-ui";
|
||||
|
||||
export const MyComponent = () => {
|
||||
return (
|
||||
@ -176,7 +176,7 @@ A Chip-like element to display information about an entity.
|
||||
<TabItem value="usage" label="Usage" default>
|
||||
|
||||
<SandpackEditor
|
||||
availableComponentPaths={['@/ui/display/chip/components/EntityChip', 'twenty-ui']}
|
||||
availableComponentPaths={['twenty-ui']}
|
||||
componentCode={entityChipCode}
|
||||
/>
|
||||
</TabItem >
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { AnimatedCheckmark } from "@/ui/display/checkmark/components/AnimatedCheckmark";
|
||||
import { AnimatedCheckmark } from 'twenty-ui';
|
||||
|
||||
export const MyComponent = () => {
|
||||
return (
|
||||
@ -9,6 +9,4 @@ export const MyComponent = () => {
|
||||
size={30}
|
||||
/>
|
||||
);
|
||||
|
||||
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Checkmark } from "@/ui/display/checkmark/components/Checkmark";
|
||||
import { Checkmark } from 'twenty-ui';
|
||||
|
||||
export const MyComponent = () => {
|
||||
return <Checkmark />;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Chip } from "@/ui/display/chip/components/Chip";
|
||||
import { Chip } from 'twenty-ui';
|
||||
|
||||
export const MyComponent = () => {
|
||||
return (
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
import { IconTwentyStar } from 'twenty-ui';
|
||||
|
||||
import { EntityChip } from '@/ui/display/chip/components/EntityChip';
|
||||
import { EntityChip, IconTwentyStar } from 'twenty-ui';
|
||||
|
||||
export const MyComponent = () => {
|
||||
return (
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { OverflowingTextWithTooltip } from "@/ui/display/tooltip/OverflowingTextWithTooltip";
|
||||
import { OverflowingTextWithTooltip } from 'twenty-ui';
|
||||
|
||||
export const MyComponent = () => {
|
||||
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} />;
|
||||
};
|
||||
|
@ -1,7 +1,13 @@
|
||||
import React from 'react';
|
||||
import { css, useTheme } from '@emotion/react';
|
||||
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 { 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 { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell';
|
||||
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 { beautifyPastDateRelativeToNow } from '~/utils/date-utils';
|
||||
|
||||
|
@ -3,7 +3,7 @@ import { css, useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { format } from 'date-fns';
|
||||
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 { CalendarContext } from '@/activities/calendar/contexts/CalendarContext';
|
||||
@ -14,9 +14,8 @@ import { hasCalendarEventEnded } from '@/activities/calendar/utils/hasCalendarEv
|
||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||
import { Card } from '@/ui/layout/card/components/Card';
|
||||
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 { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
type CalendarEventRowProps = {
|
||||
@ -161,7 +160,7 @@ export const CalendarEventRow = ({
|
||||
key={[participant.workspaceMemberId, participant.displayName]
|
||||
.filter(isDefined)
|
||||
.join('-')}
|
||||
avatarUrl={participant.avatarUrl}
|
||||
avatarUrl={getImageAbsoluteURIOrBase64(participant.avatarUrl)}
|
||||
placeholder={
|
||||
participant.firstName && participant.lastName
|
||||
? `${participant.firstName} ${participant.lastName}`
|
||||
|
@ -1,12 +1,13 @@
|
||||
import { Tooltip } from 'react-tooltip';
|
||||
import styled from '@emotion/styled';
|
||||
import { Avatar } from 'twenty-ui';
|
||||
|
||||
import { Comment } from '@/activities/types/Comment';
|
||||
import { Avatar } from '@/users/components/Avatar';
|
||||
import {
|
||||
beautifyExactDateTime,
|
||||
beautifyPastDateRelativeToNow,
|
||||
} from '~/utils/date-utils';
|
||||
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
align-items: center;
|
||||
@ -75,7 +76,7 @@ export const CommentHeader = ({ comment, actionBar }: CommentHeaderProps) => {
|
||||
<StyledContainer>
|
||||
<StyledLeftContainer>
|
||||
<Avatar
|
||||
avatarUrl={avatarUrl}
|
||||
avatarUrl={getImageAbsoluteURIOrBase64(avatarUrl)}
|
||||
size="md"
|
||||
entityId={author?.id}
|
||||
placeholder={authorName}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { useMemo } from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import { Chip, ChipVariant } from 'twenty-ui';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { ActivityTargetWithTargetRecord } from '@/activities/types/ActivityTargetObject';
|
||||
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 { RGBA } from '@/ui/theme/constants/Rgba';
|
||||
|
||||
|
@ -1,14 +1,15 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { IconCheckbox, IconNotes } from 'twenty-ui';
|
||||
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import {
|
||||
Chip,
|
||||
ChipAccent,
|
||||
ChipSize,
|
||||
ChipVariant,
|
||||
} from '@/ui/display/chip/components/Chip';
|
||||
IconCheckbox,
|
||||
IconNotes,
|
||||
} from 'twenty-ui';
|
||||
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
|
||||
type ActivityTypeDropdownProps = {
|
||||
activityId: string;
|
||||
|
@ -1,9 +1,10 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { Avatar } from 'twenty-ui';
|
||||
|
||||
import { getDisplayNameFromParticipant } from '@/activities/emails/utils/getDisplayNameFromParticipant';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { RecordChip } from '@/object-record/components/RecordChip';
|
||||
import { Avatar } from '@/users/components/Avatar';
|
||||
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
|
||||
|
||||
const StyledAvatar = styled(Avatar)`
|
||||
margin-right: ${({ theme }) => theme.spacing(1)};
|
||||
@ -67,7 +68,7 @@ export const ParticipantChip = ({
|
||||
) : (
|
||||
<StyledChip>
|
||||
<StyledAvatar
|
||||
avatarUrl={avatarUrl}
|
||||
avatarUrl={getImageAbsoluteURIOrBase64(avatarUrl)}
|
||||
type="rounded"
|
||||
placeholder={displayName}
|
||||
size="sm"
|
||||
|
@ -1,8 +1,8 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { OverflowingTextWithTooltip } from 'twenty-ui';
|
||||
|
||||
import { EmailThreadMessageParticipant } from '@/activities/emails/types/EmailThreadMessageParticipant';
|
||||
import { getDisplayNameFromParticipant } from '@/activities/emails/utils/getDisplayNameFromParticipant';
|
||||
import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip';
|
||||
|
||||
type EmailThreadMessageReceiversProps = {
|
||||
receivers: EmailThreadMessageParticipant[];
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { useRef } from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { Avatar } from 'twenty-ui';
|
||||
|
||||
import { EmailThreadNotShared } from '@/activities/emails/components/EmailThreadNotShared';
|
||||
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 { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer';
|
||||
import { GRAY_SCALE } from '@/ui/theme/constants/GrayScale';
|
||||
import { Avatar } from '@/users/components/Avatar';
|
||||
import { TimelineThread } from '~/generated/graphql';
|
||||
import { formatToHumanReadableDate } from '~/utils';
|
||||
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
|
||||
|
||||
const StyledCardContent = styled(CardContent)<{ visibility: string }>`
|
||||
align-items: center;
|
||||
@ -152,20 +153,24 @@ export const EmailThreadPreview = ({
|
||||
<StyledHeading unread={!thread.read}>
|
||||
<StyledParticipantsContainer>
|
||||
<Avatar
|
||||
avatarUrl={thread?.firstParticipant?.avatarUrl}
|
||||
avatarUrl={getImageAbsoluteURIOrBase64(
|
||||
thread?.firstParticipant?.avatarUrl,
|
||||
)}
|
||||
placeholder={thread.firstParticipant.displayName}
|
||||
type="rounded"
|
||||
/>
|
||||
{thread?.lastTwoParticipants?.[0] && (
|
||||
<StyledAvatar
|
||||
avatarUrl={thread.lastTwoParticipants[0].avatarUrl}
|
||||
avatarUrl={getImageAbsoluteURIOrBase64(
|
||||
thread.lastTwoParticipants[0].avatarUrl,
|
||||
)}
|
||||
placeholder={thread.lastTwoParticipants[0].displayName}
|
||||
type="rounded"
|
||||
/>
|
||||
)}
|
||||
{finalDisplayedName && (
|
||||
<StyledAvatar
|
||||
avatarUrl={finalAvatarUrl}
|
||||
avatarUrl={getImageAbsoluteURIOrBase64(finalAvatarUrl)}
|
||||
placeholder={finalDisplayedName}
|
||||
type="rounded"
|
||||
color={isCountIcon ? GRAY_SCALE.gray50 : undefined}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { useApolloClient } from '@apollo/client';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { Nullable } from 'twenty-ui';
|
||||
|
||||
import { Activity } from '@/activities/types/Activity';
|
||||
import { ActivityTarget } from '@/activities/types/ActivityTarget';
|
||||
@ -7,7 +8,6 @@ import { ActivityTargetWithTargetRecord } from '@/activities/types/ActivityTarge
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { useGetRecordFromCache } from '@/object-record/cache/hooks/useGetRecordFromCache';
|
||||
import { Nullable } from '~/types/Nullable';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
export const useActivityTargetObjectRecords = (activity: Activity) => {
|
||||
|
@ -1,13 +1,16 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
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 { useActivityTargetObjectRecords } from '@/activities/hooks/useActivityTargetObjectRecords';
|
||||
import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer';
|
||||
import { Activity } from '@/activities/types/Activity';
|
||||
import { getActivitySummary } from '@/activities/utils/getActivitySummary';
|
||||
import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip';
|
||||
import { Checkbox, CheckboxShape } from '@/ui/input/components/Checkbox';
|
||||
import { beautifyExactDate, hasDatePassed } from '~/utils/date-utils';
|
||||
|
||||
|
@ -2,17 +2,17 @@ import { Tooltip } from 'react-tooltip';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { IconCheckbox, IconNotes } from 'twenty-ui';
|
||||
import { Avatar, IconCheckbox, IconNotes } from 'twenty-ui';
|
||||
|
||||
import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer';
|
||||
import { timelineActivityWithoutTargetsFamilyState } from '@/activities/timeline/states/timelineActivityWithoutTargetsFamilyState';
|
||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||
import { Avatar } from '@/users/components/Avatar';
|
||||
import {
|
||||
beautifyExactDateTime,
|
||||
beautifyPastDateRelativeToNow,
|
||||
} from '~/utils/date-utils';
|
||||
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
|
||||
|
||||
const StyledAvatarContainer = styled.div`
|
||||
align-items: center;
|
||||
@ -170,7 +170,9 @@ export const TimelineActivity = ({
|
||||
<StyledTimelineItemContainer>
|
||||
<StyledAvatarContainer>
|
||||
<Avatar
|
||||
avatarUrl={activityForTimeline.author?.avatarUrl}
|
||||
avatarUrl={getImageAbsoluteURIOrBase64(
|
||||
activityForTimeline.author?.avatarUrl,
|
||||
)}
|
||||
placeholder={activityForTimeline.author?.name.firstName ?? ''}
|
||||
size="sm"
|
||||
type="rounded"
|
||||
|
@ -1,7 +1,7 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { OverflowingTextWithTooltip } from 'twenty-ui';
|
||||
|
||||
import { ActivityType } from '@/activities/types/Activity';
|
||||
import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip';
|
||||
import { Checkbox, CheckboxShape } from '@/ui/input/components/Checkbox';
|
||||
|
||||
const StyledTitleContainer = styled.div`
|
||||
|
@ -1,6 +1,6 @@
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { getImageAbsoluteURIOrBase64 } from '@/users/utils/getProfilePictureAbsoluteURI';
|
||||
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
|
||||
|
||||
type LogoProps = {
|
||||
workspaceLogo?: string | null;
|
||||
|
@ -3,7 +3,7 @@ import styled from '@emotion/styled';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { Key } from 'ts-key-enum';
|
||||
import { IconNotes } from 'twenty-ui';
|
||||
import { Avatar, IconNotes } from 'twenty-ui';
|
||||
|
||||
import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer';
|
||||
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 { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
||||
import { Avatar } from '@/users/components/Avatar';
|
||||
import { getLogoUrlFromDomainName } from '~/utils';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { Avatar } from 'twenty-ui';
|
||||
|
||||
import { DraggableItem } from '@/ui/layout/draggable-list/components/DraggableItem';
|
||||
import { DraggableList } from '@/ui/layout/draggable-list/components/DraggableList';
|
||||
import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem';
|
||||
import { NavigationDrawerSection } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSection';
|
||||
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';
|
||||
|
||||
@ -63,7 +64,7 @@ export const Favorites = () => {
|
||||
Icon={() => (
|
||||
<StyledAvatar
|
||||
entityId={recordId}
|
||||
avatarUrl={avatarUrl}
|
||||
avatarUrl={getImageAbsoluteURIOrBase64(avatarUrl)}
|
||||
type={avatarType}
|
||||
placeholder={labelIdentifier}
|
||||
className="fav-avatar"
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { gql } from '@apollo/client';
|
||||
import { AvatarType } from 'twenty-ui';
|
||||
|
||||
import { AvatarType } from '@/users/components/Avatar';
|
||||
import { ColorScheme } from '@/workspace-member/types/WorkspaceMember';
|
||||
|
||||
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 = {
|
||||
id: string;
|
||||
|
@ -11,7 +11,7 @@ import {
|
||||
} from '@/ui/navigation/navigation-drawer/components/NavigationDrawer';
|
||||
import { isNavigationDrawerOpenState } from '@/ui/navigation/states/isNavigationDrawerOpenState';
|
||||
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 { currentMobileNavigationDrawerState } from '../states/currentMobileNavigationDrawerState';
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { Nullable } from 'twenty-ui';
|
||||
|
||||
import { useColumnDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromFieldMetadata';
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
|
||||
import { Nullable } from '~/types/Nullable';
|
||||
|
||||
describe('useColumnDefinitionsFromFieldMetadata', () => {
|
||||
it('should return empty definitions if no object is passed', () => {
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { useMemo } from 'react';
|
||||
import { Nullable } from 'twenty-ui';
|
||||
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
||||
import { filterAvailableTableColumns } from '@/object-record/utils/filterAvailableTableColumns';
|
||||
import { Nullable } from '~/types/Nullable';
|
||||
|
||||
import { formatFieldMetadataItemAsColumnDefinition } from '../utils/formatFieldMetadataItemAsColumnDefinition';
|
||||
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 { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { EntityChip } from '@/ui/display/chip/components/EntityChip';
|
||||
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
|
||||
|
||||
export type RecordChipProps = {
|
||||
objectNameSingular: string;
|
||||
@ -28,7 +28,9 @@ export const RecordChip = ({
|
||||
entityId={record.id}
|
||||
name={objectRecordIdentifier.name}
|
||||
avatarType={objectRecordIdentifier.avatarType}
|
||||
avatarUrl={objectRecordIdentifier.avatarUrl}
|
||||
avatarUrl={
|
||||
getImageAbsoluteURIOrBase64(objectRecordIdentifier.avatarUrl) || ''
|
||||
}
|
||||
linkToEntity={objectRecordIdentifier.linkToShowPage}
|
||||
maxWidth={maxWidth}
|
||||
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';
|
||||
|
||||
@ -17,7 +17,7 @@ export const GenericEntityFilterChip = ({
|
||||
entityId={filter.value}
|
||||
name={filter.displayValue}
|
||||
avatarType="rounded"
|
||||
avatarUrl={filter.displayAvatarUrl}
|
||||
avatarUrl={getImageAbsoluteURIOrBase64(filter.displayAvatarUrl) || ''}
|
||||
LeftIcon={Icon}
|
||||
/>
|
||||
);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Nullable } from 'twenty-ui';
|
||||
|
||||
import { useDateField } from '@/object-record/record-field/meta-types/hooks/useDateField';
|
||||
import { DateInput } from '@/ui/field/input/components/DateInput';
|
||||
import { Nullable } from '~/types/Nullable';
|
||||
|
||||
import { usePersistField } from '../../../hooks/usePersistField';
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Nullable } from 'twenty-ui';
|
||||
|
||||
import { DateInput } from '@/ui/field/input/components/DateInput';
|
||||
import { Nullable } from '~/types/Nullable';
|
||||
|
||||
import { usePersistField } from '../../../hooks/usePersistField';
|
||||
import { useDateTimeField } from '../../hooks/useDateTimeField';
|
||||
|
@ -1,5 +1,6 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { Avatar } from 'twenty-ui';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
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 { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
||||
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)`
|
||||
height: 100%;
|
||||
@ -42,7 +43,9 @@ export const MultipleObjectRecordSelectItem = ({
|
||||
isKeySelected={isSelectedByKeyboard}
|
||||
avatar={
|
||||
<Avatar
|
||||
avatarUrl={objectRecordForSelect.recordIdentifier.avatarUrl}
|
||||
avatarUrl={getImageAbsoluteURIOrBase64(
|
||||
objectRecordForSelect.recordIdentifier.avatarUrl,
|
||||
)}
|
||||
entityId={objectRecordForSelect.record.id}
|
||||
placeholder={objectRecordForSelect.recordIdentifier.name}
|
||||
size="md"
|
||||
|
@ -1,11 +1,12 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { Avatar } from 'twenty-ui';
|
||||
|
||||
import { EntityForSelect } from '@/object-record/relation-picker/types/EntityForSelect';
|
||||
import { SelectableItem } from '@/ui/layout/selectable-list/components/SelectableItem';
|
||||
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
||||
import { MenuItemSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemSelectAvatar';
|
||||
import { Avatar } from '@/users/components/Avatar';
|
||||
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
|
||||
|
||||
type SelectableMenuItemSelectProps = {
|
||||
entity: EntityForSelect;
|
||||
@ -39,7 +40,7 @@ export const SelectableMenuItemSelect = ({
|
||||
hovered={isSelectedItemId}
|
||||
avatar={
|
||||
<Avatar
|
||||
avatarUrl={entity.avatarUrl}
|
||||
avatarUrl={getImageAbsoluteURIOrBase64(entity.avatarUrl)}
|
||||
entityId={entity.id}
|
||||
placeholder={entity.name}
|
||||
size="md"
|
||||
|
@ -1,11 +1,12 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Avatar } from 'twenty-ui';
|
||||
|
||||
import { SelectableRecord } from '@/object-record/select/types/SelectableRecord';
|
||||
import { DropdownMenuSkeletonItem } from '@/ui/input/relation-picker/components/skeletons/DropdownMenuSkeletonItem';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||
import { MenuItemMultiSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemMultiSelectAvatar';
|
||||
import { Avatar } from '@/users/components/Avatar';
|
||||
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
|
||||
|
||||
export const MultipleRecordSelectDropdown = ({
|
||||
recordsToSelect,
|
||||
@ -68,7 +69,7 @@ export const MultipleRecordSelectDropdown = ({
|
||||
}
|
||||
avatar={
|
||||
<Avatar
|
||||
avatarUrl={record.avatarUrl}
|
||||
avatarUrl={getImageAbsoluteURIOrBase64(record.avatarUrl)}
|
||||
entityId={record.id}
|
||||
placeholder={record.name}
|
||||
size="md"
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { AvatarType } from '@/users/components/Avatar';
|
||||
import { AvatarType } from 'twenty-ui';
|
||||
|
||||
export type SelectableRecord = {
|
||||
id: string;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Nullable } from 'twenty-ui';
|
||||
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { ObjectRecordEdge } from '@/object-record/types/ObjectRecordEdge';
|
||||
import { Nullable } from '~/types/Nullable';
|
||||
|
||||
export type ObjectRecordConnection<T extends ObjectRecord = ObjectRecord> = {
|
||||
__typename?: string;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { AvatarType } from '@/users/components/Avatar';
|
||||
import { AvatarType } from 'twenty-ui';
|
||||
|
||||
export type ObjectRecordIdentifier = {
|
||||
id: string;
|
||||
|
@ -1,7 +1,6 @@
|
||||
import {
|
||||
EntityChip,
|
||||
EntityChipVariant,
|
||||
} from '@/ui/display/chip/components/EntityChip';
|
||||
import { EntityChip, EntityChipVariant } from 'twenty-ui';
|
||||
|
||||
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
|
||||
|
||||
export type PersonChipProps = {
|
||||
id: string;
|
||||
@ -21,7 +20,7 @@ export const PersonChip = ({
|
||||
linkToEntity={`/person/${id}`}
|
||||
name={name}
|
||||
avatarType="rounded"
|
||||
avatarUrl={avatarUrl}
|
||||
avatarUrl={getImageAbsoluteURIOrBase64(avatarUrl) || ''}
|
||||
variant={variant}
|
||||
/>
|
||||
);
|
||||
|
@ -2,7 +2,7 @@ import { ReactNode, useMemo } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useIcons } from 'twenty-ui';
|
||||
import { Nullable, useIcons } from 'twenty-ui';
|
||||
|
||||
import { useGetRelationMetadata } from '@/object-metadata/hooks/useGetRelationMetadata';
|
||||
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 { TableCell } from '@/ui/layout/table/components/TableCell';
|
||||
import { TableRow } from '@/ui/layout/table/components/TableRow';
|
||||
import { Nullable } from '~/types/Nullable';
|
||||
|
||||
import { RELATION_TYPES } from '../../constants/RelationTypes';
|
||||
|
||||
|
@ -5,8 +5,8 @@ import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMembe
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
|
||||
import { ImageInput } from '@/ui/input/components/ImageInput';
|
||||
import { getImageAbsoluteURIOrBase64 } from '@/users/utils/getProfilePictureAbsoluteURI';
|
||||
import { useUploadProfilePictureMutation } from '~/generated/graphql';
|
||||
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
|
||||
|
||||
|
@ -2,11 +2,11 @@ import { useRecoilState } from 'recoil';
|
||||
|
||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||
import { ImageInput } from '@/ui/input/components/ImageInput';
|
||||
import { getImageAbsoluteURIOrBase64 } from '@/users/utils/getProfilePictureAbsoluteURI';
|
||||
import {
|
||||
useUpdateWorkspaceMutation,
|
||||
useUploadWorkspaceLogoMutation,
|
||||
} from '~/generated/graphql';
|
||||
import { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
|
||||
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
|
||||
|
||||
export const WorkspaceLogoUploader = () => {
|
||||
|
@ -9,11 +9,11 @@ import {
|
||||
size,
|
||||
useFloating,
|
||||
} from '@floating-ui/react';
|
||||
import { AppTooltip } from 'twenty-ui';
|
||||
import { ReadonlyDeep } from 'type-fest';
|
||||
import { useDebouncedCallback } from 'use-debounce';
|
||||
|
||||
import { SelectOption } from '@/spreadsheet-import/types';
|
||||
import { AppTooltip } from '@/ui/display/tooltip/AppTooltip';
|
||||
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
||||
|
@ -2,9 +2,9 @@
|
||||
import { Column } from 'react-data-grid';
|
||||
import { createPortal } from 'react-dom';
|
||||
import styled from '@emotion/styled';
|
||||
import { AppTooltip } from 'twenty-ui';
|
||||
|
||||
import { Fields } from '@/spreadsheet-import/types';
|
||||
import { AppTooltip } from '@/ui/display/tooltip/AppTooltip';
|
||||
|
||||
const StyledHeaderContainer = styled.div`
|
||||
align-items: center;
|
||||
|
@ -2,10 +2,10 @@
|
||||
import { Column, useRowSelection } from 'react-data-grid';
|
||||
import { createPortal } from 'react-dom';
|
||||
import styled from '@emotion/styled';
|
||||
import { AppTooltip } from 'twenty-ui';
|
||||
|
||||
import { MatchColumnSelect } from '@/spreadsheet-import/components/MatchColumnSelect';
|
||||
import { Data, Fields } from '@/spreadsheet-import/types';
|
||||
import { AppTooltip } from '@/ui/display/tooltip/AppTooltip';
|
||||
import { Checkbox, CheckboxVariant } from '@/ui/input/components/Checkbox';
|
||||
import { TextInput } from '@/ui/input/components/TextInput';
|
||||
import { Toggle } from '@/ui/input/components/Toggle';
|
||||
|
@ -1,8 +1,8 @@
|
||||
import React, { ReactElement, useRef, useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
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 { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
|
||||
|
@ -1,12 +1,10 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { CatalogDecorator, CatalogStory, ComponentDecorator } from 'twenty-ui';
|
||||
|
||||
import { Info, InfoAccent } from '@/ui/display/info/components/Info.tsx';
|
||||
import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator.tsx';
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator.tsx';
|
||||
import { CatalogStory } from '~/testing/types.ts';
|
||||
import { Info, InfoAccent } from '@/ui/display/info/components/Info';
|
||||
|
||||
const meta: Meta<typeof Info> = {
|
||||
title: 'UI/Display/Info/Info',
|
||||
title: 'UI/Display/Info',
|
||||
component: Info,
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { OverflowingTextWithTooltip } from '../../../display/tooltip/OverflowingTextWithTooltip';
|
||||
import { OverflowingTextWithTooltip } from 'twenty-ui';
|
||||
|
||||
import { EllipsisDisplay } from './EllipsisDisplay';
|
||||
|
||||
|
@ -2,11 +2,11 @@ import { useRef, useState } from 'react';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
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 { DateDisplay } from '@/ui/field/display/components/DateDisplay';
|
||||
import { InternalDatePicker } from '@/ui/input/components/internal/date/components/InternalDatePicker';
|
||||
import { Nullable } from '~/types/Nullable';
|
||||
|
||||
const StyledCalendarContainer = styled.div`
|
||||
background: ${({ theme }) => theme.background.secondary};
|
||||
|
@ -6,8 +6,8 @@ import {
|
||||
motion,
|
||||
useAnimation,
|
||||
} from 'framer-motion';
|
||||
import { Checkmark } from 'twenty-ui';
|
||||
|
||||
import { Checkmark } from '@/ui/display/checkmark/components/Checkmark';
|
||||
import { ColorScheme } from '@/workspace-member/types/WorkspaceMember';
|
||||
|
||||
const StyledColorSchemeBackground = styled.div<
|
||||
|
@ -3,14 +3,13 @@ import styled from '@emotion/styled';
|
||||
import { Decorator, Meta, StoryObj } from '@storybook/react';
|
||||
import { expect, userEvent, waitFor, within } from '@storybook/test';
|
||||
import { PlayFunction } from '@storybook/types';
|
||||
import { Avatar, ComponentDecorator } from 'twenty-ui';
|
||||
|
||||
import { Button } from '@/ui/input/button/components/Button';
|
||||
import { DropdownMenuSkeletonItem } from '@/ui/input/relation-picker/components/skeletons/DropdownMenuSkeletonItem';
|
||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||
import { MenuItemMultiSelectAvatar } from '@/ui/navigation/menu-item/components/MenuItemMultiSelectAvatar';
|
||||
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 { DropdownMenuHeader } from '../DropdownMenuHeader';
|
||||
|
@ -4,9 +4,12 @@ import { useNavigate } from 'react-router-dom';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
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 { NavigationDrawerCollapseButton } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerCollapseButton';
|
||||
import { isNavigationDrawerOpenState } from '@/ui/navigation/states/isNavigationDrawerOpenState';
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { ChangeEvent, ReactNode, useRef } from 'react';
|
||||
import { Tooltip } from 'react-tooltip';
|
||||
import styled from '@emotion/styled';
|
||||
import { Avatar, AvatarType } from 'twenty-ui';
|
||||
import { v4 as uuidV4 } from 'uuid';
|
||||
|
||||
import { Avatar, AvatarType } from '@/users/components/Avatar';
|
||||
import {
|
||||
beautifyExactDateTime,
|
||||
beautifyPastDateRelativeToNow,
|
||||
|
@ -1,8 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { Link as ReactLink } from 'react-router-dom';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { Chip, ChipSize, ChipVariant } from '@/ui/display/chip/components/Chip';
|
||||
import { Chip, ChipSize, ChipVariant } from 'twenty-ui';
|
||||
|
||||
type RoundedLinkProps = {
|
||||
href: string;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { ReactNode } from 'react';
|
||||
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 {
|
||||
|
@ -1,8 +1,6 @@
|
||||
import { ReactNode } from 'react';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { IconCheck } from 'twenty-ui';
|
||||
|
||||
import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip';
|
||||
import { IconCheck, OverflowingTextWithTooltip } from 'twenty-ui';
|
||||
|
||||
import {
|
||||
StyledMenuItemLabel,
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { Avatar } from '@/users/components/Avatar';
|
||||
import {
|
||||
Avatar,
|
||||
CatalogDecorator,
|
||||
CatalogDimension,
|
||||
CatalogOptions,
|
||||
} from '~/testing/decorators/CatalogDecorator';
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
CatalogStory,
|
||||
ComponentDecorator,
|
||||
} from 'twenty-ui';
|
||||
|
||||
import { avatarUrl } from '~/testing/mock-data/users';
|
||||
import { CatalogStory } from '~/testing/types';
|
||||
|
||||
import { MenuItemMultiSelectAvatar } from '../MenuItemMultiSelectAvatar';
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { Avatar } from '@/users/components/Avatar';
|
||||
import {
|
||||
Avatar,
|
||||
CatalogDecorator,
|
||||
CatalogDimension,
|
||||
CatalogOptions,
|
||||
} from '~/testing/decorators/CatalogDecorator';
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
CatalogStory,
|
||||
ComponentDecorator,
|
||||
} from 'twenty-ui';
|
||||
|
||||
import { avatarUrl } from '~/testing/mock-data/users';
|
||||
import { CatalogStory } from '~/testing/types';
|
||||
|
||||
import { MenuItemSelectAvatar } from '../MenuItemSelectAvatar';
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { IconComponent, IconGripVertical } from 'twenty-ui';
|
||||
|
||||
import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip';
|
||||
import {
|
||||
IconComponent,
|
||||
IconGripVertical,
|
||||
OverflowingTextWithTooltip,
|
||||
} from 'twenty-ui';
|
||||
|
||||
import {
|
||||
StyledMenuItemLabel,
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
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 { 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 = {
|
||||
id: string;
|
||||
@ -11,6 +13,6 @@ export const UserChip = ({ id, name, avatarUrl }: UserChipProps) => (
|
||||
entityId={id}
|
||||
name={name}
|
||||
avatarType="rounded"
|
||||
avatarUrl={avatarUrl}
|
||||
avatarUrl={getImageAbsoluteURIOrBase64(avatarUrl) || ''}
|
||||
/>
|
||||
);
|
||||
|
@ -5,11 +5,16 @@ import {
|
||||
OnDragEndResponder,
|
||||
ResponderProvided,
|
||||
} 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 { 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 { DraggableList } from '@/ui/layout/draggable-list/components/DraggableList';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
|
@ -1,8 +1,8 @@
|
||||
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 { getImageAbsoluteURIOrBase64 } from '~/utils/image/getImageAbsoluteURIOrBase64';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
background: ${({ theme }) => theme.background.secondary};
|
||||
@ -39,7 +39,7 @@ export const WorkspaceMemberCard = ({
|
||||
}: WorkspaceMemberCardProps) => (
|
||||
<StyledContainer>
|
||||
<Avatar
|
||||
avatarUrl={workspaceMember.avatarUrl}
|
||||
avatarUrl={getImageAbsoluteURIOrBase64(workspaceMember.avatarUrl)}
|
||||
entityId={workspaceMember.id}
|
||||
placeholder={workspaceMember.name.firstName || ''}
|
||||
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;
|
||||
}
|
||||
|
||||
if (imageUrl?.startsWith('data:')) {
|
||||
return imageUrl;
|
||||
}
|
||||
|
||||
if (imageUrl?.startsWith('https:')) {
|
||||
if (imageUrl?.startsWith('data:') || imageUrl?.startsWith('https:')) {
|
||||
return imageUrl;
|
||||
}
|
||||
|
@ -14,13 +14,13 @@ module.exports = {
|
||||
patterns: [
|
||||
{
|
||||
group: ['@tabler/icons-react'],
|
||||
message: 'Please import icons from `src/display`',
|
||||
message: 'Please import icons from `@ui/display`',
|
||||
},
|
||||
{
|
||||
group: ['react-hotkeys-web-hook'],
|
||||
importNames: ['useHotkeys'],
|
||||
message:
|
||||
'Please use the custom wrapper: `useScopedHotkeys` from `src/utilities`',
|
||||
'Please use the custom wrapper: `useScopedHotkeys` from `@ui/utilities`',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -2,10 +2,10 @@
|
||||
"name": "twenty-ui",
|
||||
"version": "0.4.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"main": "./src/index.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js",
|
||||
"require": "./dist/index.cjs"
|
||||
}
|
||||
|
@ -2,10 +2,7 @@ import { useEffect, useState } from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
|
||||
import { Nullable } from '~/types/Nullable';
|
||||
import { stringToHslColor } from '~/utils/string-to-hsl';
|
||||
|
||||
import { getImageAbsoluteURIOrBase64 } from '../utils/getProfilePictureAbsoluteURI';
|
||||
import { Nullable, stringToHslColor } from '@ui/utilities';
|
||||
|
||||
export type AvatarType = 'squared' | 'rounded';
|
||||
|
||||
@ -93,7 +90,7 @@ export const Avatar = ({
|
||||
const img = new Image();
|
||||
img.onload = () => resolve(false);
|
||||
img.onerror = () => resolve(true);
|
||||
img.src = getImageAbsoluteURIOrBase64(avatarUrl) as string;
|
||||
img.src = avatarUrl;
|
||||
}).then((res) => {
|
||||
setIsInvalidAvatarUrl(res as boolean);
|
||||
});
|
||||
@ -110,7 +107,7 @@ export const Avatar = ({
|
||||
return (
|
||||
<StyledAvatar
|
||||
className={className}
|
||||
avatarUrl={getImageAbsoluteURIOrBase64(avatarUrl)}
|
||||
avatarUrl={avatarUrl}
|
||||
placeholder={placeholder}
|
||||
size={size}
|
||||
type={type}
|
@ -1,7 +1,6 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
import { avatarUrl } from '~/testing/mock-data/users';
|
||||
import { AVATAR_URL_MOCK, ComponentDecorator } from '@ui/testing';
|
||||
|
||||
import { Avatar } from '../Avatar';
|
||||
|
||||
@ -9,7 +8,12 @@ const meta: Meta<typeof Avatar> = {
|
||||
title: 'Modules/Users/Avatar',
|
||||
component: Avatar,
|
||||
decorators: [ComponentDecorator],
|
||||
args: { avatarUrl, size: 'md', placeholder: 'L', type: 'rounded' },
|
||||
args: {
|
||||
avatarUrl: AVATAR_URL_MOCK,
|
||||
size: 'md',
|
||||
placeholder: 'L',
|
||||
type: 'rounded',
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
@ -5,10 +5,12 @@ import {
|
||||
AvatarProps,
|
||||
AvatarSize,
|
||||
AvatarType,
|
||||
} from '@/users/components/Avatar';
|
||||
import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator';
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
import { avatarUrl } from '~/testing/mock-data/users';
|
||||
} from '@ui/display/avatar/components/Avatar';
|
||||
import {
|
||||
AVATAR_URL_MOCK,
|
||||
CatalogDecorator,
|
||||
ComponentDecorator,
|
||||
} from '@ui/testing';
|
||||
|
||||
import { AvatarGroup, AvatarGroupProps } from '../AvatarGroup';
|
||||
|
||||
@ -18,7 +20,7 @@ const makeAvatar = (userName: string, props: Partial<AvatarProps> = {}) => (
|
||||
);
|
||||
|
||||
const getAvatars = (commonProps: Partial<AvatarProps> = {}) => [
|
||||
makeAvatar('Matthew', { avatarUrl, ...commonProps }),
|
||||
makeAvatar('Matthew', { avatarUrl: AVATAR_URL_MOCK, ...commonProps }),
|
||||
makeAvatar('Sophie', commonProps),
|
||||
makeAvatar('Jane', commonProps),
|
||||
makeAvatar('Lily', commonProps),
|
@ -1,7 +1,8 @@
|
||||
import React from 'react';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { IconCheck } from 'twenty-ui';
|
||||
|
||||
import { IconCheck } from '@ui/display/icon/components/TablerIcons';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
align-items: center;
|
@ -1,11 +1,11 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
import { ComponentDecorator } from '@ui/testing/decorators/ComponentDecorator';
|
||||
|
||||
import { Checkmark } from '../Checkmark';
|
||||
|
||||
const meta: Meta<typeof Checkmark> = {
|
||||
title: 'UI/Display/Checkmark/Checkmark',
|
||||
title: 'UI/Display/Checkmark',
|
||||
component: Checkmark,
|
||||
decorators: [ComponentDecorator],
|
||||
};
|
@ -2,7 +2,7 @@ import { MouseEvent, ReactNode } from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { OverflowingTextWithTooltip } from '../../tooltip/OverflowingTextWithTooltip';
|
||||
import { OverflowingTextWithTooltip } from '@ui/display/tooltip/OverflowingTextWithTooltip';
|
||||
|
||||
export enum ChipSize {
|
||||
Large = 'large',
|
@ -2,10 +2,10 @@ import * as React from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { IconComponent } from 'twenty-ui';
|
||||
|
||||
import { Avatar, AvatarType } from '@/users/components/Avatar';
|
||||
import { Nullable } from '~/types/Nullable';
|
||||
import { Avatar, AvatarType } from '@ui/display/avatar/components/Avatar';
|
||||
import { IconComponent } from '@ui/display/icon/types/IconComponent';
|
||||
import { Nullable } from '@ui/utilities/types/Nullable';
|
||||
|
||||
import { Chip, ChipVariant } from './Chip';
|
||||
|
@ -1,8 +1,10 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator';
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
import { CatalogStory } from '~/testing/types';
|
||||
import {
|
||||
CatalogDecorator,
|
||||
CatalogStory,
|
||||
ComponentDecorator,
|
||||
} from '@ui/testing';
|
||||
|
||||
import { Chip, ChipAccent, ChipSize, ChipVariant } from '../Chip';
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator';
|
||||
import { ComponentDecorator, RouterDecorator } from '@ui/testing';
|
||||
|
||||
import { EntityChip } from '../EntityChip';
|
||||
|
||||
const meta: Meta<typeof EntityChip> = {
|
||||
title: 'UI/Display/Chip/EntityChip',
|
||||
component: EntityChip,
|
||||
decorators: [ComponentWithRouterDecorator],
|
||||
decorators: [RouterDecorator, ComponentDecorator],
|
||||
args: {
|
||||
name: 'Entity name',
|
||||
linkToEntity: '/entity-link',
|
@ -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/IconGmail';
|
||||
export * from './icon/components/IconGoogle';
|
||||
@ -9,3 +15,5 @@ export * from './icon/hooks/useIcons';
|
||||
export * from './icon/providers/IconsProvider';
|
||||
export * from './icon/states/iconsState';
|
||||
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 styled from '@emotion/styled';
|
||||
|
||||
import { RGBA } from '@/ui/theme/constants/Rgba';
|
||||
import { RGBA } from '@ui/theme/constants/Rgba';
|
||||
|
||||
export enum TooltipPosition {
|
||||
Top = 'top',
|
@ -1,7 +1,7 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { userEvent, within } from '@storybook/test';
|
||||
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
import { ComponentDecorator } from '@ui/testing';
|
||||
|
||||
import { OverflowingTextWithTooltip } from '../OverflowingTextWithTooltip';
|
||||
|
@ -1,13 +1,15 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator';
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
import { CatalogStory } from '~/testing/types';
|
||||
import {
|
||||
CatalogDecorator,
|
||||
CatalogStory,
|
||||
ComponentDecorator,
|
||||
} from '@ui/testing';
|
||||
|
||||
import { AppTooltip as Tooltip, TooltipPosition } from '../AppTooltip';
|
||||
|
||||
const meta: Meta<typeof Tooltip> = {
|
||||
title: 'UI/Display/Tooltip/Tooltip',
|
||||
title: 'UI/Display/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>
|
||||
);
|
@ -1,2 +1,6 @@
|
||||
export * from './ComponentStorybookLayout';
|
||||
export * from './decorators/CatalogDecorator';
|
||||
export * from './decorators/ComponentDecorator';
|
||||
export * from './decorators/RouterDecorator';
|
||||
export * from './mocks/avatarUrlMock';
|
||||
export * from './types/CatalogStory';
|
||||
|
2
packages/twenty-ui/src/testing/mocks/avatarUrlMock.ts
Normal file
2
packages/twenty-ui/src/testing/mocks/avatarUrlMock.ts
Normal file
@ -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 {
|
||||
CatalogDimension,
|
||||
CatalogOptions,
|
||||
} from './decorators/CatalogDecorator';
|
||||
} from '../decorators/CatalogDecorator';
|
||||
|
||||
export type CatalogStory<
|
||||
StoryType extends StoryObj<ComponentType>,
|
@ -1,4 +1,4 @@
|
||||
import { stringToHslColor } from '../string-to-hsl';
|
||||
import { stringToHslColor } from '../stringToHslColor';
|
||||
|
||||
describe('stringToHslColor', () => {
|
||||
it('should return a color based on a string', () => {
|
@ -1 +1,3 @@
|
||||
export * from './color/utils/stringToHslColor';
|
||||
export * from './state/utils/createState';
|
||||
export * from './types/Nullable';
|
||||
|
@ -17,8 +17,7 @@
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"twenty-emails": ["packages/twenty-emails/src/index.ts"],
|
||||
"twenty-ui": ["packages/twenty-ui/src/index.ts"],
|
||||
"@ui/*": ["packages/twenty-ui/src/*"]
|
||||
"twenty-ui": ["packages/twenty-ui/src/index.ts"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "tmp"]
|
||||
|
Loading…
Reference in New Issue
Block a user