Icon microsoft (#9907)

Implementing the Outlook icon for CreatedBy, only for emails.

Not in this PR original scope : The similar feature for calendar created
records. Since it was straightforward, I added it to the scope of this
PR.

Fix https://github.com/twentyhq/core-team-issues/issues/252
This commit is contained in:
Guillim
2025-01-30 17:09:42 +01:00
committed by GitHub
parent 9ec524213c
commit a5273732b3
42 changed files with 530 additions and 93 deletions

View File

@ -66,6 +66,7 @@ const mocks = [
source
workspaceMemberId
name
context
}
deletedAt
emails {
@ -226,6 +227,7 @@ const mocks = [
source
workspaceMemberId
name
context
}
deletedAt
emails {

View File

@ -74,6 +74,7 @@ const mocks: MockedResponse[] = [
source
workspaceMemberId
name
context
}
deletedAt
dueAt

View File

@ -47,6 +47,7 @@ const FIND_MANY_COMPANIES = gql`
source
workspaceMemberId
name
context
}
deletedAt
domainName {

View File

@ -129,6 +129,7 @@ mutation UpdateOneFavorite(
source
workspaceMemberId
name
context
}
deletedAt
domainName {
@ -183,6 +184,7 @@ mutation UpdateOneFavorite(
source
workspaceMemberId
name
context
}
deletedAt
id
@ -204,6 +206,7 @@ mutation UpdateOneFavorite(
source
workspaceMemberId
name
context
}
deletedAt
id
@ -224,6 +227,7 @@ mutation UpdateOneFavorite(
source
workspaceMemberId
name
context
}
deletedAt
emails {
@ -273,6 +277,7 @@ mutation UpdateOneFavorite(
source
workspaceMemberId
name
context
}
deletedAt
id
@ -290,6 +295,7 @@ mutation UpdateOneFavorite(
source
workspaceMemberId
name
context
}
deletedAt
dueAt
@ -336,6 +342,7 @@ mutation UpdateOneFavorite(
source
workspaceMemberId
name
context
}
deletedAt
endedAt
@ -417,6 +424,7 @@ export const mocks = [
source
workspaceMemberId
name
context
}
deletedAt
domainName {
@ -471,6 +479,7 @@ export const mocks = [
source
workspaceMemberId
name
context
}
deletedAt
id
@ -492,6 +501,7 @@ export const mocks = [
source
workspaceMemberId
name
context
}
deletedAt
id
@ -512,6 +522,7 @@ export const mocks = [
source
workspaceMemberId
name
context
}
deletedAt
emails {
@ -561,6 +572,7 @@ export const mocks = [
source
workspaceMemberId
name
context
}
deletedAt
id
@ -578,6 +590,7 @@ export const mocks = [
source
workspaceMemberId
name
context
}
deletedAt
dueAt
@ -624,6 +637,7 @@ export const mocks = [
source
workspaceMemberId
name
context
}
deletedAt
endedAt

View File

@ -141,6 +141,7 @@ ${mapObjectMetadataToGraphQLQuery({
source
workspaceMemberId
name
context
}`;
}

View File

@ -8,6 +8,7 @@ export const PERSON_FRAGMENT_WITH_DEPTH_ZERO_RELATIONS = `
source
workspaceMemberId
name
context
}
deletedAt
emails {
@ -114,6 +115,7 @@ export const PERSON_FRAGMENT_WITH_DEPTH_ONE_RELATIONS = `
source
workspaceMemberId
name
context
}
deletedAt
domainName {
@ -152,6 +154,7 @@ export const PERSON_FRAGMENT_WITH_DEPTH_ONE_RELATIONS = `
source
workspaceMemberId
name
context
}
deletedAt
emails {
@ -249,6 +252,7 @@ export const PERSON_FRAGMENT_WITH_DEPTH_ONE_RELATIONS = `
source
workspaceMemberId
name
context
}
deletedAt
id

View File

@ -71,6 +71,7 @@ const mocks: MockedResponse[] = [
source
workspaceMemberId
name
context
}
deletedAt
domainName {
@ -115,6 +116,7 @@ const mocks: MockedResponse[] = [
source
workspaceMemberId
name
context
}
deletedAt
id
@ -136,6 +138,7 @@ const mocks: MockedResponse[] = [
source
workspaceMemberId
name
context
}
deletedAt
id
@ -156,6 +159,7 @@ const mocks: MockedResponse[] = [
source
workspaceMemberId
name
context
}
deletedAt
emails {
@ -204,6 +208,7 @@ const mocks: MockedResponse[] = [
source
workspaceMemberId
name
context
}
deletedAt
id
@ -243,6 +248,7 @@ const mocks: MockedResponse[] = [
source
workspaceMemberId
name
context
}
deletedAt
domainName {
@ -292,6 +298,7 @@ const mocks: MockedResponse[] = [
source
workspaceMemberId
name
context
}
deletedAt
id
@ -312,6 +319,7 @@ const mocks: MockedResponse[] = [
source
workspaceMemberId
name
context
}
deletedAt
emails {
@ -360,6 +368,7 @@ const mocks: MockedResponse[] = [
source
workspaceMemberId
name
context
}
deletedAt
id
@ -377,6 +386,7 @@ const mocks: MockedResponse[] = [
source
workspaceMemberId
name
context
}
deletedAt
dueAt

View File

@ -87,6 +87,7 @@ const mocks: MockedResponse[] = [
source
workspaceMemberId
name
context
}
deletedAt
domainName {
@ -163,6 +164,7 @@ const mocks: MockedResponse[] = [
source
workspaceMemberId
name
context
}
deletedAt
id
@ -186,6 +188,7 @@ const mocks: MockedResponse[] = [
source
workspaceMemberId
name
context
}
deletedAt
emails {

View File

@ -23,6 +23,7 @@ export const ActorFieldDisplay = () => {
source={fieldValue.source}
avatarUrl={fieldValue.workspaceMember?.avatarUrl}
workspaceMemberId={fieldValue.workspaceMemberId}
context={fieldValue.context}
/>
) : null;
};

View File

@ -1,3 +1,4 @@
import { ConnectedAccountProvider } from 'twenty-shared';
import { ThemeColor } from 'twenty-ui';
import { RATING_VALUES } from '@/object-record/record-field/meta-types/constants/RatingValues';
@ -269,6 +270,9 @@ export type FieldActorValue = {
source: string;
workspaceMemberId?: string;
name: string;
context?: {
provider?: ConnectedAccountProvider;
};
};
export type FieldArrayValue = string[];

View File

@ -1,3 +1,5 @@
import { ConnectedAccountProvider } from 'twenty-shared';
import { z } from 'zod';
import { FieldActorValue } from '../FieldMetadata';
@ -6,6 +8,11 @@ const actorSchema = z.object({
source: z.string(),
workspaceMemberId: z.optional(z.string().nullable()),
name: z.string(),
context: z.optional(
z.object({
provider: z.optional(z.nativeEnum(ConnectedAccountProvider)),
}),
),
});
export const isFieldActorValue = (

View File

@ -86,6 +86,7 @@ const companyMocks = [
source
workspaceMemberId
name
context
}
deletedAt
domainName {
@ -162,6 +163,7 @@ const companyMocks = [
source
workspaceMemberId
name
context
}
deletedAt
id
@ -185,6 +187,7 @@ const companyMocks = [
source
workspaceMemberId
name
context
}
deletedAt
emails {

View File

@ -89,6 +89,7 @@ export const generateEmptyFieldValue = (
source: 'MANUAL',
workspaceMemberId: null,
name: '',
context: {},
};
}
case FieldMetadataType.PHONES: {

View File

@ -10,6 +10,7 @@ import {
} from '@/object-record/record-field/types/FieldMetadata';
import { SettingsFieldTypeConfig } from '@/settings/data-model/constants/SettingsNonCompositeFieldTypeConfigs';
import { CompositeFieldType } from '@/settings/data-model/types/CompositeFieldType';
import { ConnectedAccountProvider } from 'twenty-shared';
import {
IllustrationIconCurrency,
IllustrationIconLink,
@ -175,7 +176,13 @@ export const SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS = {
source: 'Source',
name: 'Name',
workspaceMemberId: 'Workspace Member ID',
context: 'Context',
},
exampleValue: {
source: 'source',
name: 'name',
workspaceMemberId: 'id',
context: { provider: ConnectedAccountProvider.GOOGLE },
},
exampleValue: { source: 'source', name: 'name', workspaceMemberId: 'id' },
} as const satisfies SettingsCompositeFieldTypeConfig<FieldActorValue>,
} as const satisfies SettingsCompositeFieldTypeConfigArray;

View File

@ -1,4 +1,6 @@
import { FieldActorValue } from '@/object-record/record-field/types/FieldMetadata';
import { ConnectedAccountProvider } from 'twenty-shared';
import { useMemo } from 'react';
import {
AvatarChip,
@ -7,6 +9,10 @@ import {
IconCalendar,
IconCsv,
IconGmail,
IconGoogleCalendar,
IconMail,
IconMicrosoftCalendar,
IconMicrosoftOutlook,
IconRobot,
IconSettingsAutomation,
} from 'twenty-ui';
@ -15,11 +21,25 @@ type ActorDisplayProps = Partial<FieldActorValue> & {
avatarUrl?: string | null;
};
const PROVIDORS_ICON_MAPPING = {
EMAIL: {
[ConnectedAccountProvider.MICROSOFT]: IconMicrosoftOutlook,
[ConnectedAccountProvider.GOOGLE]: IconGmail,
default: IconMail,
},
CALENDAR: {
[ConnectedAccountProvider.MICROSOFT]: IconMicrosoftCalendar,
[ConnectedAccountProvider.GOOGLE]: IconGoogleCalendar,
default: IconCalendar,
},
};
export const ActorDisplay = ({
name,
source,
workspaceMemberId,
avatarUrl,
context,
}: ActorDisplayProps) => {
const LeftIcon = useMemo(() => {
switch (source) {
@ -28,9 +48,9 @@ export const ActorDisplay = ({
case 'IMPORT':
return IconCsv;
case 'EMAIL':
return IconGmail;
return PROVIDORS_ICON_MAPPING.EMAIL[context?.provider ?? 'default'];
case 'CALENDAR':
return IconCalendar;
return PROVIDORS_ICON_MAPPING.CALENDAR[context?.provider ?? 'default'];
case 'SYSTEM':
return IconRobot;
case 'WORKFLOW':
@ -38,7 +58,7 @@ export const ActorDisplay = ({
default:
return undefined;
}
}, [source]);
}, [source, context?.provider]);
const isIconInverted =
source === 'API' || source === 'IMPORT' || source === 'SYSTEM';