Add Twenty Shared & Fix profile image rendering (#8841)
PR Summary: 1. Added `Twenty Shared` Package to centralize utilitiies as mentioned in #8942 2. Optimization of `getImageAbsoluteURI.ts` to handle edge cases  --------- Co-authored-by: Antoine Moreaux <moreaux.antoine@gmail.com> Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
committed by
GitHub
parent
4e329d08b0
commit
08a9db2df6
@ -1,6 +1,8 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { getImageAbsoluteURI } from 'twenty-ui';
|
||||
|
||||
import { getImageAbsoluteURI } from 'twenty-shared';
|
||||
import { REACT_APP_SERVER_BASE_URL } from '~/config';
|
||||
|
||||
type LogoProps = {
|
||||
primaryLogo?: string | null;
|
||||
@ -46,16 +48,21 @@ const StyledPrimaryLogo = styled.div<{ src: string }>`
|
||||
export const Logo = (props: LogoProps) => {
|
||||
const defaultPrimaryLogoUrl = `${window.location.origin}/icons/android/android-launchericon-192-192.png`;
|
||||
|
||||
const primaryLogoUrl = getImageAbsoluteURI(
|
||||
props.primaryLogo ?? defaultPrimaryLogoUrl,
|
||||
);
|
||||
const primaryLogoUrl = getImageAbsoluteURI({
|
||||
imageUrl: props.primaryLogo ?? defaultPrimaryLogoUrl,
|
||||
baseUrl: REACT_APP_SERVER_BASE_URL,
|
||||
});
|
||||
|
||||
const secondaryLogoUrl = isNonEmptyString(props.secondaryLogo)
|
||||
? getImageAbsoluteURI(props.secondaryLogo)
|
||||
? getImageAbsoluteURI({
|
||||
imageUrl: props.secondaryLogo,
|
||||
baseUrl: REACT_APP_SERVER_BASE_URL,
|
||||
})
|
||||
: null;
|
||||
|
||||
return (
|
||||
<StyledContainer>
|
||||
<StyledPrimaryLogo src={primaryLogoUrl} />
|
||||
<StyledPrimaryLogo src={primaryLogoUrl ?? ''} />
|
||||
{secondaryLogoUrl && (
|
||||
<StyledSecondaryLogoContainer>
|
||||
<StyledSecondaryLogo src={secondaryLogoUrl} />
|
||||
|
||||
@ -19,7 +19,7 @@ export const useGetPublicWorkspaceDataBySubdomain = () => {
|
||||
workspacePublicDataState,
|
||||
);
|
||||
|
||||
const { loading } = useGetPublicWorkspaceDataBySubdomainQuery({
|
||||
const { loading, data, error } = useGetPublicWorkspaceDataBySubdomainQuery({
|
||||
skip:
|
||||
(isMultiWorkspaceEnabled && isDefaultDomain) ||
|
||||
isDefined(workspacePublicData),
|
||||
@ -38,5 +38,7 @@ export const useGetPublicWorkspaceDataBySubdomain = () => {
|
||||
|
||||
return {
|
||||
loading,
|
||||
data: data?.getPublicWorkspaceDataBySubdomain,
|
||||
error,
|
||||
};
|
||||
};
|
||||
|
||||
@ -8,11 +8,14 @@ import {
|
||||
NavigationDrawerProps,
|
||||
} from '@/ui/navigation/navigation-drawer/components/NavigationDrawer';
|
||||
import { isAdvancedModeEnabledState } from '@/ui/navigation/navigation-drawer/states/isAdvancedModeEnabledState';
|
||||
import { getImageAbsoluteURI } from 'twenty-shared';
|
||||
import { REACT_APP_SERVER_BASE_URL } from '~/config';
|
||||
|
||||
import { useIsSettingsDrawer } from '@/navigation/hooks/useIsSettingsDrawer';
|
||||
|
||||
import { AdvancedSettingsToggle, getImageAbsoluteURI } from 'twenty-ui';
|
||||
import { MainNavigationDrawerItems } from './MainNavigationDrawerItems';
|
||||
import { MainNavigationDrawerItems } from '@/navigation/components/MainNavigationDrawerItems';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { AdvancedSettingsToggle } from 'twenty-ui';
|
||||
|
||||
export type AppNavigationDrawerProps = {
|
||||
className?: string;
|
||||
@ -40,10 +43,12 @@ export const AppNavigationDrawer = ({
|
||||
),
|
||||
}
|
||||
: {
|
||||
logo:
|
||||
(currentWorkspace?.logo &&
|
||||
getImageAbsoluteURI(currentWorkspace.logo)) ??
|
||||
undefined,
|
||||
logo: isNonEmptyString(currentWorkspace?.logo)
|
||||
? getImageAbsoluteURI({
|
||||
imageUrl: currentWorkspace.logo,
|
||||
baseUrl: REACT_APP_SERVER_BASE_URL,
|
||||
})
|
||||
: undefined,
|
||||
title: currentWorkspace?.displayName ?? undefined,
|
||||
children: <MainNavigationDrawerItems />,
|
||||
footer: <SupportDropdown />,
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
import { Company } from '@/companies/types/Company';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { getCompanyDomainName } from '@/object-metadata/utils/getCompanyDomainName';
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { getImageAbsoluteURI } from 'twenty-shared';
|
||||
import { REACT_APP_SERVER_BASE_URL } from '~/config';
|
||||
import { getLogoUrlFromDomainName } from '~/utils';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
import { Company } from '@/companies/types/Company';
|
||||
import { getCompanyDomainName } from '@/object-metadata/utils/getCompanyDomainName';
|
||||
import { getImageAbsoluteURI } from 'twenty-ui';
|
||||
import { getImageIdentifierFieldValue } from './getImageIdentifierFieldValue';
|
||||
|
||||
export const getAvatarUrl = (
|
||||
@ -26,7 +26,10 @@ export const getAvatarUrl = (
|
||||
|
||||
if (objectNameSingular === CoreObjectNameSingular.Person) {
|
||||
return isDefined(record.avatarUrl)
|
||||
? getImageAbsoluteURI(record.avatarUrl)
|
||||
? getImageAbsoluteURI({
|
||||
imageUrl: record.avatarUrl,
|
||||
baseUrl: REACT_APP_SERVER_BASE_URL,
|
||||
})
|
||||
: '';
|
||||
}
|
||||
|
||||
|
||||
@ -2,14 +2,9 @@ import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import React from 'react';
|
||||
import {
|
||||
Button,
|
||||
IconPhotoUp,
|
||||
IconTrash,
|
||||
IconUpload,
|
||||
IconX,
|
||||
getImageAbsoluteURI,
|
||||
} from 'twenty-ui';
|
||||
import { getImageAbsoluteURI } from 'twenty-shared';
|
||||
import { Button, IconPhotoUp, IconTrash, IconUpload, IconX } from 'twenty-ui';
|
||||
import { REACT_APP_SERVER_BASE_URL } from '~/config';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
@ -117,7 +112,10 @@ export const ImageInput = ({
|
||||
};
|
||||
|
||||
const pictureURI = isNonEmptyString(picture)
|
||||
? getImageAbsoluteURI(picture)
|
||||
? getImageAbsoluteURI({
|
||||
imageUrl: picture,
|
||||
baseUrl: REACT_APP_SERVER_BASE_URL,
|
||||
})
|
||||
: null;
|
||||
|
||||
return (
|
||||
|
||||
@ -14,12 +14,13 @@ import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useState } from 'react';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { getImageAbsoluteURI } from 'twenty-shared';
|
||||
import {
|
||||
IconChevronDown,
|
||||
MenuItemSelectAvatar,
|
||||
UndecoratedLink,
|
||||
getImageAbsoluteURI,
|
||||
} from 'twenty-ui';
|
||||
import { REACT_APP_SERVER_BASE_URL } from '~/config';
|
||||
|
||||
const StyledLogo = styled.div<{ logo: string }>`
|
||||
background: url(${({ logo }) => logo});
|
||||
@ -102,9 +103,12 @@ export const MultiWorkspaceDropdownButton = ({
|
||||
isNavigationDrawerExpanded={isNavigationDrawerExpanded}
|
||||
>
|
||||
<StyledLogo
|
||||
logo={getImageAbsoluteURI(
|
||||
currentWorkspace?.logo ?? DEFAULT_WORKSPACE_LOGO,
|
||||
)}
|
||||
logo={
|
||||
getImageAbsoluteURI({
|
||||
imageUrl: currentWorkspace?.logo ?? '',
|
||||
baseUrl: REACT_APP_SERVER_BASE_URL,
|
||||
}) ?? ''
|
||||
}
|
||||
/>
|
||||
<NavigationDrawerAnimatedCollapseWrapper>
|
||||
<StyledLabel>{currentWorkspace?.displayName ?? ''}</StyledLabel>
|
||||
@ -132,9 +136,12 @@ export const MultiWorkspaceDropdownButton = ({
|
||||
text={workspace.displayName ?? '(No name)'}
|
||||
avatar={
|
||||
<StyledLogo
|
||||
logo={getImageAbsoluteURI(
|
||||
workspace.logo ?? DEFAULT_WORKSPACE_LOGO,
|
||||
)}
|
||||
logo={
|
||||
getImageAbsoluteURI({
|
||||
imageUrl: workspace.logo ?? DEFAULT_WORKSPACE_LOGO,
|
||||
baseUrl: REACT_APP_SERVER_BASE_URL,
|
||||
}) ?? ''
|
||||
}
|
||||
/>
|
||||
}
|
||||
selected={currentWorkspace?.id === workspace.id}
|
||||
|
||||
@ -1,18 +1,23 @@
|
||||
import { workspacePublicDataState } from '@/auth/states/workspacePublicDataState';
|
||||
import { Helmet } from 'react-helmet-async';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { getImageAbsoluteURI } from 'twenty-ui';
|
||||
import { getImageAbsoluteURI } from 'twenty-shared';
|
||||
import { REACT_APP_SERVER_BASE_URL } from '~/config';
|
||||
|
||||
export const PageFavicon = () => {
|
||||
const workspacePublicData = useRecoilValue(workspacePublicDataState);
|
||||
|
||||
return (
|
||||
<Helmet>
|
||||
{workspacePublicData?.logo && (
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/x-icon"
|
||||
href={getImageAbsoluteURI(workspacePublicData.logo)}
|
||||
href={
|
||||
getImageAbsoluteURI({
|
||||
imageUrl: workspacePublicData.logo,
|
||||
baseUrl: REACT_APP_SERVER_BASE_URL,
|
||||
}) ?? ''
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</Helmet>
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { workspacePublicDataState } from '@/auth/states/workspacePublicDataState';
|
||||
import { useEffect } from 'react';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
import { isMultiWorkspaceEnabledState } from '@/client-config/states/isMultiWorkspaceEnabledState';
|
||||
@ -9,8 +8,10 @@ import { lastAuthenticatedWorkspaceDomainState } from '@/domain-manager/states/l
|
||||
import { useReadWorkspaceSubdomainFromCurrentLocation } from '@/domain-manager/hooks/useReadWorkspaceSubdomainFromCurrentLocation';
|
||||
|
||||
import { useIsCurrentLocationOnDefaultDomain } from '@/domain-manager/hooks/useIsCurrentLocationOnDefaultDomain';
|
||||
import { useGetPublicWorkspaceDataBySubdomain } from '@/domain-manager/hooks/useGetPublicWorkspaceDataBySubdomain';
|
||||
export const WorkspaceProviderEffect = () => {
|
||||
const workspacePublicData = useRecoilValue(workspacePublicDataState);
|
||||
const { data: getPublicWorkspaceData } =
|
||||
useGetPublicWorkspaceDataBySubdomain();
|
||||
|
||||
const lastAuthenticatedWorkspaceDomain = useRecoilValue(
|
||||
lastAuthenticatedWorkspaceDomainState,
|
||||
@ -26,16 +27,16 @@ export const WorkspaceProviderEffect = () => {
|
||||
useEffect(() => {
|
||||
if (
|
||||
isMultiWorkspaceEnabled &&
|
||||
isDefined(workspacePublicData?.subdomain) &&
|
||||
workspacePublicData.subdomain !== workspaceSubdomain
|
||||
isDefined(getPublicWorkspaceData?.subdomain) &&
|
||||
getPublicWorkspaceData.subdomain !== workspaceSubdomain
|
||||
) {
|
||||
redirectToWorkspaceDomain(workspacePublicData.subdomain);
|
||||
redirectToWorkspaceDomain(getPublicWorkspaceData.subdomain);
|
||||
}
|
||||
}, [
|
||||
workspaceSubdomain,
|
||||
isMultiWorkspaceEnabled,
|
||||
redirectToWorkspaceDomain,
|
||||
workspacePublicData,
|
||||
getPublicWorkspaceData,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
Reference in New Issue
Block a user