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';

View File

@ -0,0 +1,191 @@
import { InjectRepository } from '@nestjs/typeorm';
import chalk from 'chalk';
import { Command } from 'nest-commander';
import { FieldMetadataType } from 'twenty-shared';
import { In, Repository, TableColumn } from 'typeorm';
import {
ActiveWorkspacesCommandOptions,
ActiveWorkspacesCommandRunner,
} from 'src/database/commands/active-workspaces.command';
import { CommandLogger } from 'src/database/commands/logger';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { FieldActorSource } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { WorkspaceMetadataVersionService } from 'src/engine/metadata-modules/workspace-metadata-version/services/workspace-metadata-version.service';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
import { computeTableName } from 'src/engine/utils/compute-table-name.util';
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
@Command({
name: 'upgrade-0.41:add-context-to-actor-composite-type',
description: 'Add context to actor composite type.',
})
export class AddContextToActorCompositeTypeCommand extends ActiveWorkspacesCommandRunner {
protected readonly logger;
constructor(
@InjectRepository(Workspace, 'core')
protected readonly workspaceRepository: Repository<Workspace>,
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
@InjectRepository(FieldMetadataEntity, 'metadata')
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>,
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
private readonly workspaceMetadataVersionService: WorkspaceMetadataVersionService,
) {
super(workspaceRepository);
this.logger = new CommandLogger({
constructorName: this.constructor.name,
verbose: false,
});
this.logger.setVerbose(false);
}
async executeActiveWorkspacesCommand(
_passedParam: string[],
options: ActiveWorkspacesCommandOptions,
workspaceIds: string[],
): Promise<void> {
this.logger.log(`Running add-context-to-actor-composite-type command`);
if (options?.dryRun) {
this.logger.log(chalk.yellow('Dry run mode: No changes will be applied'));
}
for (const workspaceId of workspaceIds) {
try {
await this.execute(workspaceId, options?.dryRun);
this.logger.verbose(`Added for workspace: ${workspaceId}`);
} catch (error) {
this.logger.error(`Error for workspace: ${workspaceId}`, error);
}
}
}
private async execute(workspaceId: string, dryRun = false): Promise<void> {
this.logger.verbose(`Adding for workspace: ${workspaceId}`);
const actorFields = await this.fieldMetadataRepository.find({
where: {
type: FieldMetadataType.ACTOR,
workspaceId,
},
relations: ['object'],
});
// Filter and update fields with EMAIL or CALENDAR source
for (const field of actorFields) {
if (!field || !field.object) {
this.logger.verbose(
'field.objectMetadata is null',
workspaceId,
field.id,
);
continue;
}
await this.addContextColumn(
field,
`${field.name}Context`,
workspaceId,
dryRun,
);
const fieldRepository =
await this.twentyORMGlobalManager.getRepositoryForWorkspace(
workspaceId,
field.object.nameSingular,
);
if (!dryRun) {
await this.workspaceMetadataVersionService.incrementMetadataVersion(
workspaceId,
);
}
if (!dryRun) {
const rowsToUpdate = await fieldRepository.update(
{
[field.name + 'Source']: In([
FieldActorSource.EMAIL,
FieldActorSource.CALENDAR,
]),
[field.name + 'Context']: {},
},
{
[field.name + 'Context']: {
provider: 'google',
},
},
);
this.logger.verbose(
`updated ${rowsToUpdate ? rowsToUpdate.affected : 0} rows`,
);
}
}
}
private async addContextColumn(
field: FieldMetadataEntity,
newColumnName: string,
workspaceId: string,
dryRun = false,
): Promise<void> {
const workspaceDataSource =
await this.workspaceDataSourceService.connectToWorkspaceDataSource(
workspaceId,
);
if (!workspaceDataSource) {
this.logger.verbose('No workspace data source found');
return;
}
const queryRunner = workspaceDataSource?.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
const schemaName =
this.workspaceDataSourceService.getSchemaName(workspaceId);
try {
const hasColumn = await queryRunner.hasColumn(
`${schemaName}.${computeTableName(
field.object.nameSingular,
field?.object?.isCustom,
)}`,
newColumnName,
);
if (hasColumn) {
return;
}
if (!dryRun) {
await queryRunner.addColumn(
`${schemaName}.${computeTableName(
field.object.nameSingular,
field?.object?.isCustom,
)}`,
new TableColumn({
name: newColumnName,
type: 'jsonb',
default: `'{}'::"jsonb"`,
isNullable: true,
}),
);
await queryRunner.commitTransaction();
}
} catch (error) {
await queryRunner.rollbackTransaction();
throw error;
} finally {
await queryRunner.release();
}
}
}

View File

