Skip to content

Commit

Permalink
Add Twenty Shared & Fix profile image rendering (#8841)
Browse files Browse the repository at this point in the history
PR Summary: 

1. Added `Twenty Shared` Package to centralize utilitiies as mentioned
in #8942
2. Optimization of `getImageAbsoluteURI.ts` to handle edge cases


![image](https://github.com/user-attachments/assets/c72a3061-6eba-46b8-85ac-869f06bf23c0)

---------

Co-authored-by: Antoine Moreaux <[email protected]>
Co-authored-by: Charles Bochet <[email protected]>
  • Loading branch information
3 people authored Dec 17, 2024
1 parent 4e329d0 commit 08a9db2
Show file tree
Hide file tree
Showing 39 changed files with 453 additions and 129 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci-front.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ jobs:
package.json
packages/twenty-front/**
packages/twenty-ui/**
packages/twenty-shared/**
- name: Skip if no relevant changes
if: steps.changed-files.outputs.any_changed == 'false'
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/ci-server.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,14 @@ jobs:
package.json
packages/twenty-server/**
packages/twenty-emails/**
packages/twenty-shared/**
- name: Install dependencies
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/yarn-install
- name: Build twenty-shared
if: steps.changed-files.outputs.any_changed == 'true'
run: npx nx build twenty-shared
- name: Server / Restore Task Cache
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/task-cache
Expand Down Expand Up @@ -120,6 +124,7 @@ jobs:
package.json
packages/twenty-server/**
packages/twenty-emails/**
packages/twenty-shared/**
- name: Install dependencies
if: steps.changed-files.outputs.any_changed == 'true'
Expand Down
48 changes: 48 additions & 0 deletions .github/workflows/ci-shared.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: CI Shared
on:
push:
branches:
- main

pull_request:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
shared-test:
timeout-minutes: 30
runs-on: ubuntu-latest
env:
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
strategy:
matrix:
task: [lint, typecheck, test]
steps:
- name: Cancel Previous Runs
uses: styfle/[email protected]
with:
access_token: ${{ github.token }}
- name: Fetch custom Github Actions and base branch history
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check for changed files
id: changed-files
uses: tj-actions/changed-files@v11
with:
files: |
packages/twenty-shared/**
- name: Skip if no relevant changes
if: steps.changed-files.outputs.any_changed == 'false'
run: echo "No relevant changes. Skipping CI."
- name: Install dependencies
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/yarn-install
- name: Run ${{ matrix.task }} task
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/workflows/actions/nx-affected
with:
tag: scope:frontend
tasks: ${{ matrix.task }}
12 changes: 8 additions & 4 deletions nx.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@
"configurations": {
"ci": { "cacheStrategy": "content" },
"fix": { "fix": true }
}
},
"dependsOn": ["^build"]
},
"fmt": {
"executor": "nx:run-commands",
Expand All @@ -63,7 +64,8 @@
"configurations": {
"ci": { "cacheStrategy": "content" },
"fix": { "write": true }
}
},
"dependsOn": ["^build"]
},
"typecheck": {
"executor": "nx:run-commands",
Expand All @@ -74,7 +76,8 @@
},
"configurations": {
"watch": { "watch": true }
}
},
"dependsOn": ["^build"]
},
"test": {
"executor": "@nx/jest:jest",
Expand Down Expand Up @@ -115,7 +118,8 @@
"command": "VITE_DISABLE_TYPESCRIPT_CHECKER=true VITE_DISABLE_ESLINT_CHECKER=true storybook build",
"output-dir": "storybook-static",
"config-dir": ".storybook"
}
},
"dependsOn": ["^build"]
},
"storybook:serve:dev": {
"executor": "nx:run-commands",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,6 @@
"@types/express": "^4.17.13",
"@types/graphql-fields": "^1.3.6",
"@types/graphql-upload": "^8.0.12",
"@types/jest": "^29.5.11",
"@types/js-cookie": "^3.0.3",
"@types/js-levenshtein": "^1.1.3",
"@types/lodash.camelcase": "^4.3.7",
Expand Down Expand Up @@ -365,6 +364,7 @@
"packages/twenty-zapier",
"packages/twenty-website",
"packages/twenty-e2e-testing",
"packages/twenty-shared",
"tools/eslint-rules"
]
}
Expand Down
4 changes: 2 additions & 2 deletions packages/twenty-emails/src/emails/send-invite-link.email.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { MainText } from 'src/components/MainText';
import { Title } from 'src/components/Title';
import { WhatIsTwenty } from 'src/components/WhatIsTwenty';
import { capitalize } from 'src/utils/capitalize';
import { getImageAbsoluteURI } from 'src/utils/getImageAbsoluteURI';
import { getImageAbsoluteURI } from 'twenty-shared';

type SendInviteLinkEmailProps = {
link: string;
Expand All @@ -30,7 +30,7 @@ export const SendInviteLinkEmail = ({
serverUrl,
}: SendInviteLinkEmailProps) => {
const workspaceLogo = workspace.logo
? getImageAbsoluteURI(workspace.logo, serverUrl)
? getImageAbsoluteURI({ imageUrl: workspace.logo, baseUrl: serverUrl })
: null;

return (
Expand Down
9 changes: 0 additions & 9 deletions packages/twenty-emails/src/utils/getImageAbsoluteURI.ts

This file was deleted.

6 changes: 5 additions & 1 deletion packages/twenty-emails/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
{
"type": "module",
"compilerOptions": {
"jsx": "react-jsx",
"allowJs": false,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"types": ["vite/client"],
"baseUrl": "."
"baseUrl": ".",
"paths": {
"twenty-shared": ["../../packages/twenty-shared/dist"]
}
},
"files": [],
"include": [],
Expand Down
2 changes: 1 addition & 1 deletion packages/twenty-front/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8" />

<link rel="icon" href="/icons/android/android-launchericon-48-48.png" />
<link rel="icon" type="image/x-icon" href="/icons/android/android-launchericon-48-48.png" data-rh="true"/>
<link rel="apple-touch-icon" href="/icons/ios/192.png" />

<meta name="theme-color" content="#000000" />
Expand Down
19 changes: 13 additions & 6 deletions packages/twenty-front/src/modules/auth/components/Logo.tsx
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const useGetPublicWorkspaceDataBySubdomain = () => {
workspacePublicDataState,
);

const { loading } = useGetPublicWorkspaceDataBySubdomainQuery({
const { loading, data, error } = useGetPublicWorkspaceDataBySubdomainQuery({
skip:
(isMultiWorkspaceEnabled && isDefaultDomain) ||
isDefined(workspacePublicData),
Expand All @@ -38,5 +38,7 @@ export const useGetPublicWorkspaceDataBySubdomain = () => {

return {
loading,
data: data?.getPublicWorkspaceDataBySubdomain,
error,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 />,
Expand Down
Original file line number Diff line number Diff line change
@@ -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 = (
Expand All @@ -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,
})
: '';
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down Expand Up @@ -117,7 +112,10 @@ export const ImageInput = ({
};

const pictureURI = isNonEmptyString(picture)
? getImageAbsoluteURI(picture)
? getImageAbsoluteURI({
imageUrl: picture,
baseUrl: REACT_APP_SERVER_BASE_URL,
})
: null;

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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});
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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}
Expand Down
Loading

0 comments on commit 08a9db2

Please sign in to comment.