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:
Faisal-imtiyaz123 2024-08-08 22:00:02 +05:30 committed by GitHub
parent 320742cdea
commit b4e2ada3b0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 149 additions and 85 deletions

View File

@ -96,7 +96,10 @@ export const SettingsDataModelFieldPreview = ({
return (
<>
{previewRecord ? (
<SettingsDataModelSetRecordEffect record={previewRecord} />
<SettingsDataModelSetRecordEffect
fieldName={fieldName}
record={previewRecord}
/>
) : (
<SettingsDataModelSetFieldValueEffect
recordId={recordId}

View File

@ -1,8 +1,10 @@
import { useEffect } from 'react';
import { useSetRecoilState } from 'recoil';
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 { 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 = {
recordId: string;
@ -15,19 +17,43 @@ export const SettingsDataModelSetFieldValueEffect = ({
fieldName,
value,
}: SettingsDataModelSetFieldValueEffectProps) => {
const previewRecordId = useRecoilValue(previewRecordIdState);
const upsertedPreviewRecord = useRecoilValue(
recordStoreFamilyState(previewRecordId ?? ''),
);
const setFieldValue = useSetRecoilState(
recordStoreFamilySelector({
recordId,
fieldName,
}),
);
const setRecordFieldValue = useSetRecordFieldValue();
useEffect(() => {
if (
isDefined(upsertedPreviewRecord) &&
!!upsertedPreviewRecord[fieldName]
) {
setFieldValue(upsertedPreviewRecord[fieldName]);
setRecordFieldValue(
recordId,
fieldName,
upsertedPreviewRecord[fieldName],
);
} else {
setFieldValue(value);
setRecordFieldValue(recordId, fieldName, value);
}, [value, setFieldValue, setRecordFieldValue, recordId, fieldName]);
}
}, [
value,
setFieldValue,
setRecordFieldValue,
recordId,
fieldName,
upsertedPreviewRecord,
]);
return null;
};

View File

@ -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 { 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 = {
record: ObjectRecord;
fieldName: string;
};
export const SettingsDataModelSetRecordEffect = ({
record,
fieldName,
}: SettingsDataModelSetRecordEffectProps) => {
const { upsertRecords: upsertRecordsInStore } = useUpsertRecordsInStore();
const setRecordFieldValue = useSetRecordFieldValue();
const setPreviewRecordId = useSetRecoilState(previewRecordIdState);
useEffect(() => {
upsertRecordsInStore([record]);
}, [record, upsertRecordsInStore]);
setRecordFieldValue(record.id, fieldName, record[fieldName]);
setPreviewRecordId(record.id);
}, [
record,
upsertRecordsInStore,
setRecordFieldValue,
fieldName,
setPreviewRecordId,
]);
return null;
};

View File

@ -0,0 +1,6 @@
import { createState } from 'twenty-ui';
export const previewRecordIdState = createState<string | null>({
key: 'previewRecordId',
defaultValue: null,
});

View File

@ -1,7 +1,7 @@
import styled from '@emotion/styled';
import { useMemo } from 'react';
import { Controller, useFormContext } from 'react-hook-form';
import styled from '@emotion/styled';
import { IconCircleOff, useIcons } from 'twenty-ui';
import { IconCircleOff, isDefined, useIcons } from 'twenty-ui';
import { z } from 'zod';
import { LABEL_IDENTIFIER_FIELD_METADATA_TYPES } from '@/object-metadata/constants/LabelIdentifierFieldMetadataTypes';
@ -22,6 +22,7 @@ export type SettingsDataModelObjectIdentifiersFormValues = z.infer<
type SettingsDataModelObjectIdentifiersFormProps = {
objectMetadataItem: ObjectMetadataItem;
defaultLabelIdentifierFieldMetadataId: string;
};
const StyledContainer = styled.div`
@ -31,6 +32,7 @@ const StyledContainer = styled.div`
export const SettingsDataModelObjectIdentifiersForm = ({
objectMetadataItem,
defaultLabelIdentifierFieldMetadataId,
}: SettingsDataModelObjectIdentifiersFormProps) => {
const { control } =
useFormContext<SettingsDataModelObjectIdentifiersFormValues>();
@ -58,7 +60,6 @@ export const SettingsDataModelObjectIdentifiersForm = ({
label: 'None',
value: null,
};
return (
<StyledContainer>
{[
@ -77,7 +78,13 @@ export const SettingsDataModelObjectIdentifiersForm = ({
key={fieldName}
name={fieldName}
control={control}
defaultValue={objectMetadataItem[fieldName]}
defaultValue={
fieldName === 'labelIdentifierFieldMetadataId'
? isDefined(objectMetadataItem[fieldName])
? objectMetadataItem[fieldName]
: defaultLabelIdentifierFieldMetadataId
: objectMetadataItem[fieldName]
}
render={({ field: { onBlur, onChange, value } }) => {
return (
<Select

View File

@ -1,6 +1,6 @@
import styled from '@emotion/styled';
import { useMemo } from 'react';
import { useFormContext } from 'react-hook-form';
import styled from '@emotion/styled';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { getLabelIdentifierFieldMetadataItem } from '@/object-metadata/utils/getLabelIdentifierFieldMetadataItem';
@ -78,6 +78,9 @@ export const SettingsDataModelObjectSettingsFormCard = ({
<CardContent>
<SettingsDataModelObjectIdentifiersForm
objectMetadataItem={objectMetadataItem}
defaultLabelIdentifierFieldMetadataId={
labelIdentifierFieldMetadataItem?.id
}
/>
</CardContent>
</Card>

View File

@ -1,6 +1,6 @@
import { useMemo, useRef, useState } from 'react';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useMemo, useRef, useState } from 'react';
import { IconChevronDown, IconComponent } from 'twenty-ui';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';

View File

@ -1,3 +1,5 @@
/* eslint-disable react/jsx-props-no-spreading */
import { zodResolver } from '@hookform/resolvers/zod';
import pick from 'lodash.pick';
import { useEffect } from 'react';
@ -28,6 +30,7 @@ import { Button } from '@/ui/input/button/components/Button';
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
import { Section } from '@/ui/layout/section/components/Section';
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
const objectEditFormSchema = z
.object({})
@ -103,7 +106,7 @@ export const SettingsObjectEdit = () => {
};
return (
// eslint-disable-next-line react/jsx-props-no-spreading
<RecordFieldValueSelectorContextProvider>
<FormProvider {...formConfig}>
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
<SettingsPageContainer>
@ -164,5 +167,6 @@ export const SettingsObjectEdit = () => {
</SettingsPageContainer>
</SubMenuTopBarContainer>
</FormProvider>
</RecordFieldValueSelectorContextProvider>
);
};

View File

@ -18,9 +18,9 @@ import {
SaveOptions,
UpdateResult,
} from 'typeorm';
import { PickKeysByType } from 'typeorm/common/PickKeysByType';
import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
import { UpsertOptions } from 'typeorm/repository/UpsertOptions';
import { PickKeysByType } from 'typeorm/common/PickKeysByType';
import { WorkspaceInternalContext } from 'src/engine/twenty-orm/interfaces/workspace-internal-context.interface';

View File

@ -1,17 +1,17 @@
import { Injectable } from '@nestjs/common';
import axios, { AxiosInstance } from 'axios';
import { EntityManager, ILike } from 'typeorm';
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 { 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 { 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 { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
import { computeDisplayName } from 'src/utils/compute-display-name';
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
type CompanyToCreate = {
domainName: string;

View File

@ -3,13 +3,13 @@ import { Injectable } from '@nestjs/common';
import { EntityManager } from 'typeorm';
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 { 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 { computeDisplayName } from 'src/utils/compute-display-name';
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
type ContactToCreate = {
handle: string;