Files
twenty/packages/twenty-front/src/modules/activities/timeline-activities/components/TimelineCard.tsx
T
Raphaël Bosi c596a5e342 Rename twenty-ui to twenty-ui-deprecated and twenty-new-ui to twenty-ui to prepare package release (#21315)
## Description

Promotes the next-gen UI library (formerly `twenty-new-ui`) to the name
**`twenty-ui`** (v0.1.0, publishable) and renames the old package to
**`twenty-ui-deprecated`**. Rewrites ~1,730 `twenty-ui` imports →
`twenty-ui-deprecated`, updates all configs/CI/Docker/deps, and migrates
twenty-front's `Toggle` to the new package (first consumer) as a
drop-in.

## Next steps
- Wire the `ui/v*` publish dispatch (`cd-deploy-tag.yaml` +
`.yarnrc.yml`), then tag `ui/v0.1.0` to publish.
- Continue migrating components from `twenty-ui-deprecated` →
`twenty-ui`.
2026-06-08 18:12:28 +02:00

108 lines
3.3 KiB
TypeScript

import { styled } from '@linaria/react';
import { CustomResolverFetchMoreLoader } from '@/activities/components/CustomResolverFetchMoreLoader';
import { SkeletonLoader } from '@/activities/components/SkeletonLoader';
import { EventList } from '@/activities/timeline-activities/components/EventList';
import { useTimelineActivities } from '@/activities/timeline-activities/hooks/useTimelineActivities';
import { useLayoutRenderingContext } from '@/ui/layout/contexts/LayoutRenderingContext';
import { useTargetRecord } from '@/ui/layout/contexts/useTargetRecord';
import { t } from '@lingui/core/macro';
import {
AnimatedPlaceholder,
AnimatedPlaceholderEmptyContainer,
AnimatedPlaceholderEmptySubTitle,
AnimatedPlaceholderEmptyTextContainer,
AnimatedPlaceholderEmptyTitle,
EMPTY_PLACEHOLDER_TRANSITION_PROPS,
} from 'twenty-ui-deprecated/layout';
import {
MOBILE_VIEWPORT,
themeCssVariables,
} from 'twenty-ui-deprecated/theme-constants';
const StyledMainContainer = styled.div`
align-items: flex-start;
align-self: stretch;
border-top: none;
display: flex;
flex-direction: column;
gap: ${themeCssVariables.spacing[4]};
justify-content: center;
overflow: auto;
padding-left: ${themeCssVariables.spacing[6]};
padding-right: ${themeCssVariables.spacing[6]};
padding-top: ${themeCssVariables.spacing[6]};
@media (max-width: ${MOBILE_VIEWPORT}px) {
border-top: 1px solid ${themeCssVariables.border.color.medium};
padding-right: ${themeCssVariables.spacing[1]};
padding-left: ${themeCssVariables.spacing[1]};
}
`;
const StyledSidePanelPlaceholderWrapper = styled.div`
> * {
height: auto;
padding-top: ${themeCssVariables.spacing[8]};
}
`;
export const TimelineCard = () => {
const targetRecord = useTargetRecord();
const { isInSidePanel } = useLayoutRenderingContext();
const {
timelineActivities,
firstQueryLoading,
loadingMore,
fetchMoreRecords,
} = useTimelineActivities(targetRecord);
const isTimelineActivitiesEmpty = timelineActivities.length === 0;
if (firstQueryLoading === true) {
return <SkeletonLoader withSubSections />;
}
if (isTimelineActivitiesEmpty) {
const placeholderContent = (
<AnimatedPlaceholderEmptyContainer
// oxlint-disable-next-line react/jsx-props-no-spreading
{...EMPTY_PLACEHOLDER_TRANSITION_PROPS}
>
<AnimatedPlaceholder type="emptyTimeline" />
<AnimatedPlaceholderEmptyTextContainer>
<AnimatedPlaceholderEmptyTitle>
{t`No activity yet`}
</AnimatedPlaceholderEmptyTitle>
<AnimatedPlaceholderEmptySubTitle>
{t`There is no activity associated with this record.`}
</AnimatedPlaceholderEmptySubTitle>
</AnimatedPlaceholderEmptyTextContainer>
</AnimatedPlaceholderEmptyContainer>
);
return isInSidePanel ? (
<StyledSidePanelPlaceholderWrapper>
{placeholderContent}
</StyledSidePanelPlaceholderWrapper>
) : (
placeholderContent
);
}
return (
<StyledMainContainer>
<EventList
targetableObject={targetRecord}
title={t`All`}
events={timelineActivities ?? []}
/>
<CustomResolverFetchMoreLoader
loading={loadingMore}
onLastRowVisible={fetchMoreRecords}
/>
</StyledMainContainer>
);
};