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.
This commit is contained in:
Raphaël Bosi
2026-06-22 18:38:00 +02:00
committed by GitHub
parent e59e102448
commit 5f22908588
47 changed files with 198 additions and 115 deletions
@@ -12,6 +12,7 @@ import { AppTooltip, TooltipDelay } from 'twenty-ui/surfaces';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { type RoleWithPartialMembers } from '@/settings/roles/types/RoleWithPartialMembers';
import { getAbsoluteImageUrl } from '~/utils/image/getAbsoluteImageUrl';
const StyledAssignedText = styled.div`
color: ${themeCssVariables.font.color.secondary};
@@ -102,7 +103,7 @@ export const SettingsRolesTableRow = ({ role }: SettingsRolesTableRowProps) => {
<React.Fragment key={workspaceMember.id}>
<div id={`avatar-${workspaceMember.id}`}>
<Avatar
avatarUrl={workspaceMember.avatarUrl}
avatarUrl={getAbsoluteImageUrl(workspaceMember.avatarUrl)}
placeholderColorSeed={workspaceMember.id}
placeholder={workspaceMember.name.firstName ?? ''}
type="rounded"
@@ -7,6 +7,7 @@ import { t } from '@lingui/core/macro';
import { Avatar } from 'twenty-ui/data-display';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { getAbsoluteImageUrl } from '~/utils/image/getAbsoluteImageUrl';
const StyledSettingsCardContainer = styled.div`
margin-top: ${themeCssVariables.spacing[6]};
@@ -41,7 +42,9 @@ export const SettingsRoleAssignmentConfirmationModalSubtitle = ({
title={selectedRoleTarget.role?.label || ''}
Icon={
<Avatar
avatarUrl={enrichedSelectedWorkspaceMember?.avatarUrl}
avatarUrl={getAbsoluteImageUrl(
enrichedSelectedWorkspaceMember?.avatarUrl,
)}
placeholderColorSeed={enrichedSelectedWorkspaceMember?.id}
placeholder={workspaceMemberName}
size="md"
@@ -12,6 +12,7 @@ import { OverflowingTextWithTooltip } from 'twenty-ui/surfaces';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { type Agent, type ApiKeyForRole } from '~/generated-metadata/graphql';
import { dateLocaleState } from '~/localization/states/dateLocaleState';
import { getAbsoluteImageUrl } from '~/utils/image/getAbsoluteImageUrl';
import { formatDateString } from '~/utils/string/formatDateString';
import { type PartialWorkspaceMember } from '@/settings/roles/types/RoleWithPartialMembers';
@@ -63,7 +64,7 @@ export const SettingsRoleAssignmentTableRow = ({
);
return (
<Avatar
avatarUrl={enrichedWorkspaceMember?.avatarUrl}
avatarUrl={getAbsoluteImageUrl(enrichedWorkspaceMember?.avatarUrl)}
placeholderColorSeed={enrichedWorkspaceMember?.id}
placeholder={enrichedWorkspaceMember?.name.firstName ?? ''}
type="rounded"