@ -5,6 +5,7 @@ import { Repository } from 'typeorm';
import { ActiveWorkspacesCommandRunner } from 'src/database/commands/active-workspaces.command';
import { BaseCommandOptions } from 'src/database/commands/base.command';
import { AddContextToActorCompositeTypeCommand } from 'src/database/commands/upgrade-version/0-41/0-41-add-context-to-actor-composite-type';
import { MigrateRelationsToFieldMetadataCommand } from 'src/database/commands/upgrade-version/0-41/0-41-migrate-relations-to-field-metadata.command';
import { RemoveDuplicateMcmasCommand } from 'src/database/commands/upgrade-version/0-41/0-41-remove-duplicate-mcmas';
import { SeedWorkflowViewsCommand } from 'src/database/commands/upgrade-version/0-41/0-41-seed-workflow-views.command';
@ -22,6 +23,7 @@ export class UpgradeTo0_41Command extends ActiveWorkspacesCommandRunner {
private readonly seedWorkflowViewsCommand: SeedWorkflowViewsCommand,
private readonly syncWorkspaceMetadataCommand: SyncWorkspaceMetadataCommand,
private readonly migrateRelationsToFieldMetadata: MigrateRelationsToFieldMetadataCommand,
private readonly addContextToActorCompositeType: AddContextToActorCompositeTypeCommand,
private readonly removeDuplicateMcmasCommand: RemoveDuplicateMcmasCommand,
) {
super(workspaceRepository);
@ -40,6 +42,12 @@ export class UpgradeTo0_41Command extends ActiveWorkspacesCommandRunner {
workspaceIds,
);
await this.addContextToActorCompositeType.executeActiveWorkspacesCommand(
passedParam,
options,
workspaceIds,
);
await this.syncWorkspaceMetadataCommand.executeActiveWorkspacesCommand(
passedParam,
{

View File

@ -1,6 +1,7 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AddContextToActorCompositeTypeCommand } from 'src/database/commands/upgrade-version/0-41/0-41-add-context-to-actor-composite-type';
import { MigrateRelationsToFieldMetadataCommand } from 'src/database/commands/upgrade-version/0-41/0-41-migrate-relations-to-field-metadata.command';
import { RemoveDuplicateMcmasCommand } from 'src/database/commands/upgrade-version/0-41/0-41-remove-duplicate-mcmas';
import { SeedWorkflowViewsCommand } from 'src/database/commands/upgrade-version/0-41/0-41-seed-workflow-views.command';
@ -10,6 +11,8 @@ import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module';
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module';
import { WorkspaceMetadataVersionModule } from 'src/engine/metadata-modules/workspace-metadata-version/workspace-metadata-version.module';
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';
import { WorkspaceHealthModule } from 'src/engine/workspace-manager/workspace-health/workspace-health.module';
import { SyncWorkspaceLoggerService } from 'src/engine/workspace-manager/workspace-sync-metadata/commands/services/sync-workspace-logger.service';
import { SyncWorkspaceMetadataCommand } from 'src/engine/workspace-manager/workspace-sync-metadata/commands/sync-workspace-metadata.command';
@ -26,6 +29,8 @@ import { WorkspaceSyncMetadataModule } from 'src/engine/workspace-manager/worksp
WorkspaceSyncMetadataCommandsModule,
WorkspaceSyncMetadataModule,
WorkspaceHealthModule,
WorkspaceDataSourceModule,
WorkspaceMetadataVersionModule,
],
providers: [
SyncWorkspaceLoggerService,
@ -33,6 +38,7 @@ import { WorkspaceSyncMetadataModule } from 'src/engine/workspace-manager/worksp
SeedWorkflowViewsCommand,
UpgradeTo0_41Command,
MigrateRelationsToFieldMetadataCommand,
AddContextToActorCompositeTypeCommand,
RemoveDuplicateMcmasCommand,
],
})

View File

