Files
twenty/packages/twenty-front/src/pages/settings/applications/components/SettingsAvailableApplicationCard.tsx
T
Raphaël Bosi 5f22908588 Decouple twenty-ui Avatar from app server-URL config (#21968)
Makes `twenty-ui`'s `Avatar` render the `avatarUrl` it receives instead
of building it from `window._env_`/`window.location` at module load, so
the library no longer depends on the app environment. URL resolution
moves to `twenty-front` via a `getAbsoluteImageUrl` helper applied at
the call sites.

Part of making twenty-ui a standalone library.
2026-06-22 18:38:00 +02:00

85 lines
2.5 KiB
TypeScript

import {
StyledSettingsCardContent,
StyledSettingsCardThirdLine,
StyledSettingsCardTitle,
} from '@/settings/components/SettingsOptions/SettingsCardContentBase';
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { Link } from 'react-router-dom';
import { SettingsPath } from 'twenty-shared/types';
import { getSettingsPath } from 'twenty-shared/utils';
import { Avatar } from 'twenty-ui/data-display';
import { Card } from 'twenty-ui/surfaces';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { type MarketplaceApp } from '~/generated-metadata/graphql';
import { getApplicationDescriptionSummary } from '~/pages/settings/applications/utils/getApplicationDescriptionSummary';
import { getAbsoluteImageUrl } from '~/utils/image/getAbsoluteImageUrl';
type SettingsAvailableApplicationCardProps = {
application: MarketplaceApp;
};
const StyledLinkContainer = styled.div`
> a {
display: flex;
height: 100%;
text-decoration: none;
}
`;
const StyledDescription = styled.div`
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
color: ${themeCssVariables.font.color.secondary};
display: -webkit-box;
a {
pointer-events: auto;
position: relative;
z-index: 1;
}
font-size: ${themeCssVariables.font.size.sm};
line-height: 1.5;
overflow: hidden;
`;
export const SettingsAvailableApplicationCard = ({
application,
}: SettingsAvailableApplicationCardProps) => {
const descriptionSummary = getApplicationDescriptionSummary(
application.description,
);
return (
<StyledLinkContainer>
<Link
to={getSettingsPath(SettingsPath.AvailableApplicationDetail, {
availableApplicationId: application.id,
})}
>
<Card rounded fullWidth>
<StyledSettingsCardContent alignItems="flex-start" fullHeight>
<Avatar
avatarUrl={getAbsoluteImageUrl(application.logo || null)}
placeholder={application.name}
placeholderColorSeed={application.name}
size="lg"
type="squared"
/>
<div>
<StyledSettingsCardTitle>
{application.name}
</StyledSettingsCardTitle>
<StyledDescription>{descriptionSummary}</StyledDescription>
<StyledSettingsCardThirdLine>
{t`by {author}`} {application.author}
</StyledSettingsCardThirdLine>
</div>
</StyledSettingsCardContent>
</Card>
</Link>
</StyledLinkContainer>
);
};