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 16:09:42 +00:00
committed by GitHub
parent 9ec524213c
commit a5273732b3
42 changed files with 530 additions and 93 deletions
@@ -66,6 +66,7 @@ const mocks = [
source
workspaceMemberId
name
context
}
deletedAt
emails {
@@ -226,6 +227,7 @@ const mocks = [
source
workspaceMemberId
name
context
}
deletedAt
emails {
@@ -74,6 +74,7 @@ const mocks: MockedResponse[] = [
source
workspaceMemberId
name
context
}
deletedAt
dueAt
@@ -47,6 +47,7 @@ const FIND_MANY_COMPANIES = gql`
source
workspaceMemberId
name
context
}
deletedAt
domainName {
@@ -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
@@ -141,6 +141,7 @@ ${mapObjectMetadataToGraphQLQuery({
source
workspaceMemberId
name
context
}`;
}
@@ -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
@@ -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
@@ -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 {
@@ -23,6 +23,7 @@ export const ActorFieldDisplay = () => {
source={fieldValue.source}
avatarUrl={fieldValue.workspaceMember?.avatarUrl}
workspaceMemberId={fieldValue.workspaceMemberId}
context={fieldValue.context}
/>
) : null;
};
@@ -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[];
@@ -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 = (
@@ -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 {
@@ -89,6 +89,7 @@ export const generateEmptyFieldValue = (
source: 'MANUAL',
workspaceMemberId: null,
name: '',
context: {},
};
}
case FieldMetadataType.PHONES: {
@@ -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;
@@ -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';