Fixes Empty Label Identifer Preview in Settings/DataModel/Object/Edit (#6370)
fixes #6143 --------- Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
This commit is contained in:
committed by
GitHub
parent
320742cdea
commit
b4e2ada3b0
@ -96,7 +96,10 @@ export const SettingsDataModelFieldPreview = ({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{previewRecord ? (
|
{previewRecord ? (
|
||||||
<SettingsDataModelSetRecordEffect record={previewRecord} />
|
<SettingsDataModelSetRecordEffect
|
||||||
|
fieldName={fieldName}
|
||||||
|
record={previewRecord}
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
<SettingsDataModelSetFieldValueEffect
|
<SettingsDataModelSetFieldValueEffect
|
||||||
recordId={recordId}
|
recordId={recordId}
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
import { useEffect } from 'react';
|
|
||||||
import { useSetRecoilState } from 'recoil';
|
|
||||||
|
|
||||||
import { useSetRecordFieldValue } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
import { useSetRecordFieldValue } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
||||||
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
|
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
|
||||||
|
import { previewRecordIdState } from '@/settings/data-model/fields/preview/states/previewRecordIdState';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||||
|
import { isDefined } from '~/utils/isDefined';
|
||||||
|
|
||||||
type SettingsDataModelSetFieldValueEffectProps = {
|
type SettingsDataModelSetFieldValueEffectProps = {
|
||||||
recordId: string;
|
recordId: string;
|
||||||
@ -15,19 +17,43 @@ export const SettingsDataModelSetFieldValueEffect = ({
|
|||||||
fieldName,
|
fieldName,
|
||||||
value,
|
value,
|
||||||
}: SettingsDataModelSetFieldValueEffectProps) => {
|
}: SettingsDataModelSetFieldValueEffectProps) => {
|
||||||
|
const previewRecordId = useRecoilValue(previewRecordIdState);
|
||||||
|
|
||||||
|
const upsertedPreviewRecord = useRecoilValue(
|
||||||
|
recordStoreFamilyState(previewRecordId ?? ''),
|
||||||
|
);
|
||||||
|
|
||||||
const setFieldValue = useSetRecoilState(
|
const setFieldValue = useSetRecoilState(
|
||||||
recordStoreFamilySelector({
|
recordStoreFamilySelector({
|
||||||
recordId,
|
recordId,
|
||||||
fieldName,
|
fieldName,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const setRecordFieldValue = useSetRecordFieldValue();
|
const setRecordFieldValue = useSetRecordFieldValue();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setFieldValue(value);
|
if (
|
||||||
setRecordFieldValue(recordId, fieldName, value);
|
isDefined(upsertedPreviewRecord) &&
|
||||||
}, [value, setFieldValue, setRecordFieldValue, recordId, fieldName]);
|
!!upsertedPreviewRecord[fieldName]
|
||||||
|
) {
|
||||||
|
setFieldValue(upsertedPreviewRecord[fieldName]);
|
||||||
|
setRecordFieldValue(
|
||||||
|
recordId,
|
||||||
|
fieldName,
|
||||||
|
upsertedPreviewRecord[fieldName],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
setFieldValue(value);
|
||||||
|
setRecordFieldValue(recordId, fieldName, value);
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
value,
|
||||||
|
setFieldValue,
|
||||||
|
setRecordFieldValue,
|
||||||
|
recordId,
|
||||||
|
fieldName,
|
||||||
|
upsertedPreviewRecord,
|
||||||
|
]);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,20 +1,35 @@
|
|||||||
import { useEffect } from 'react';
|
import { useSetRecordFieldValue } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
||||||
|
|
||||||
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
|
import { useUpsertRecordsInStore } from '@/object-record/record-store/hooks/useUpsertRecordsInStore';
|
||||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||||
|
import { previewRecordIdState } from '@/settings/data-model/fields/preview/states/previewRecordIdState';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
type SettingsDataModelSetRecordEffectProps = {
|
type SettingsDataModelSetRecordEffectProps = {
|
||||||
record: ObjectRecord;
|
record: ObjectRecord;
|
||||||
|
fieldName: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SettingsDataModelSetRecordEffect = ({
|
export const SettingsDataModelSetRecordEffect = ({
|
||||||
record,
|
record,
|
||||||
|
fieldName,
|
||||||
}: SettingsDataModelSetRecordEffectProps) => {
|
}: SettingsDataModelSetRecordEffectProps) => {
|
||||||
const { upsertRecords: upsertRecordsInStore } = useUpsertRecordsInStore();
|
const { upsertRecords: upsertRecordsInStore } = useUpsertRecordsInStore();
|
||||||
|
const setRecordFieldValue = useSetRecordFieldValue();
|
||||||
|
|
||||||
|
const setPreviewRecordId = useSetRecoilState(previewRecordIdState);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
upsertRecordsInStore([record]);
|
upsertRecordsInStore([record]);
|
||||||
}, [record, upsertRecordsInStore]);
|
setRecordFieldValue(record.id, fieldName, record[fieldName]);
|
||||||
|
setPreviewRecordId(record.id);
|
||||||
|
}, [
|
||||||
|
record,
|
||||||
|
upsertRecordsInStore,
|
||||||
|
setRecordFieldValue,
|
||||||
|
fieldName,
|
||||||
|
setPreviewRecordId,
|
||||||
|
]);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -0,0 +1,6 @@
|
|||||||
|
import { createState } from 'twenty-ui';
|
||||||
|
|
||||||
|
export const previewRecordIdState = createState<string | null>({
|
||||||
|
key: 'previewRecordId',
|
||||||
|
defaultValue: null,
|
||||||
|
});
|
||||||
@ -1,7 +1,7 @@
|
|||||||
|
import styled from '@emotion/styled';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { Controller, useFormContext } from 'react-hook-form';
|
import { Controller, useFormContext } from 'react-hook-form';
|
||||||
import styled from '@emotion/styled';
|
import { IconCircleOff, isDefined, useIcons } from 'twenty-ui';
|
||||||
import { IconCircleOff, useIcons } from 'twenty-ui';
|
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { LABEL_IDENTIFIER_FIELD_METADATA_TYPES } from '@/object-metadata/constants/LabelIdentifierFieldMetadataTypes';
|
import { LABEL_IDENTIFIER_FIELD_METADATA_TYPES } from '@/object-metadata/constants/LabelIdentifierFieldMetadataTypes';
|
||||||
@ -22,6 +22,7 @@ export type SettingsDataModelObjectIdentifiersFormValues = z.infer<
|
|||||||
|
|
||||||
type SettingsDataModelObjectIdentifiersFormProps = {
|
type SettingsDataModelObjectIdentifiersFormProps = {
|
||||||
objectMetadataItem: ObjectMetadataItem;
|
objectMetadataItem: ObjectMetadataItem;
|
||||||
|
defaultLabelIdentifierFieldMetadataId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
@ -31,6 +32,7 @@ const StyledContainer = styled.div`
|
|||||||
|
|
||||||
export const SettingsDataModelObjectIdentifiersForm = ({
|
export const SettingsDataModelObjectIdentifiersForm = ({
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
|
defaultLabelIdentifierFieldMetadataId,
|
||||||
}: SettingsDataModelObjectIdentifiersFormProps) => {
|
}: SettingsDataModelObjectIdentifiersFormProps) => {
|
||||||
const { control } =
|
const { control } =
|
||||||
useFormContext<SettingsDataModelObjectIdentifiersFormValues>();
|
useFormContext<SettingsDataModelObjectIdentifiersFormValues>();
|
||||||
@ -58,7 +60,6 @@ export const SettingsDataModelObjectIdentifiersForm = ({
|
|||||||
label: 'None',
|
label: 'None',
|
||||||
value: null,
|
value: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
{[
|
{[
|
||||||
@ -77,7 +78,13 @@ export const SettingsDataModelObjectIdentifiersForm = ({
|
|||||||
key={fieldName}
|
key={fieldName}
|
||||||
name={fieldName}
|
name={fieldName}
|
||||||
control={control}
|
control={control}
|
||||||
defaultValue={objectMetadataItem[fieldName]}
|
defaultValue={
|
||||||
|
fieldName === 'labelIdentifierFieldMetadataId'
|
||||||
|
? isDefined(objectMetadataItem[fieldName])
|
||||||
|
? objectMetadataItem[fieldName]
|
||||||
|
: defaultLabelIdentifierFieldMetadataId
|
||||||
|
: objectMetadataItem[fieldName]
|
||||||
|
}
|
||||||
render={({ field: { onBlur, onChange, value } }) => {
|
render={({ field: { onBlur, onChange, value } }) => {
|
||||||
return (
|
return (
|
||||||
<Select
|
<Select
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
|
import styled from '@emotion/styled';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useFormContext } from 'react-hook-form';
|
import { useFormContext } from 'react-hook-form';
|
||||||
import styled from '@emotion/styled';
|
|
||||||
|
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
import { getLabelIdentifierFieldMetadataItem } from '@/object-metadata/utils/getLabelIdentifierFieldMetadataItem';
|
import { getLabelIdentifierFieldMetadataItem } from '@/object-metadata/utils/getLabelIdentifierFieldMetadataItem';
|
||||||
@ -78,6 +78,9 @@ export const SettingsDataModelObjectSettingsFormCard = ({
|
|||||||
<CardContent>
|
<CardContent>
|
||||||
<SettingsDataModelObjectIdentifiersForm
|
<SettingsDataModelObjectIdentifiersForm
|
||||||
objectMetadataItem={objectMetadataItem}
|
objectMetadataItem={objectMetadataItem}
|
||||||
|
defaultLabelIdentifierFieldMetadataId={
|
||||||
|
labelIdentifierFieldMetadataItem?.id
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { useMemo, useRef, useState } from 'react';
|
|
||||||
import { useTheme } from '@emotion/react';
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
import { useMemo, useRef, useState } from 'react';
|
||||||
import { IconChevronDown, IconComponent } from 'twenty-ui';
|
import { IconChevronDown, IconComponent } from 'twenty-ui';
|
||||||
|
|
||||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
/* eslint-disable react/jsx-props-no-spreading */
|
||||||
|
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import pick from 'lodash.pick';
|
import pick from 'lodash.pick';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
@ -28,6 +30,7 @@ import { Button } from '@/ui/input/button/components/Button';
|
|||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
|
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
|
||||||
import { Section } from '@/ui/layout/section/components/Section';
|
import { Section } from '@/ui/layout/section/components/Section';
|
||||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||||
|
import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
||||||
|
|
||||||
const objectEditFormSchema = z
|
const objectEditFormSchema = z
|
||||||
.object({})
|
.object({})
|
||||||
@ -103,66 +106,67 @@ export const SettingsObjectEdit = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
<RecordFieldValueSelectorContextProvider>
|
||||||
<FormProvider {...formConfig}>
|
<FormProvider {...formConfig}>
|
||||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||||
<SettingsPageContainer>
|
<SettingsPageContainer>
|
||||||
<SettingsHeaderContainer>
|
<SettingsHeaderContainer>
|
||||||
<Breadcrumb
|
<Breadcrumb
|
||||||
links={[
|
links={[
|
||||||
{
|
{
|
||||||
children: 'Objects',
|
children: 'Objects',
|
||||||
href: settingsObjectsPagePath,
|
href: settingsObjectsPagePath,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
children: activeObjectMetadataItem.labelPlural,
|
children: activeObjectMetadataItem.labelPlural,
|
||||||
href: `${settingsObjectsPagePath}/${objectSlug}`,
|
href: `${settingsObjectsPagePath}/${objectSlug}`,
|
||||||
},
|
},
|
||||||
{ children: 'Edit' },
|
{ children: 'Edit' },
|
||||||
]}
|
]}
|
||||||
/>
|
|
||||||
{activeObjectMetadataItem.isCustom && (
|
|
||||||
<SaveAndCancelButtons
|
|
||||||
isSaveDisabled={!canSave}
|
|
||||||
isCancelDisabled={isSubmitting}
|
|
||||||
onCancel={() =>
|
|
||||||
navigate(`${settingsObjectsPagePath}/${objectSlug}`)
|
|
||||||
}
|
|
||||||
onSave={formConfig.handleSubmit(handleSave)}
|
|
||||||
/>
|
/>
|
||||||
)}
|
{activeObjectMetadataItem.isCustom && (
|
||||||
</SettingsHeaderContainer>
|
<SaveAndCancelButtons
|
||||||
<Section>
|
isSaveDisabled={!canSave}
|
||||||
<H2Title
|
isCancelDisabled={isSubmitting}
|
||||||
title="About"
|
onCancel={() =>
|
||||||
description="Name in both singular (e.g., 'Invoice') and plural (e.g., 'Invoices') forms."
|
navigate(`${settingsObjectsPagePath}/${objectSlug}`)
|
||||||
/>
|
}
|
||||||
<SettingsDataModelObjectAboutForm
|
onSave={formConfig.handleSubmit(handleSave)}
|
||||||
disabled={!activeObjectMetadataItem.isCustom}
|
/>
|
||||||
disableNameEdit
|
)}
|
||||||
objectMetadataItem={activeObjectMetadataItem}
|
</SettingsHeaderContainer>
|
||||||
/>
|
<Section>
|
||||||
</Section>
|
<H2Title
|
||||||
<Section>
|
title="About"
|
||||||
<H2Title
|
description="Name in both singular (e.g., 'Invoice') and plural (e.g., 'Invoices') forms."
|
||||||
title="Settings"
|
/>
|
||||||
description="Choose the fields that will identify your records"
|
<SettingsDataModelObjectAboutForm
|
||||||
/>
|
disabled={!activeObjectMetadataItem.isCustom}
|
||||||
<SettingsDataModelObjectSettingsFormCard
|
disableNameEdit
|
||||||
objectMetadataItem={activeObjectMetadataItem}
|
objectMetadataItem={activeObjectMetadataItem}
|
||||||
/>
|
/>
|
||||||
</Section>
|
</Section>
|
||||||
<Section>
|
<Section>
|
||||||
<H2Title title="Danger zone" description="Deactivate object" />
|
<H2Title
|
||||||
<Button
|
title="Settings"
|
||||||
Icon={IconArchive}
|
description="Choose the fields that will identify your records"
|
||||||
title="Deactivate"
|
/>
|
||||||
size="small"
|
<SettingsDataModelObjectSettingsFormCard
|
||||||
onClick={handleDisable}
|
objectMetadataItem={activeObjectMetadataItem}
|
||||||
/>
|
/>
|
||||||
</Section>
|
</Section>
|
||||||
</SettingsPageContainer>
|
<Section>
|
||||||
</SubMenuTopBarContainer>
|
<H2Title title="Danger zone" description="Deactivate object" />
|
||||||
</FormProvider>
|
<Button
|
||||||
|
Icon={IconArchive}
|
||||||
|
title="Deactivate"
|
||||||
|
size="small"
|
||||||
|
onClick={handleDisable}
|
||||||
|
/>
|
||||||
|
</Section>
|
||||||
|
</SettingsPageContainer>
|
||||||
|
</SubMenuTopBarContainer>
|
||||||
|
</FormProvider>
|
||||||
|
</RecordFieldValueSelectorContextProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -18,9 +18,9 @@ import {
|
|||||||
SaveOptions,
|
SaveOptions,
|
||||||
UpdateResult,
|
UpdateResult,
|
||||||
} from 'typeorm';
|
} from 'typeorm';
|
||||||
|
import { PickKeysByType } from 'typeorm/common/PickKeysByType';
|
||||||
import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
|
import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
|
||||||
import { UpsertOptions } from 'typeorm/repository/UpsertOptions';
|
import { UpsertOptions } from 'typeorm/repository/UpsertOptions';
|
||||||
import { PickKeysByType } from 'typeorm/common/PickKeysByType';
|
|
||||||
|
|
||||||
import { WorkspaceInternalContext } from 'src/engine/twenty-orm/interfaces/workspace-internal-context.interface';
|
import { WorkspaceInternalContext } from 'src/engine/twenty-orm/interfaces/workspace-internal-context.interface';
|
||||||
|
|
||||||
|
|||||||
@ -1,17 +1,17 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
import axios, { AxiosInstance } from 'axios';
|
import axios, { AxiosInstance } from 'axios';
|
||||||
import { EntityManager, ILike } from 'typeorm';
|
|
||||||
import uniqBy from 'lodash.uniqby';
|
import uniqBy from 'lodash.uniqby';
|
||||||
|
import { EntityManager, ILike } from 'typeorm';
|
||||||
|
|
||||||
|
import { FieldActorSource } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
|
||||||
|
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
||||||
|
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||||
import { CompanyWorkspaceEntity } from 'src/modules/company/standard-objects/company.workspace-entity';
|
import { CompanyWorkspaceEntity } from 'src/modules/company/standard-objects/company.workspace-entity';
|
||||||
import { extractDomainFromLink } from 'src/modules/contact-creation-manager/utils/extract-domain-from-link.util';
|
import { extractDomainFromLink } from 'src/modules/contact-creation-manager/utils/extract-domain-from-link.util';
|
||||||
import { getCompanyNameFromDomainName } from 'src/modules/contact-creation-manager/utils/get-company-name-from-domain-name.util';
|
import { getCompanyNameFromDomainName } from 'src/modules/contact-creation-manager/utils/get-company-name-from-domain-name.util';
|
||||||
import { FieldActorSource } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
|
|
||||||
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
|
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
|
||||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
|
||||||
import { computeDisplayName } from 'src/utils/compute-display-name';
|
import { computeDisplayName } from 'src/utils/compute-display-name';
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
|
||||||
|
|
||||||
type CompanyToCreate = {
|
type CompanyToCreate = {
|
||||||
domainName: string;
|
domainName: string;
|
||||||
|
|||||||
@ -3,13 +3,13 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import { EntityManager } from 'typeorm';
|
import { EntityManager } from 'typeorm';
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
|
import { FieldActorSource } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
|
||||||
|
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
||||||
|
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||||
import { getFirstNameAndLastNameFromHandleAndDisplayName } from 'src/modules/contact-creation-manager/utils/get-first-name-and-last-name-from-handle-and-display-name.util';
|
import { getFirstNameAndLastNameFromHandleAndDisplayName } from 'src/modules/contact-creation-manager/utils/get-first-name-and-last-name-from-handle-and-display-name.util';
|
||||||
import { PersonWorkspaceEntity } from 'src/modules/person/standard-objects/person.workspace-entity';
|
import { PersonWorkspaceEntity } from 'src/modules/person/standard-objects/person.workspace-entity';
|
||||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
|
||||||
import { FieldActorSource } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
|
|
||||||
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
|
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
|
||||||
import { computeDisplayName } from 'src/utils/compute-display-name';
|
import { computeDisplayName } from 'src/utils/compute-display-name';
|
||||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
|
||||||
|
|
||||||
type ContactToCreate = {
|
type ContactToCreate = {
|
||||||
handle: string;
|
handle: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user