@ -1,6 +1,7 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { ConnectedAccountProvider } from 'twenty-shared';
import { EntityManager, Repository } from 'typeorm';
import { v4 } from 'uuid';
@ -22,10 +23,7 @@ import {
CalendarChannelWorkspaceEntity,
} from 'src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity';
import { AccountsToReconnectService } from 'src/modules/connected-account/services/accounts-to-reconnect.service';
import {
ConnectedAccountProvider,
ConnectedAccountWorkspaceEntity,
} from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
import {
MessageChannelSyncStage,
MessageChannelSyncStatus,

View File

@ -1,6 +1,7 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { ConnectedAccountProvider } from 'twenty-shared';
import { EntityManager, Repository } from 'typeorm';
import { v4 } from 'uuid';
@ -21,10 +22,7 @@ import {
CalendarChannelWorkspaceEntity,
} from 'src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity';
import { AccountsToReconnectService } from 'src/modules/connected-account/services/accounts-to-reconnect.service';
import {
ConnectedAccountProvider,
ConnectedAccountWorkspaceEntity,
} from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
import {
MessageChannelSyncStage,
MessageChannelSyncStatus,

View File

@ -1,4 +1,4 @@
import { FieldMetadataType } from 'twenty-shared';
import { ConnectedAccountProvider, FieldMetadataType } from 'twenty-shared';
import {
CompositeProperty,
@ -41,6 +41,12 @@ export const actorCompositeType: CompositeType = {
hidden: 'input',
isRequired: true,
},
{
name: 'context',
type: FieldMetadataType.RAW_JSON,
hidden: false,
isRequired: false,
},
],
};
@ -48,4 +54,7 @@ export type ActorMetadata = {
source: FieldActorSource;
workspaceMemberId?: string;
name: string;
context?: {
provider?: ConnectedAccountProvider;
};
};

View File

@ -2,6 +2,8 @@ import { FieldMetadataType } from 'twenty-shared';
import { FieldMetadataDefaultValue } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface';
import { FieldActorSource } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
export function generateDefaultValue(
type: FieldMetadataType,
): FieldMetadataDefaultValue {
@ -52,6 +54,12 @@ export function generateDefaultValue(
blocknote: "''",
markdown: "''",
};
case FieldMetadataType.ACTOR:
return {
source: `'${FieldActorSource.MANUAL}'`,
name: "'System'",
context: {},
};
default:
return null;
}

View File

@ -2,10 +2,7 @@ import { msg } from '@lingui/core/macro';
import { FieldMetadataType } from 'twenty-shared';
import { SEARCH_VECTOR_FIELD } from 'src/engine/metadata-modules/constants/search-vector-field.constants';
import {
ActorMetadata,
FieldActorSource,
} from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
import { ActorMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
import { IndexType } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
import { DEFAULT_LABEL_IDENTIFIER_FIELD_NAME } from 'src/engine/metadata-modules/object-metadata/object-metadata.constants';
import {
@ -64,10 +61,6 @@ export class CustomWorkspaceEntity extends BaseWorkspaceEntity {
label: msg`Created by`,
icon: 'IconCreativeCommonsSa',
description: msg`The creator of the record`,
defaultValue: {
source: `'${FieldActorSource.MANUAL}'`,
name: "''",
},
})
createdBy: ActorMetadata;

View File

@ -4,10 +4,7 @@ import { FieldMetadataType } from 'twenty-shared';
import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface';
import { SEARCH_VECTOR_FIELD } from 'src/engine/metadata-modules/constants/search-vector-field.constants';
import {
ActorMetadata,
FieldActorSource,
} from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
import { ActorMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
import { AddressMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/address.composite-type';
import { CurrencyMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/currency.composite-type';
import { LinksMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/links.composite-type';
@ -157,10 +154,6 @@ export class CompanyWorkspaceEntity extends BaseWorkspaceEntity {
label: msg`Created by`,
icon: 'IconCreativeCommonsSa',
description: msg`The creator of the record`,
defaultValue: {
source: `'${FieldActorSource.MANUAL}'`,
name: "''",
},
})
createdBy: ActorMetadata;

View File

@ -1,5 +1,5 @@
import { msg } from '@lingui/core/macro';
import { FieldMetadataType } from 'twenty-shared';
import { ConnectedAccountProvider, FieldMetadataType } from 'twenty-shared';
import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface';
@ -22,11 +22,6 @@ import { CalendarChannelWorkspaceEntity } from 'src/modules/calendar/common/stan
import { MessageChannelWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
export enum ConnectedAccountProvider {
GOOGLE = 'google',
MICROSOFT = 'microsoft',
}
@WorkspaceEntity({
standardId: STANDARD_OBJECT_IDS.connectedAccount,
namePlural: 'connectedAccounts',

View File

@ -127,6 +127,9 @@ export class CreateCompanyAndContactService {
: undefined,
createdBySource: source,
createdByWorkspaceMember: connectedAccount.accountOwner,
createdByContext: {
provider: connectedAccount.provider,
},
}));
return this.createContactService.createPeople(

View File

@ -1,5 +1,6 @@
import { Injectable } from '@nestjs/common';
import { ConnectedAccountProvider } from 'twenty-shared';
import { DeepPartial, EntityManager } from 'typeorm';
import { v4 } from 'uuid';
@ -17,6 +18,9 @@ type ContactToCreate = {
companyId?: string;
createdBySource: FieldActorSource;
createdByWorkspaceMember?: WorkspaceMemberWorkspaceEntity | null;
createdByContext?: {
provider?: ConnectedAccountProvider;
};
};
@Injectable()
@ -38,6 +42,7 @@ export class CreateContactService {
companyId,
createdBySource,
createdByWorkspaceMember,
createdByContext,
} = contact;
const { firstName, lastName } =
@ -56,6 +61,7 @@ export class CreateContactService {
source: createdBySource,
workspaceMemberId: contact.createdByWorkspaceMember?.id,
name: createdByName,
context: createdByContext,
},
position: ++lastPersonPosition,
};

View File

@ -1,9 +1,10 @@
import { ConfigService } from '@nestjs/config';
import { Test, TestingModule } from '@nestjs/testing';
import { ConnectedAccountProvider } from 'twenty-shared';
import { EnvironmentModule } from 'src/engine/core-modules/environment/environment.module';
import { MicrosoftOAuth2ClientManagerService } from 'src/modules/connected-account/oauth2-client-manager/drivers/microsoft/microsoft-oauth2-client-manager.service';
import { ConnectedAccountProvider } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
import { MicrosoftClientProvider } from 'src/modules/messaging/message-import-manager/drivers/microsoft/providers/microsoft-client.provider';
import { MicrosoftGetMessageListService } from './microsoft-get-message-list.service';

View File

@ -1,9 +1,10 @@
import { ConfigService } from '@nestjs/config';
import { Test, TestingModule } from '@nestjs/testing';
import { ConnectedAccountProvider } from 'twenty-shared';
import { EnvironmentModule } from 'src/engine/core-modules/environment/environment.module';
import { MicrosoftOAuth2ClientManagerService } from 'src/modules/connected-account/oauth2-client-manager/drivers/microsoft/microsoft-oauth2-client-manager.service';
import { ConnectedAccountProvider } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
import { MicrosoftClientProvider } from 'src/modules/messaging/message-import-manager/drivers/microsoft/providers/microsoft-client.provider';
import { MicrosoftFetchByBatchService } from 'src/modules/messaging/message-import-manager/drivers/microsoft/services/microsoft-fetch-by-batch.service';
import { MicrosoftGetMessagesService } from 'src/modules/messaging/message-import-manager/drivers/microsoft/services/microsoft-get-messages.service';

View File

@ -1,9 +1,10 @@
import { ConfigService } from '@nestjs/config';
import { Test, TestingModule } from '@nestjs/testing';
import { ConnectedAccountProvider } from 'twenty-shared';
import { EnvironmentModule } from 'src/engine/core-modules/environment/environment.module';
import { MicrosoftOAuth2ClientManagerService } from 'src/modules/connected-account/oauth2-client-manager/drivers/microsoft/microsoft-oauth2-client-manager.service';
import { ConnectedAccountProvider } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity';
import {
microsoftGraphBatchWithHtmlMessagesResponse,
microsoftGraphBatchWithTwoMessagesResponse,

View File

@ -5,10 +5,7 @@ import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/i
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { SEARCH_VECTOR_FIELD } from 'src/engine/metadata-modules/constants/search-vector-field.constants';
import {
ActorMetadata,
FieldActorSource,
} from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
import { ActorMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
import { RichTextV2Metadata } from 'src/engine/metadata-modules/field-metadata/composite-types/rich-text-v2.composite-type';
import { IndexType } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
import {
@ -101,10 +98,6 @@ export class NoteWorkspaceEntity extends BaseWorkspaceEntity {
label: msg`Created by`,
icon: 'IconCreativeCommonsSa',
description: msg`The creator of the record`,
defaultValue: {
source: `'${FieldActorSource.MANUAL}'`,
name: "''",
},
})
createdBy: ActorMetadata;

View File

@ -4,10 +4,7 @@ import { FieldMetadataType } from 'twenty-shared';
import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface';
import { SEARCH_VECTOR_FIELD } from 'src/engine/metadata-modules/constants/search-vector-field.constants';
import {
ActorMetadata,
FieldActorSource,
} from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
import { ActorMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
import { CurrencyMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/currency.composite-type';
import { IndexType } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
import {
@ -126,10 +123,6 @@ export class OpportunityWorkspaceEntity extends BaseWorkspaceEntity {
label: msg`Created by`,
icon: 'IconCreativeCommonsSa',
description: msg`The creator of the record`,
defaultValue: {
source: `'${FieldActorSource.MANUAL}'`,
name: "''",
},
})
createdBy: ActorMetadata;

View File

@ -4,10 +4,7 @@ import { FieldMetadataType } from 'twenty-shared';
import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface';
import { SEARCH_VECTOR_FIELD } from 'src/engine/metadata-modules/constants/search-vector-field.constants';
import {
ActorMetadata,
FieldActorSource,
} from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
import { ActorMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
import { EmailsMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/emails.composite-type';
import { FullNameMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/full-name.composite-type';
import { LinksMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/links.composite-type';
@ -170,10 +167,6 @@ export class PersonWorkspaceEntity extends BaseWorkspaceEntity {
label: msg`Created by`,
icon: 'IconCreativeCommonsSa',
description: msg`The creator of the record`,
defaultValue: {
source: `'${FieldActorSource.MANUAL}'`,
name: "''",
},
})
createdBy: ActorMetadata;

View File

@ -5,10 +5,7 @@ import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/i
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { SEARCH_VECTOR_FIELD } from 'src/engine/metadata-modules/constants/search-vector-field.constants';
import {
ActorMetadata,
FieldActorSource,
} from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
import { ActorMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
import { RichTextV2Metadata } from 'src/engine/metadata-modules/field-metadata/composite-types/rich-text-v2.composite-type';
import { IndexType } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
import {
@ -139,10 +136,6 @@ export class TaskWorkspaceEntity extends BaseWorkspaceEntity {
label: msg`Created by`,
icon: 'IconCreativeCommonsSa',
description: msg`The creator of the record`,
defaultValue: {
source: `'${FieldActorSource.MANUAL}'`,
name: "''",
},
})
createdBy: ActorMetadata;

View File

@ -3,10 +3,7 @@ import { FieldMetadataType } from 'twenty-shared';
import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface';
import {
ActorMetadata,
FieldActorSource,
} from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
import { ActorMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
import {
RelationMetadataType,
RelationOnDeleteAction,
@ -130,10 +127,6 @@ export class WorkflowRunWorkspaceEntity extends BaseWorkspaceEntity {
label: msg`Executed by`,
icon: 'IconCreativeCommonsSa',
description: msg`The executor of the workflow`,
defaultValue: {
source: `'${FieldActorSource.MANUAL}'`,
name: "''",
},
})
createdBy: ActorMetadata;

View File

@ -3,10 +3,7 @@ import { FieldMetadataType } from 'twenty-shared';
import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface';
import {
ActorMetadata,
FieldActorSource,
} from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
import { ActorMetadata } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
import { FieldMetadataComplexOption } from 'src/engine/metadata-modules/field-metadata/dtos/options.input';
import {
RelationMetadataType,
@ -169,10 +166,6 @@ export class WorkflowWorkspaceEntity extends BaseWorkspaceEntity {
label: msg`Created by`,
icon: 'IconCreativeCommonsSa',
description: msg`The creator of the record`,
defaultValue: {
source: `'${FieldActorSource.MANUAL}'`,
name: "''",
},
})
createdBy: ActorMetadata;
}

View File

@ -1,6 +1,7 @@
export * from './constants/FieldForTotalCountAggregateOperation';
export * from './constants/TwentyCompaniesBaseUrl';
export * from './constants/TwentyIconsBaseUrl';
export * from './types/ConnectedAccountProvider';
export * from './types/FieldMetadataType';
export * from './utils/fieldMetadata/isFieldMetadataDateKind';
export * from './utils/image/getImageAbsoluteURI';

View File

@ -0,0 +1,4 @@
export enum ConnectedAccountProvider {
GOOGLE = 'google',
MICROSOFT = 'microsoft',
}

View File

@ -0,0 +1,142 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="170mm"
height="173mm"
viewBox="0 0 170 173"
version="1.1"
id="svg8"
inkscape:version="1.0.2 (e86c870879, 2021-01-15, custom)"
sodipodi:docname="cldrnw.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="446.39757"
inkscape:cy="364.37241"
inkscape:document-units="mm"
inkscape:current-layer="layer2"
inkscape:document-rotation="0"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Capa 2"
style="opacity:1">
<path
id="rect862"
style="fill:#1b64b6;fill-opacity:1;fill-rule:evenodd;stroke-width:6.46864;stroke-linecap:square;paint-order:markers fill stroke"
d="M 7.9243621,0.40426573 H 162.081 c 4.29879,0 7.75955,3.45686397 7.75955,7.75081597 V 36.958129 c 0,4.293952 -3.46076,7.750816 -7.75955,7.750816 H 7.9243621 c -4.29883,0 -7.75961003,-3.456864 -7.75961003,-7.750816 V 8.1550817 c 0,-4.293952 3.46078003,-7.75081597 7.75961003,-7.75081597 z" />
<rect
style="fill:#2179d2;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:6.46499;stroke-linecap:square;paint-order:markers fill stroke"
id="rect865"
width="53.482864"
height="47.625"
x="0.21232992"
y="30.049105"
ry="0" />
<rect
style="fill:#5edafe;fill-opacity:1;fill-rule:evenodd;stroke-width:6.46499;stroke-linecap:square;paint-order:markers fill stroke"
id="rect865-6"
width="53.483627"
height="47.625"
x="116.33598"
y="30.049105"
ry="0" />
<rect
style="fill:#3ca8e8;fill-opacity:1;fill-rule:evenodd;stroke-width:6.99654;stroke-linecap:square;paint-order:markers fill stroke"
id="rect865-5"
width="62.640022"
height="47.625"
x="53.695198"
y="30.049105"
ry="0" />
<rect
style="fill:#1b64b6;fill-opacity:1;fill-rule:evenodd;stroke-width:6.46499;stroke-linecap:square;paint-order:markers fill stroke"
id="rect865-1"
width="53.483627"
height="47.625"
x="0.21232992"
y="77.674103"
ry="0" />
<rect
style="fill:#3ca8e8;fill-opacity:1;fill-rule:evenodd;stroke-width:6.46499;stroke-linecap:square;paint-order:markers fill stroke"
id="rect865-6-7"
width="53.483627"
height="47.625"
x="116.33598"
y="77.674103"
ry="0" />
<rect
style="fill:#2179d2;fill-opacity:1;fill-rule:evenodd;stroke-width:6.99654;stroke-linecap:square;paint-order:markers fill stroke"
id="rect865-5-7"
width="62.640022"
height="47.625"
x="53.695198"
y="77.674103"
ry="0" />
<rect
style="fill:#154a8a;fill-opacity:1;fill-rule:evenodd;stroke-width:6.46499;stroke-linecap:square;paint-order:markers fill stroke"
id="rect865-1-1"
width="53.483627"
height="47.625"
x="0.21232992"
y="125.29911"
ry="7.7508163" />
<rect
style="fill:#1b64b6;fill-opacity:1;fill-rule:evenodd;stroke-width:6.99654;stroke-linecap:square;paint-order:markers fill stroke"
id="rect865-5-7-8"
width="62.639313"
height="47.624989"
x="53.695961"
y="125.29911"
ry="0" />
<rect
style="fill:#2179d2;fill-opacity:1;fill-rule:evenodd;stroke-width:6.46499;stroke-linecap:square;paint-order:markers fill stroke"
id="rect865-1-1-4"
width="53.483627"
height="47.625"
x="116.33598"
y="125.29911"
ry="7.7508163" />
<path
style="fill:#154a8a;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 0.21378207,125.2991 53.48140993,1e-5 0.003,47.62499 H 8.4247021 l -8.21573003,-8.21568 z"
id="path1012"
sodipodi:nodetypes="cccccc" />
<path
style="fill:#2179d2;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 169.82154,125.29911 h -53.48556 l 0.002,47.625 h 45.27325 l 8.21568,-8.21568 z"
id="path1012-9"
sodipodi:nodetypes="cccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -1,8 +1,35 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<title>file_type_outlook</title>
<path d="M19.484,7.937v5.477L21.4,14.619a.489.489,0,0,0,.21,0l8.238-5.554a1.174,1.174,0,0,0-.959-1.128Z" style="fill:#0072c6"/>
<path d="M19.484,15.457l1.747,1.2a.522.522,0,0,0,.543,0c-.3.181,8.073-5.378,8.073-5.378V21.345a1.408,1.408,0,0,1-1.49,1.555H19.483V15.457Z" style="fill:#0072c6"/>
<path d="M10.44,12.932a1.609,1.609,0,0,0-1.42.838,4.131,4.131,0,0,0-.526,2.218A4.05,4.05,0,0,0,9.02,18.2a1.6,1.6,0,0,0,2.771.022,4.014,4.014,0,0,0,.515-2.2,4.369,4.369,0,0,0-.5-2.281A1.536,1.536,0,0,0,10.44,12.932Z" style="fill:#0072c6"/>
<path d="M2.153,5.155V26.582L18.453,30V2ZM13.061,19.491a3.231,3.231,0,0,1-2.7,1.361,3.19,3.19,0,0,1-2.64-1.318A5.459,5.459,0,0,1,6.706,16.1a5.868,5.868,0,0,1,1.036-3.616A3.267,3.267,0,0,1,10.486,11.1a3.116,3.116,0,0,1,2.61,1.321,5.639,5.639,0,0,1,1,3.484A5.763,5.763,0,0,1,13.061,19.491Z" style="fill:#0072c6"/>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Livello_1" xmlns:x="http://ns.adobe.com/Extensibility/1.0/" xmlns:i="http://ns.adobe.com/AdobeIllustrator/10.0/" xmlns:graph="http://ns.adobe.com/Graphs/1.0/" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1831.085 1703.335" enable-background="new 0 0 1831.085 1703.335" xml:space="preserve">
<path fill="#0A2767" d="M1831.083,894.25c0.1-14.318-7.298-27.644-19.503-35.131h-0.213l-0.767-0.426l-634.492-375.585 c-2.74-1.851-5.583-3.543-8.517-5.067c-24.498-12.639-53.599-12.639-78.098,0c-2.934,1.525-5.777,3.216-8.517,5.067L446.486,858.693 l-0.766,0.426c-19.392,12.059-25.337,37.556-13.278,56.948c3.553,5.714,8.447,10.474,14.257,13.868l634.492,375.585 c2.749,1.835,5.592,3.527,8.517,5.068c24.498,12.639,53.599,12.639,78.098,0c2.925-1.541,5.767-3.232,8.517-5.068l634.492-375.585 C1823.49,922.545,1831.228,908.923,1831.083,894.25z"/>
<path fill="#0364B8" d="M520.453,643.477h416.38v381.674h-416.38V643.477z M1745.917,255.5V80.908 c1-43.652-33.552-79.862-77.203-80.908H588.204C544.552,1.046,510,37.256,511,80.908V255.5l638.75,170.333L1745.917,255.5z"/>
<path fill="#0078D4" d="M511,255.5h425.833v383.25H511V255.5z"/>
<path fill="#28A8EA" d="M1362.667,255.5H936.833v383.25L1362.667,1022h383.25V638.75L1362.667,255.5z"/>
<path fill="#0078D4" d="M936.833,638.75h425.833V1022H936.833V638.75z"/>
<path fill="#0364B8" d="M936.833,1022h425.833v383.25H936.833V1022z"/>
<path fill="#14447D" d="M520.453,1025.151h416.38v346.969h-416.38V1025.151z"/>
<path fill="#0078D4" d="M1362.667,1022h383.25v383.25h-383.25V1022z"/>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="1128.4584" y1="811.0833" x2="1128.4584" y2="1.9982" gradientTransform="matrix(1 0 0 -1 0 1705.3334)">
<stop offset="0" style="stop-color:#35B8F1"/>
<stop offset="1" style="stop-color:#28A8EA"/>
</linearGradient>
<path fill="url(#SVGID_1_)" d="M1811.58,927.593l-0.809,0.426l-634.492,356.848c-2.768,1.703-5.578,3.321-8.517,4.769 c-10.777,5.132-22.481,8.029-34.407,8.517l-34.663-20.27c-2.929-1.47-5.773-3.105-8.517-4.897L447.167,906.003h-0.298 l-21.036-11.753v722.384c0.328,48.196,39.653,87.006,87.849,86.7h1230.914c0.724,0,1.363-0.341,2.129-0.341 c10.18-0.651,20.216-2.745,29.808-6.217c4.145-1.756,8.146-3.835,11.966-6.217c2.853-1.618,7.75-5.152,7.75-5.152 c21.814-16.142,34.726-41.635,34.833-68.772V894.25C1831.068,908.067,1823.616,920.807,1811.58,927.593z"/>
<path opacity="0.5" fill="#0A2767" enable-background="new " d="M1797.017,891.397v44.287l-663.448,456.791L446.699,906.301 c0-0.235-0.191-0.426-0.426-0.426l0,0l-63.023-37.899v-31.938l25.976-0.426l54.932,31.512l1.277,0.426l4.684,2.981 c0,0,645.563,368.346,647.267,369.197l24.698,14.478c2.129-0.852,4.258-1.703,6.813-2.555 c1.278-0.852,640.879-360.681,640.879-360.681L1797.017,891.397z"/>
<path fill="#1490DF" d="M1811.58,927.593l-0.809,0.468l-634.492,356.848c-2.768,1.703-5.578,3.321-8.517,4.769 c-24.641,12.038-53.457,12.038-78.098,0c-2.918-1.445-5.76-3.037-8.517-4.769L446.657,928.061l-0.766-0.468 c-12.25-6.642-19.93-19.409-20.057-33.343v722.384c0.305,48.188,39.616,87.004,87.803,86.7c0.001,0,0.002,0,0.004,0h1229.636 c48.188,0.307,87.5-38.509,87.807-86.696c0-0.001,0-0.002,0-0.004V894.25C1831.068,908.067,1823.616,920.807,1811.58,927.593z"/>
<path opacity="0.1" enable-background="new " d="M1185.52,1279.629l-9.496,5.323c-2.752,1.752-5.595,3.359-8.517,4.812 c-10.462,5.135-21.838,8.146-33.47,8.857l241.405,285.479l421.107,101.476c11.539-8.716,20.717-20.178,26.7-33.343L1185.52,1279.629 z"/>
<path opacity="0.05" enable-background="new " d="M1228.529,1255.442l-52.505,29.51c-2.752,1.752-5.595,3.359-8.517,4.812 c-10.462,5.135-21.838,8.146-33.47,8.857l113.101,311.838l549.538,74.989c21.649-16.254,34.394-41.743,34.407-68.815v-9.326 L1228.529,1255.442z"/>
<path fill="#28A8EA" d="M514.833,1703.333h1228.316c18.901,0.096,37.335-5.874,52.59-17.033l-697.089-408.331 c-2.929-1.47-5.773-3.105-8.517-4.897L447.125,906.088h-0.298l-20.993-11.838v719.914 C425.786,1663.364,465.632,1703.286,514.833,1703.333C514.832,1703.333,514.832,1703.333,514.833,1703.333z"/>
<path opacity="0.1" enable-background="new " d="M1022,418.722v908.303c-0.076,31.846-19.44,60.471-48.971,72.392 c-9.148,3.931-19,5.96-28.957,5.962H425.833V383.25H511v-42.583h433.073C987.092,340.83,1021.907,375.702,1022,418.722z"/>
<path opacity="0.2" enable-background="new " d="M979.417,461.305v908.302c0.107,10.287-2.074,20.469-6.388,29.808 c-11.826,29.149-40.083,48.273-71.54,48.417H425.833V383.25h475.656c12.356-0.124,24.533,2.958,35.344,8.943 C962.937,405.344,979.407,432.076,979.417,461.305z"/>
<path opacity="0.2" enable-background="new " d="M979.417,461.305v823.136c-0.208,43-34.928,77.853-77.927,78.225H425.833V383.25 h475.656c12.356-0.124,24.533,2.958,35.344,8.943C962.937,405.344,979.407,432.076,979.417,461.305z"/>
<path opacity="0.2" enable-background="new " d="M936.833,461.305v823.136c-0.046,43.067-34.861,78.015-77.927,78.225H425.833 V383.25h433.072c43.062,0.023,77.951,34.951,77.927,78.013C936.833,461.277,936.833,461.291,936.833,461.305z"/>
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="162.7469" y1="1383.0741" x2="774.0864" y2="324.2592" gradientTransform="matrix(1 0 0 -1 0 1705.3334)">
<stop offset="0" style="stop-color:#1784D9"/>
<stop offset="0.5" style="stop-color:#107AD5"/>
<stop offset="1" style="stop-color:#0A63C9"/>
</linearGradient>
<path fill="url(#SVGID_2_)" d="M78.055,383.25h780.723c43.109,0,78.055,34.947,78.055,78.055v780.723 c0,43.109-34.946,78.055-78.055,78.055H78.055c-43.109,0-78.055-34.947-78.055-78.055V461.305 C0,418.197,34.947,383.25,78.055,383.25z"/>
<path fill="#FFFFFF" d="M243.96,710.631c19.238-40.988,50.29-75.289,89.17-98.495c43.057-24.651,92.081-36.94,141.675-35.515 c45.965-0.997,91.321,10.655,131.114,33.683c37.414,22.312,67.547,55.004,86.742,94.109c20.904,43.09,31.322,90.512,30.405,138.396 c1.013,50.043-9.706,99.628-31.299,144.783c-19.652,40.503-50.741,74.36-89.425,97.388c-41.327,23.734-88.367,35.692-136.011,34.578 c-46.947,1.133-93.303-10.651-134.01-34.067c-37.738-22.341-68.249-55.07-87.892-94.28c-21.028-42.467-31.57-89.355-30.745-136.735 C212.808,804.859,223.158,755.686,243.96,710.631z M339.006,941.858c10.257,25.912,27.651,48.385,50.163,64.812 c22.93,16.026,50.387,24.294,78.353,23.591c29.783,1.178,59.14-7.372,83.634-24.358c22.227-16.375,39.164-38.909,48.715-64.812 c10.677-28.928,15.946-59.572,15.543-90.404c0.33-31.127-4.623-62.084-14.649-91.554c-8.855-26.607-25.246-50.069-47.182-67.537 c-23.88-17.79-53.158-26.813-82.91-25.55c-28.572-0.74-56.644,7.593-80.184,23.804c-22.893,16.496-40.617,39.168-51.1,65.365 c-23.255,60.049-23.376,126.595-0.341,186.728L339.006,941.858z"/>
<path fill="#50D9FF" d="M1362.667,255.5h383.25v383.25h-383.25V255.5z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@ -0,0 +1,14 @@
import { useTheme } from '@emotion/react';
import IconMicrosoftCalendarRaw from '../assets/microsoft-calendar.svg?react';
interface IconMicrosoftCalendarProps {
size?: number;
}
export const IconMicrosoftCalendar = (props: IconMicrosoftCalendarProps) => {
const theme = useTheme();
const size = props.size ?? theme.icon.size.lg;
return <IconMicrosoftCalendarRaw height={size} width={size} />;
};

View File

@ -16,6 +16,7 @@ export * from './icon/components/IconGoogle';
export * from './icon/components/IconGoogleCalendar';
export * from './icon/components/IconLock';
export * from './icon/components/IconMicrosoft';
export * from './icon/components/IconMicrosoftCalendar';
export * from './icon/components/IconMicrosoftOutlook';
export * from './icon/components/IconRelationManyToOne';
export * from './icon/components/IconTwentyStar';