Refactor Field Inputs (#3658)

* Rename field to record-field folder

* Simplify FieldInput

* Fix perfs

* Fixes

* Fixes

* Fix tests

* Fix tests
This commit is contained in:
Charles Bochet
2024-01-27 23:42:39 +01:00
committed by GitHub
parent d6f117c688
commit ada8f55574
228 changed files with 975 additions and 1037 deletions

View File

@@ -7,11 +7,11 @@ import { AttachmentIcon } from '@/activities/files/components/AttachmentIcon';
import { Attachment } from '@/activities/files/types/Attachment';
import { downloadFile } from '@/activities/files/utils/downloadFile';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
import {
FieldContext,
GenericFieldContextType,
} from '@/object-record/field/contexts/FieldContext';
import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
} from '@/object-record/record-field/contexts/FieldContext';
import { IconCalendar } from '@/ui/display/icon';
import { REACT_APP_SERVER_BASE_URL } from '~/config';
import { formatToHumanReadableDate } from '~/utils';

View File

@@ -3,11 +3,10 @@ import { useActivityTargetObjectRecords } from '@/activities/hooks/useActivityTa
import { ActivityTargetInlineCellEditMode } from '@/activities/inline-cell/components/ActivityTargetInlineCellEditMode';
import { ActivityTarget } from '@/activities/types/ActivityTarget';
import { GraphQLActivity } from '@/activities/types/GraphQLActivity';
import { RecordFieldInputScope } from '@/object-record/record-field/scopes/RecordFieldInputScope';
import { RecordInlineCellContainer } from '@/object-record/record-inline-cell/components/RecordInlineCellContainer';
import { FieldRecoilScopeContext } from '@/object-record/record-inline-cell/states/recoil-scope-contexts/FieldRecoilScopeContext';
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
import { IconArrowUpRight, IconPencil } from '@/ui/display/icon';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
type ActivityTargetsInlineCellProps = {
activity?: Pick<GraphQLActivity, 'id'> & {
@@ -27,7 +26,7 @@ export const ActivityTargetsInlineCell = ({
});
return (
<RecoilScope CustomRecoilScopeContext={FieldRecoilScopeContext}>
<RecordFieldInputScope recordFieldInputScopeId={activity?.id ?? ''}>
<RecordInlineCellContainer
buttonIcon={IconPencil}
customEditHotkeyScope={{
@@ -48,6 +47,6 @@ export const ActivityTargetsInlineCell = ({
}
isDisplayModeContentEmpty={activityTargetObjectRecords.length === 0}
/>
</RecoilScope>
</RecordFieldInputScope>
);
};

View File

@@ -10,7 +10,7 @@ import { getActivityPreview } from '@/activities/utils/getActivityPreview';
import {
FieldContext,
GenericFieldContextType,
} from '@/object-record/field/contexts/FieldContext';
} from '@/object-record/record-field/contexts/FieldContext';
import { IconComment } from '@/ui/display/icon';
const StyledCard = styled.div<{ isSingleNote: boolean }>`

View File

@@ -3,16 +3,16 @@ import styled from '@emotion/styled';
import { useRecoilState, useRecoilValue } from 'recoil';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import {
FieldContext,
RecordUpdateHook,
RecordUpdateHookParams,
} from '@/object-record/field/contexts/FieldContext';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import { BoardCardIdContext } from '@/object-record/record-board-deprecated/contexts/BoardCardIdContext';
import { useCurrentRecordBoardDeprecatedCardSelectedInternal } from '@/object-record/record-board-deprecated/hooks/internal/useCurrentRecordBoardDeprecatedCardSelectedInternal';
import { useRecordBoardDeprecatedScopedStates } from '@/object-record/record-board-deprecated/hooks/internal/useRecordBoardDeprecatedScopedStates';
import { isRecordBoardDeprecatedCardInCompactViewFamilyState } from '@/object-record/record-board-deprecated/states/isRecordBoardDeprecatedCardInCompactViewFamilyState';
import {
FieldContext,
RecordUpdateHook,
RecordUpdateHookParams,
} from '@/object-record/record-field/contexts/FieldContext';
import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell';
import { InlineCellHotkeyScope } from '@/object-record/record-inline-cell/types/InlineCellHotkeyScope';
import { EntityChipVariant } from '@/ui/display/chip/components/EntityChip';

View File

@@ -1,6 +1,6 @@
import { mapBoardFieldDefinitionsToViewFields } from '@/companies/utils/mapBoardFieldDefinitionsToViewFields';
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { BoardFieldDefinition } from '@/object-record/record-board-deprecated/types/BoardFieldDefinition';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
describe('mapBoardFieldDefinitionsToViewFields', () => {
it('should map board field definitions to view fields', () => {

View File

@@ -1,5 +1,5 @@
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { BoardFieldDefinition } from '@/object-record/record-board-deprecated/types/BoardFieldDefinition';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { ViewField } from '@/views/types/ViewField';
export const mapBoardFieldDefinitionsToViewFields = (

View File

@@ -1,7 +1,7 @@
import { useMemo } from 'react';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
import { Nullable } from '~/types/Nullable';

View File

@@ -1,7 +1,7 @@
import { ApolloClient, useMutation } from '@apollo/client';
import { getOperationName } from '@apollo/client/utilities';
import { FieldType } from '@/object-record/field/types/FieldType';
import { FieldType } from '@/object-record/record-field/types/FieldType';
import {
CreateOneFieldMetadataItemMutation,
CreateOneFieldMetadataItemMutationVariables,

View File

@@ -1,6 +1,6 @@
import { v4 } from 'uuid';
import { FieldType } from '@/object-record/field/types/FieldType';
import { FieldType } from '@/object-record/record-field/types/FieldType';
import { Field } from '~/generated/graphql';
import { FieldMetadataType } from '~/generated-metadata/graphql';

View File

@@ -1,7 +1,7 @@
import { useRecoilValue } from 'recoil';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { FieldType } from '@/object-record/field/types/FieldType';
import { FieldType } from '@/object-record/record-field/types/FieldType';
import { FieldMetadataItem } from '../types/FieldMetadataItem';

View File

@@ -1,6 +1,6 @@
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { parseFieldRelationType } from '@/object-metadata/utils/parseFieldRelationType';
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
import { FieldMetadataItem } from '../types/FieldMetadataItem';

View File

@@ -1,5 +1,5 @@
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { FieldDefinitionRelationType } from '@/object-record/field/types/FieldDefinition';
import { FieldDefinitionRelationType } from '@/object-record/record-field/types/FieldDefinition';
import {
FieldMetadataType,
RelationMetadataType,

View File

@@ -1,4 +1,4 @@
import { FieldType } from '@/object-record/field/types/FieldType';
import { FieldType } from '@/object-record/record-field/types/FieldType';
import { FieldMetadataType } from '~/generated-metadata/graphql';
export const parseFieldType = (fieldType: FieldMetadataType): FieldType => {

View File

@@ -1,62 +0,0 @@
import { ReactNode } from 'react';
import { act, renderHook } from '@testing-library/react';
import { RecoilRoot, useSetRecoilState } from 'recoil';
import {
fieldMetadataId,
textfieldDefinition,
} from '@/object-record/field/__mocks__/fieldDefinitions';
import { FieldContext } from '@/object-record/field/contexts/FieldContext';
import { entityFieldInitialValueFamilyState } from '@/object-record/field/states/entityFieldInitialValueFamilyState';
import { useFieldInitialValue } from '../useFieldInitialValue';
const entityId = 'entityId';
const wrapper = ({ children }: { children: ReactNode }) => (
<RecoilRoot>
<FieldContext.Provider
value={{
fieldDefinition: textfieldDefinition,
entityId,
hotkeyScope: 'hotkeyScope',
isLabelIdentifier: false,
}}
>
{children}
</FieldContext.Provider>
</RecoilRoot>
);
describe('useFieldInitialValue', () => {
it('should work as expected', () => {
const { result } = renderHook(
() => {
const setFieldInitialValue = useSetRecoilState(
entityFieldInitialValueFamilyState({
fieldMetadataId,
entityId,
}),
);
return {
setFieldInitialValue,
fieldInitialValue: useFieldInitialValue(),
};
},
{
wrapper,
},
);
expect(result.current.fieldInitialValue).toBeUndefined();
const initialValue = { isEmpty: false, value: 'Sheldon Cooper' };
act(() => {
result.current.setFieldInitialValue(initialValue);
});
expect(result.current.fieldInitialValue).toEqual(initialValue);
});
});

View File

@@ -1,52 +0,0 @@
import { ReactNode } from 'react';
import { act, renderHook } from '@testing-library/react';
import { RecoilRoot, useSetRecoilState } from 'recoil';
import { phoneFieldDefinition } from '@/object-record/field/__mocks__/fieldDefinitions';
import { FieldContext } from '@/object-record/field/contexts/FieldContext';
import { useIsFieldEditModeValueEmpty } from '@/object-record/field/hooks/useIsFieldEditModeValueEmpty';
import { entityFieldsEditModeValueFamilyState } from '@/object-record/field/states/entityFieldsEditModeValueFamilyState';
const entityId = 'entityId';
const Wrapper = ({ children }: { children: ReactNode }) => (
<FieldContext.Provider
value={{
fieldDefinition: phoneFieldDefinition,
entityId,
hotkeyScope: 'hotkeyScope',
isLabelIdentifier: false,
}}
>
<RecoilRoot>{children}</RecoilRoot>
</FieldContext.Provider>
);
describe('useIsFieldEditModeValueEmpty', () => {
it('should work as expected', () => {
const { result } = renderHook(
() => {
const setFieldEditModeValue = useSetRecoilState(
entityFieldsEditModeValueFamilyState(entityId),
);
return {
setFieldEditModeValue,
isFieldEditModeValueEmpty: useIsFieldEditModeValueEmpty(),
};
},
{
wrapper: Wrapper,
},
);
expect(result.current.isFieldEditModeValueEmpty).toBe(true);
act(() => {
result.current.setFieldEditModeValue({
phone: '+1 233223',
});
});
expect(result.current.isFieldEditModeValueEmpty).toBe(false);
});
});

View File

@@ -1,57 +0,0 @@
import { ReactNode } from 'react';
import { MockedProvider } from '@apollo/client/testing';
import { act, renderHook } from '@testing-library/react';
import { RecoilRoot, useRecoilValue } from 'recoil';
import { phoneFieldDefinition } from '@/object-record/field/__mocks__/fieldDefinitions';
import { FieldContext } from '@/object-record/field/contexts/FieldContext';
import { useSaveFieldEditModeValue } from '@/object-record/field/hooks/useSaveFieldEditModeValue';
import { entityFieldsEditModeValueFamilySelector } from '@/object-record/field/states/selectors/entityFieldsEditModeValueFamilySelector';
const entityId = 'entityId';
const fieldName = 'phone';
const Wrapper = ({ children }: { children: ReactNode }) => {
return (
<MockedProvider addTypename={false}>
<FieldContext.Provider
value={{
fieldDefinition: phoneFieldDefinition,
entityId,
hotkeyScope: 'hotkeyScope',
isLabelIdentifier: false,
}}
>
<RecoilRoot>{children}</RecoilRoot>
</FieldContext.Provider>
</MockedProvider>
);
};
describe('useSaveFieldEditModeValue', () => {
it('should work as expected', () => {
const {
result: { current },
} = renderHook(
() => {
const entityFieldsEditModeValue = useRecoilValue(
entityFieldsEditModeValueFamilySelector({ entityId, fieldName }),
);
return {
saveFieldEditModeValue: useSaveFieldEditModeValue(),
entityFieldsEditModeValue,
};
},
{ wrapper: Wrapper },
);
expect(current.entityFieldsEditModeValue).toBeUndefined();
act(() => {
current.saveFieldEditModeValue('test');
});
// We expect `current.entityFieldsEditModeValue` to be updated
// but I think it's async
});
});

View File

@@ -1,18 +0,0 @@
import { useContext } from 'react';
import { useRecoilValue } from 'recoil';
import { FieldContext } from '../contexts/FieldContext';
import { entityFieldInitialValueFamilyState } from '../states/entityFieldInitialValueFamilyState';
export const useFieldInitialValue = () => {
const { entityId, fieldDefinition } = useContext(FieldContext);
const fieldInitialValue = useRecoilValue(
entityFieldInitialValueFamilyState({
fieldMetadataId: fieldDefinition.fieldMetadataId,
entityId,
}),
);
return fieldInitialValue;
};

View File

@@ -1,22 +0,0 @@
import { useContext } from 'react';
import { useRecoilValue } from 'recoil';
import { isEntityFieldEditModeEmptyFamilySelector } from '@/object-record/field/states/selectors/isEntityFieldEditModeEmptyFamilySelector';
import { FieldContext } from '../contexts/FieldContext';
export const useIsFieldEditModeValueEmpty = () => {
const { entityId, fieldDefinition } = useContext(FieldContext);
const isFieldEditModeValueEmpty = useRecoilValue(
isEntityFieldEditModeEmptyFamilySelector({
fieldDefinition: {
type: fieldDefinition.type,
},
fieldName: fieldDefinition.metadata.fieldName,
entityId,
}),
);
return isFieldEditModeValueEmpty;
};

View File

@@ -1,112 +0,0 @@
import { useContext } from 'react';
import { useRecoilCallback } from 'recoil';
import { entityFieldsEditModeValueFamilySelector } from '@/object-record/field/states/selectors/entityFieldsEditModeValueFamilySelector';
import { isFieldFullName } from '@/object-record/field/types/guards/isFieldFullName';
import { isFieldFullNameValue } from '@/object-record/field/types/guards/isFieldFullNameValue';
import { FieldContext } from '../contexts/FieldContext';
import { isFieldBoolean } from '../types/guards/isFieldBoolean';
import { isFieldBooleanValue } from '../types/guards/isFieldBooleanValue';
import { isFieldCurrency } from '../types/guards/isFieldCurrency';
import { isFieldCurrencyValue } from '../types/guards/isFieldCurrencyValue';
import { isFieldDateTime } from '../types/guards/isFieldDateTime';
import { isFieldDateTimeValue } from '../types/guards/isFieldDateTimeValue';
import { isFieldEmail } from '../types/guards/isFieldEmail';
import { isFieldEmailValue } from '../types/guards/isFieldEmailValue';
import { isFieldLink } from '../types/guards/isFieldLink';
import { isFieldLinkValue } from '../types/guards/isFieldLinkValue';
import { isFieldNumber } from '../types/guards/isFieldNumber';
import { isFieldNumberValue } from '../types/guards/isFieldNumberValue';
import { isFieldPhone } from '../types/guards/isFieldPhone';
import { isFieldPhoneValue } from '../types/guards/isFieldPhoneValue';
import { isFieldRating } from '../types/guards/isFieldRating';
import { isFieldRatingValue } from '../types/guards/isFieldRatingValue';
import { isFieldRelation } from '../types/guards/isFieldRelation';
import { isFieldRelationValue } from '../types/guards/isFieldRelationValue';
import { isFieldText } from '../types/guards/isFieldText';
import { isFieldTextValue } from '../types/guards/isFieldTextValue';
export const useSaveFieldEditModeValue = () => {
const { entityId, fieldDefinition } = useContext(FieldContext);
const saveFieldEditModeValue = useRecoilCallback(
({ set }) =>
(currentValue: unknown) => {
const fieldIsRelation =
isFieldRelation(fieldDefinition) &&
isFieldRelationValue(currentValue);
const fieldIsText =
isFieldText(fieldDefinition) && isFieldTextValue(currentValue);
const fieldIsEmail =
isFieldEmail(fieldDefinition) && isFieldEmailValue(currentValue);
const fieldIsDateTime =
isFieldDateTime(fieldDefinition) &&
isFieldDateTimeValue(currentValue);
const fieldIsLink =
isFieldLink(fieldDefinition) && isFieldLinkValue(currentValue);
const fieldIsBoolean =
isFieldBoolean(fieldDefinition) && isFieldBooleanValue(currentValue);
const fieldIsProbability =
isFieldRating(fieldDefinition) && isFieldRatingValue(currentValue);
const fieldIsNumber =
isFieldNumber(fieldDefinition) && isFieldNumberValue(currentValue);
const fieldIsCurrency =
isFieldCurrency(fieldDefinition) &&
isFieldCurrencyValue(currentValue);
const fieldIsFullName =
isFieldFullName(fieldDefinition) &&
isFieldFullNameValue(currentValue);
const fieldIsPhone =
isFieldPhone(fieldDefinition) && isFieldPhoneValue(currentValue);
if (fieldIsRelation) {
const fieldName = fieldDefinition.metadata.fieldName;
set(
entityFieldsEditModeValueFamilySelector({ entityId, fieldName }),
currentValue,
);
} else if (
fieldIsText ||
fieldIsBoolean ||
fieldIsEmail ||
fieldIsProbability ||
fieldIsNumber ||
fieldIsDateTime ||
fieldIsPhone ||
fieldIsLink ||
fieldIsCurrency ||
fieldIsFullName
) {
const fieldName = fieldDefinition.metadata.fieldName;
set(
entityFieldsEditModeValueFamilySelector({ entityId, fieldName }),
currentValue,
);
} else {
throw new Error(
`Invalid value to save: ${JSON.stringify(
currentValue,
)} for type : ${
fieldDefinition.type
}, type may not be implemented in useSaveFieldEditModeValue.`,
);
}
},
[entityId, fieldDefinition],
);
return saveFieldEditModeValue;
};

View File

@@ -1,11 +0,0 @@
import { atomFamily } from 'recoil';
import { FieldInitialValue } from '../types/FieldInitialValue';
export const entityFieldInitialValueFamilyState = atomFamily<
FieldInitialValue | undefined,
{ entityId: string; fieldMetadataId: string }
>({
key: 'entityFieldInitialValueFamilyState',
default: undefined,
});

View File

@@ -1,9 +0,0 @@
import { atomFamily } from 'recoil';
export const entityFieldsEditModeValueFamilyState = atomFamily<
Record<string, unknown> | null,
string
>({
key: 'entityFieldsEditModeValueFamilyState',
default: null,
});

View File

@@ -1,6 +0,0 @@
import { atomFamily } from 'recoil';
export const isFieldEmptyScopedState = atomFamily<boolean, string>({
key: 'isFieldEmptyScopedState',
default: false,
});

View File

@@ -1,18 +0,0 @@
import { selectorFamily } from 'recoil';
import { entityFieldsEditModeValueFamilyState } from '@/object-record/field/states/entityFieldsEditModeValueFamilyState';
export const entityFieldsEditModeValueFamilySelector = selectorFamily({
key: 'entityFieldsEditModeValueFamilySelector',
get:
<T>({ fieldName, entityId }: { fieldName: string; entityId: string }) =>
({ get }) =>
get(entityFieldsEditModeValueFamilyState(entityId))?.[fieldName] as T,
set:
<T>({ fieldName, entityId }: { fieldName: string; entityId: string }) =>
({ set }, newValue: T) =>
set(entityFieldsEditModeValueFamilyState(entityId), (prevState) => ({
...prevState,
[fieldName]: newValue,
})),
});

View File

@@ -1,31 +0,0 @@
import { selectorFamily } from 'recoil';
import { entityFieldsEditModeValueFamilyState } from '@/object-record/field/states/entityFieldsEditModeValueFamilyState';
import { isFieldValueEmpty } from '@/object-record/field/utils/isFieldValueEmpty';
import { FieldDefinition } from '../../types/FieldDefinition';
import { FieldMetadata } from '../../types/FieldMetadata';
export const isEntityFieldEditModeEmptyFamilySelector = selectorFamily({
key: 'isEntityFieldEditModeEmptyFamilySelector',
get: ({
fieldDefinition,
fieldName,
entityId,
}: {
fieldDefinition: Pick<FieldDefinition<FieldMetadata>, 'type'>;
fieldName: string;
entityId: string;
}) => {
return ({ get }) => {
const fieldValue = get(entityFieldsEditModeValueFamilyState(entityId))?.[
fieldName
];
return isFieldValueEmpty({
fieldDefinition,
fieldValue,
});
};
},
});

View File

@@ -1,29 +0,0 @@
import { selectorFamily } from 'recoil';
import { isFieldValueEmpty } from '@/object-record/field/utils/isFieldValueEmpty';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { FieldDefinition } from '../../types/FieldDefinition';
import { FieldMetadata } from '../../types/FieldMetadata';
export const isEntityFieldEmptyFamilySelector = selectorFamily({
key: 'isEntityFieldEmptyFamilySelector',
get: ({
fieldDefinition,
fieldName,
entityId,
}: {
fieldDefinition: Pick<FieldDefinition<FieldMetadata>, 'type'>;
fieldName: string;
entityId: string;
}) => {
return ({ get }) => {
const fieldValue = get(recordStoreFamilyState(entityId))?.[fieldName];
return isFieldValueEmpty({
fieldDefinition,
fieldValue,
});
};
},
});

View File

@@ -1,4 +0,0 @@
export type FieldInitialValue = {
isEmpty?: boolean;
value?: string;
};

View File

@@ -1,73 +0,0 @@
import { FieldDefinition } from '@/object-record/field/types/FieldDefinition';
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { isFieldBoolean } from '@/object-record/field/types/guards/isFieldBoolean';
import { isFieldCurrency } from '@/object-record/field/types/guards/isFieldCurrency';
import { isFieldCurrencyValue } from '@/object-record/field/types/guards/isFieldCurrencyValue';
import { isFieldDateTime } from '@/object-record/field/types/guards/isFieldDateTime';
import { isFieldEmail } from '@/object-record/field/types/guards/isFieldEmail';
import { isFieldFullName } from '@/object-record/field/types/guards/isFieldFullName';
import { isFieldFullNameValue } from '@/object-record/field/types/guards/isFieldFullNameValue';
import { isFieldLink } from '@/object-record/field/types/guards/isFieldLink';
import { isFieldLinkValue } from '@/object-record/field/types/guards/isFieldLinkValue';
import { isFieldNumber } from '@/object-record/field/types/guards/isFieldNumber';
import { isFieldRating } from '@/object-record/field/types/guards/isFieldRating';
import { isFieldRelation } from '@/object-record/field/types/guards/isFieldRelation';
import { isFieldRelationValue } from '@/object-record/field/types/guards/isFieldRelationValue';
import { isFieldSelect } from '@/object-record/field/types/guards/isFieldSelect';
import { isFieldSelectValue } from '@/object-record/field/types/guards/isFieldSelectValue';
import { isFieldText } from '@/object-record/field/types/guards/isFieldText';
import { isFieldUuid } from '@/object-record/field/types/guards/isFieldUuid';
import { assertNotNull } from '~/utils/assert';
const isValueEmpty = (value: unknown) => !assertNotNull(value) || value === '';
export const isFieldValueEmpty = ({
fieldDefinition,
fieldValue,
}: {
fieldDefinition: Pick<FieldDefinition<FieldMetadata>, 'type'>;
fieldValue: unknown;
}) => {
if (
isFieldUuid(fieldDefinition) ||
isFieldText(fieldDefinition) ||
isFieldDateTime(fieldDefinition) ||
isFieldNumber(fieldDefinition) ||
isFieldRating(fieldDefinition) ||
isFieldEmail(fieldDefinition) ||
isFieldBoolean(fieldDefinition)
//|| isFieldPhone(fieldDefinition)
) {
return isValueEmpty(fieldValue);
}
if (isFieldRelation(fieldDefinition)) {
return isFieldRelationValue(fieldValue) && isValueEmpty(fieldValue);
}
if (isFieldSelect(fieldDefinition)) {
return isFieldSelectValue(fieldValue) && !assertNotNull(fieldValue);
}
if (isFieldCurrency(fieldDefinition)) {
return (
!isFieldCurrencyValue(fieldValue) ||
isValueEmpty(fieldValue?.amountMicros)
);
}
if (isFieldFullName(fieldDefinition)) {
return (
!isFieldFullNameValue(fieldValue) ||
isValueEmpty(fieldValue?.firstName + fieldValue?.lastName)
);
}
if (isFieldLink(fieldDefinition)) {
return !isFieldLinkValue(fieldValue) || isValueEmpty(fieldValue?.url);
}
throw new Error(
`Entity field type not supported in isEntityFieldEditModeEmptyFamilySelector : ${fieldDefinition.type}}`,
);
};

View File

@@ -2,12 +2,12 @@ import { ReactNode } from 'react';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { formatFieldMetadataItemAsColumnDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsColumnDefinition';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import {
FieldContext,
RecordUpdateHook,
RecordUpdateHookParams,
} from '@/object-record/field/contexts/FieldContext';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
} from '@/object-record/record-field/contexts/FieldContext';
import { InlineCellHotkeyScope } from '@/object-record/record-inline-cell/types/InlineCellHotkeyScope';
export const useFieldContext = ({

View File

@@ -1,8 +1,8 @@
import { useEffect } from 'react';
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { useRecordBoardDeprecated } from '@/object-record/record-board-deprecated/hooks/useRecordBoardDeprecated';
import { BoardFieldDefinition } from '@/object-record/record-board-deprecated/types/BoardFieldDefinition';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
type RecordBoardDeprecatedEffectProps = {
recordBoardId: string;

View File

@@ -2,11 +2,11 @@ import { act } from 'react-dom/test-utils';
import { renderHook, waitFor } from '@testing-library/react';
import { RecoilRoot, useRecoilState, useRecoilValue } from 'recoil';
import { FieldType } from '@/object-record/field/types/FieldType';
import { useRecordBoardDeprecatedCardFieldsInternal } from '@/object-record/record-board-deprecated/hooks/internal/useRecordBoardDeprecatedCardFieldsInternal';
import { onFieldsChangeScopedState } from '@/object-record/record-board-deprecated/states/onFieldsChangeScopedState';
import { recordBoardCardFieldsScopedState } from '@/object-record/record-board-deprecated/states/recordBoardDeprecatedCardFieldsScopedState';
import { savedRecordBoardDeprecatedCardFieldsScopedState } from '@/object-record/record-board-deprecated/states/savedRecordBoardDeprecatedCardFieldsScopedState';
import { FieldType } from '@/object-record/record-field/types/FieldType';
const recordBoardScopeId = 'recordBoardScopeId';

View File

@@ -1,12 +1,12 @@
import { useCallback } from 'react';
import { useRecoilCallback, useSetRecoilState } from 'recoil';
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { RecordBoardDeprecatedScopeInternalContext } from '@/object-record/record-board-deprecated/scopes/scope-internal-context/RecordBoardDeprecatedScopeInternalContext';
import { onFieldsChangeScopedState } from '@/object-record/record-board-deprecated/states/onFieldsChangeScopedState';
import { recordBoardCardFieldsScopedState } from '@/object-record/record-board-deprecated/states/recordBoardDeprecatedCardFieldsScopedState';
import { savedRecordBoardDeprecatedCardFieldsScopedState } from '@/object-record/record-board-deprecated/states/savedRecordBoardDeprecatedCardFieldsScopedState';
import { BoardFieldDefinition } from '@/object-record/record-board-deprecated/types/BoardFieldDefinition';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';

View File

@@ -1,4 +1,4 @@
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
import { BoardFieldDefinition } from '../types/BoardFieldDefinition';

View File

@@ -1,5 +1,5 @@
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { BoardFieldDefinition } from '@/object-record/record-board-deprecated/types/BoardFieldDefinition';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
export const onFieldsChangeScopedState = createStateScopeMap<

View File

@@ -1,4 +1,4 @@
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
import { BoardFieldDefinition } from '../types/BoardFieldDefinition';

View File

@@ -1,4 +1,4 @@
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
import { BoardFieldDefinition } from '../types/BoardFieldDefinition';

View File

@@ -1,10 +1,10 @@
import { createSelectorScopeMap } from '@/ui/utilities/recoil-scope/utils/createSelectorScopeMap';
import { createSelectorReadOnlyScopeMap } from '@/ui/utilities/recoil-scope/utils/createSelectorReadOnlyScopeMap';
import { availableRecordBoardDeprecatedCardFieldsScopedState } from '../availableRecordBoardDeprecatedCardFieldsScopedState';
import { recordBoardCardFieldsScopedState } from '../recordBoardDeprecatedCardFieldsScopedState';
export const hiddenRecordBoardDeprecatedCardFieldsScopedSelector =
createSelectorScopeMap({
createSelectorReadOnlyScopeMap({
key: 'hiddenRecordBoardDeprecatedCardFieldsScopedSelector',
get:
({ scopeId }) =>

View File

@@ -1,6 +1,6 @@
import { selectorFamily } from 'recoil';
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { BoardFieldDefinition } from '../../types/BoardFieldDefinition';
import { recordBoardCardFieldsScopedState } from '../recordBoardDeprecatedCardFieldsScopedState';

View File

@@ -1,11 +1,11 @@
import { createSelectorScopeMap } from '@/ui/utilities/recoil-scope/utils/createSelectorScopeMap';
import { createSelectorReadOnlyScopeMap } from '@/ui/utilities/recoil-scope/utils/createSelectorReadOnlyScopeMap';
import { isRecordBoardDeprecatedCardSelectedFamilyState } from '../isRecordBoardDeprecatedCardSelectedFamilyState';
import { recordBoardCardIdsByColumnIdFamilyState } from '../recordBoardCardIdsByColumnIdFamilyState';
import { recordBoardColumnsScopedState } from '../recordBoardColumnsScopedState';
export const selectedRecordBoardDeprecatedCardIdsScopedSelector =
createSelectorScopeMap<string[]>({
createSelectorReadOnlyScopeMap<string[]>({
key: 'selectedRecordBoardDeprecatedCardIdsScopedSelector',
get:
({ scopeId }) =>

View File

@@ -1,9 +1,9 @@
import { createSelectorScopeMap } from '@/ui/utilities/recoil-scope/utils/createSelectorScopeMap';
import { createSelectorReadOnlyScopeMap } from '@/ui/utilities/recoil-scope/utils/createSelectorReadOnlyScopeMap';
import { recordBoardCardFieldsScopedState } from '../recordBoardDeprecatedCardFieldsScopedState';
export const visibleRecordBoardDeprecatedCardFieldsScopedSelector =
createSelectorScopeMap({
createSelectorReadOnlyScopeMap({
key: 'visibleRecordBoardDeprecatedCardFieldsScopedSelector',
get:
({ scopeId }) =>

View File

@@ -1,5 +1,5 @@
import { FieldDefinition } from '@/object-record/field/types/FieldDefinition';
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
export type BoardFieldDefinition<T extends FieldMetadata> =
FieldDefinition<T> & {

View File

@@ -41,7 +41,6 @@ export const RecordBoard = ({ recordBoardId }: RecordBoardProps) => {
const boardRef = useRef<HTMLDivElement>(null);
const { getColumnIdsState } = useRecordBoardStates(recordBoardId);
const columnIds = useRecoilValue(getColumnIdsState());
return (

View File

@@ -14,7 +14,7 @@ import { recordBoardVisibleFieldDefinitionsScopedSelector } from '@/object-recor
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
import { getFamilyState } from '@/ui/utilities/recoil-scope/utils/getFamilyState';
import { getScopeIdOrUndefinedFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdOrUndefinedFromComponentId';
import { getSelector } from '@/ui/utilities/recoil-scope/utils/getSelector';
import { getSelectorReadOnly } from '@/ui/utilities/recoil-scope/utils/getSelectorReadOnly';
import { getState } from '@/ui/utilities/recoil-scope/utils/getState';
export const useRecordBoardStates = (recordBoardId?: string) => {
@@ -49,7 +49,7 @@ export const useRecordBoardStates = (recordBoardId?: string) => {
recordBoardFieldDefinitionsStateScopeMap,
scopeId,
),
getVisibleFieldDefinitionsState: getSelector(
getVisibleFieldDefinitionsState: getSelectorReadOnly(
recordBoardVisibleFieldDefinitionsScopedSelector,
scopeId,
),

View File

@@ -2,6 +2,7 @@ import { useRecoilCallback } from 'recoil';
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
export const useSetRecordBoardRecordIds = (recordBoardId?: string) => {
const {
@@ -21,13 +22,20 @@ export const useSetRecordBoardRecordIds = (recordBoardId?: string) => {
.getLoadable(columnsFamilySelector(columnId))
.getValue();
const existingColumnRecordIds = snapshot
.getLoadable(recordBoardRecordIdsByColumnIdFamilyState(columnId))
.getValue();
const columnRecordIds = records
.filter((record) => record.stage === column?.value)
.map((record) => record.id);
if (!isDeeplyEqual(existingColumnRecordIds, columnRecordIds)) {
set(
recordBoardRecordIdsByColumnIdFamilyState(columnId),
columnRecordIds,
);
}
});
},
[

View File

@@ -3,9 +3,9 @@ import styled from '@emotion/styled';
import { useRecoilState, useRecoilValue } from 'recoil';
import { RecordChip } from '@/object-record/components/RecordChip';
import { FieldContext } from '@/object-record/field/contexts/FieldContext';
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
import { RecordBoardCardContext } from '@/object-record/record-board/record-board-card/contexts/RecordBoardCardContext';
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell';
import { InlineCellHotkeyScope } from '@/object-record/record-inline-cell/types/InlineCellHotkeyScope';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
@@ -205,6 +205,7 @@ export const RecordBoardCard = () => {
recoilScopeId: recordId + fieldDefinition.fieldMetadataId,
isLabelIdentifier: false,
fieldDefinition: {
disableTooltip: true,
fieldMetadataId: fieldDefinition.fieldMetadataId,
label: fieldDefinition.label,
iconName: fieldDefinition.iconName,

View File

@@ -1,9 +1,9 @@
import { ReactNode } from 'react';
import { FieldDefinition } from '@/object-record/field/types/FieldDefinition';
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { RecordBoardScopeInternalContext } from '@/object-record/record-board/scopes/scope-internal-context/RecordBoardScopeInternalContext';
import { RecordBoardColumnDefinition } from '@/object-record/record-board/types/RecordBoardColumnDefinition';
import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
type RecordBoardScopeProps = {
children: ReactNode;

View File

@@ -1,13 +1,13 @@
import { FieldDefinition } from '@/object-record/field/types/FieldDefinition';
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { RecordBoardColumnDefinition } from '@/object-record/record-board/types/RecordBoardColumnDefinition';
import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { StateScopeMapKey } from '@/ui/utilities/recoil-scope/scopes-internal/types/StateScopeMapKey';
import { createScopeInternalContext } from '@/ui/utilities/recoil-scope/scopes-internal/utils/createScopeInternalContext';
type RecordBoardDeprecatedScopeInternalContextProps = StateScopeMapKey & {
type RecordBoardScopeInternalContextProps = StateScopeMapKey & {
onFieldsChange: (fields: FieldDefinition<FieldMetadata>[]) => void;
onColumnsChange: (column: RecordBoardColumnDefinition[]) => void;
};
export const RecordBoardScopeInternalContext =
createScopeInternalContext<RecordBoardDeprecatedScopeInternalContextProps>();
createScopeInternalContext<RecordBoardScopeInternalContextProps>();

View File

@@ -1,5 +1,5 @@
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { RecordBoardFieldDefinition } from '@/object-record/record-board/types/RecordBoardFieldDefinition';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
export const recordBoardFieldDefinitionsStateScopeMap = createStateScopeMap<

View File

@@ -1,8 +1,8 @@
import { recordBoardFieldDefinitionsStateScopeMap } from '@/object-record/record-board/states/recordBoardFieldDefinitionsStateScopeMap';
import { createSelectorScopeMap } from '@/ui/utilities/recoil-scope/utils/createSelectorScopeMap';
import { createSelectorReadOnlyScopeMap } from '@/ui/utilities/recoil-scope/utils/createSelectorReadOnlyScopeMap';
export const recordBoardVisibleFieldDefinitionsScopedSelector =
createSelectorScopeMap({
createSelectorReadOnlyScopeMap({
key: 'recordBoardVisibleFieldDefinitionsScopedSelector',
get:
({ scopeId }) =>

View File

@@ -1,5 +1,5 @@
import { FieldDefinition } from '@/object-record/field/types/FieldDefinition';
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
export type RecordBoardFieldDefinition<T extends FieldMetadata> =
FieldDefinition<T> & {

View File

@@ -1,4 +1,4 @@
import { FieldDefinition } from '@/object-record/field/types/FieldDefinition';
import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition';
import {
FieldBooleanMetadata,
FieldFullNameMetadata,
@@ -8,7 +8,7 @@ import {
FieldRelationMetadata,
FieldSelectMetadata,
FieldTextMetadata,
} from '@/object-record/field/types/FieldMetadata';
} from '@/object-record/record-field/types/FieldMetadata';
export const fieldMetadataId = 'fieldMetadataId';

View File

@@ -1,10 +1,11 @@
import { useContext } from 'react';
import { FullNameFieldInput } from '@/object-record/field/meta-types/input/components/FullNameFieldInput';
import { SelectFieldInput } from '@/object-record/field/meta-types/input/components/SelectFieldInput';
import { isFieldFullName } from '@/object-record/field/types/guards/isFieldFullName';
import { isFieldSelect } from '@/object-record/field/types/guards/isFieldSelect';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { FullNameFieldInput } from '@/object-record/record-field/meta-types/input/components/FullNameFieldInput';
import { SelectFieldInput } from '@/object-record/record-field/meta-types/input/components/SelectFieldInput';
import { RecordFieldInputScope } from '@/object-record/record-field/scopes/RecordFieldInputScope';
import { isFieldFullName } from '@/object-record/record-field/types/guards/isFieldFullName';
import { isFieldSelect } from '@/object-record/record-field/types/guards/isFieldSelect';
import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId';
import { FieldContext } from '../contexts/FieldContext';
import { BooleanFieldInput } from '../meta-types/input/components/BooleanFieldInput';
@@ -30,6 +31,7 @@ import { isFieldRelation } from '../types/guards/isFieldRelation';
import { isFieldText } from '../types/guards/isFieldText';
type FieldInputProps = {
recordFieldInputdId: string;
onSubmit?: FieldInputEvent;
onCancel?: () => void;
onClickOutside?: FieldInputEvent;
@@ -40,6 +42,7 @@ type FieldInputProps = {
};
export const FieldInput = ({
recordFieldInputdId,
onCancel,
onSubmit,
onEnter,
@@ -51,11 +54,11 @@ export const FieldInput = ({
const { fieldDefinition } = useContext(FieldContext);
return (
<>
<RecordFieldInputScope
recordFieldInputScopeId={getScopeIdFromComponentId(recordFieldInputdId)}
>
{isFieldRelation(fieldDefinition) ? (
<RecoilScope>
<RelationFieldInput onSubmit={onSubmit} onCancel={onCancel} />
</RecoilScope>
) : isFieldPhone(fieldDefinition) ? (
<PhoneFieldInput
onEnter={onEnter}
@@ -127,6 +130,6 @@ export const FieldInput = ({
) : (
<></>
)}
</>
</RecordFieldInputScope>
);
};

View File

@@ -5,11 +5,11 @@ import { RecoilRoot } from 'recoil';
import {
phoneFieldDefinition,
relationFieldDefinition,
} from '@/object-record/field/__mocks__/fieldDefinitions';
import { FieldContext } from '@/object-record/field/contexts/FieldContext';
import { useGetButtonIcon } from '@/object-record/field/hooks/useGetButtonIcon';
import { FieldDefinition } from '@/object-record/field/types/FieldDefinition';
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
} from '@/object-record/record-field/__mocks__/fieldDefinitions';
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
import { useGetButtonIcon } from '@/object-record/record-field/hooks/useGetButtonIcon';
import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { IconPencil } from '@/ui/display/icon';
const entityId = 'entityId';

View File

@@ -2,9 +2,9 @@ import { ReactNode } from 'react';
import { act, renderHook } from '@testing-library/react';
import { RecoilRoot, useSetRecoilState } from 'recoil';
import { phoneFieldDefinition } from '@/object-record/field/__mocks__/fieldDefinitions';
import { FieldContext } from '@/object-record/field/contexts/FieldContext';
import { useIsFieldEmpty } from '@/object-record/field/hooks/useIsFieldEmpty';
import { phoneFieldDefinition } from '@/object-record/record-field/__mocks__/fieldDefinitions';
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
import { useIsFieldEmpty } from '@/object-record/record-field/hooks/useIsFieldEmpty';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
const entityId = 'entityId';

View File

@@ -5,11 +5,11 @@ import { RecoilRoot } from 'recoil';
import {
phoneFieldDefinition,
ratingfieldDefinition,
} from '@/object-record/field/__mocks__/fieldDefinitions';
import { FieldContext } from '@/object-record/field/contexts/FieldContext';
import { useIsFieldInputOnly } from '@/object-record/field/hooks/useIsFieldInputOnly';
import { FieldDefinition } from '@/object-record/field/types/FieldDefinition';
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
} from '@/object-record/record-field/__mocks__/fieldDefinitions';
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
import { useIsFieldInputOnly } from '@/object-record/record-field/hooks/useIsFieldInputOnly';
import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
const entityId = 'entityId';

View File

@@ -5,19 +5,19 @@ import { act, renderHook, waitFor } from '@testing-library/react';
import { RecoilRoot, useRecoilValue } from 'recoil';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import {
phoneFieldDefinition,
relationFieldDefinition,
} from '@/object-record/field/__mocks__/fieldDefinitions';
} from '@/object-record/record-field/__mocks__/fieldDefinitions';
import {
FieldContext,
RecordUpdateHook,
RecordUpdateHookParams,
} from '@/object-record/field/contexts/FieldContext';
import { usePersistField } from '@/object-record/field/hooks/usePersistField';
import { FieldDefinition } from '@/object-record/field/types/FieldDefinition';
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
} from '@/object-record/record-field/contexts/FieldContext';
import { usePersistField } from '@/object-record/record-field/hooks/usePersistField';
import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition';
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
jest.mock('@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery', () => ({

View File

@@ -5,14 +5,14 @@ import { act, renderHook, waitFor } from '@testing-library/react';
import { RecoilRoot } from 'recoil';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { booleanFieldDefinition } from '@/object-record/field/__mocks__/fieldDefinitions';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import { booleanFieldDefinition } from '@/object-record/record-field/__mocks__/fieldDefinitions';
import {
FieldContext,
RecordUpdateHook,
RecordUpdateHookParams,
} from '@/object-record/field/contexts/FieldContext';
import { useToggleEditOnlyInput } from '@/object-record/field/hooks/useToggleEditOnlyInput';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
} from '@/object-record/record-field/contexts/FieldContext';
import { useToggleEditOnlyInput } from '@/object-record/record-field/hooks/useToggleEditOnlyInput';
jest.mock('@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery', () => ({
useMapFieldMetadataToGraphQLQuery: () => () => '\n',

View File

@@ -0,0 +1,22 @@
import { RecordFieldInputScopeInternalContext } from '@/object-record/record-field/scopes/scope-internal-context/RecordFieldInputScopeInternalContext';
import { recordFieldInputDraftValueSelectorScopeMap } from '@/object-record/record-field/states/selectors/recordFieldInputDraftValueSelectorScopeMap';
import { FieldInputDraftValue } from '@/object-record/record-field/types/FieldInputDraftValue';
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
import { getScopeIdOrUndefinedFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdOrUndefinedFromComponentId';
import { getSelector } from '@/ui/utilities/recoil-scope/utils/getSelector';
export const useRecordFieldInputStates = <FieldValue>(
recordFieldInputId?: string,
) => {
const scopeId = useAvailableScopeIdOrThrow(
RecordFieldInputScopeInternalContext,
getScopeIdOrUndefinedFromComponentId(recordFieldInputId),
);
return {
scopeId,
getDraftValueSelector: getSelector<
FieldInputDraftValue<FieldValue> | undefined
>(recordFieldInputDraftValueSelectorScopeMap, scopeId),
};
};

View File

@@ -1,6 +1,6 @@
import { useContext } from 'react';
import { isFieldRelation } from '@/object-record/field/types/guards/isFieldRelation';
import { isFieldRelation } from '@/object-record/record-field/types/guards/isFieldRelation';
import { IconPencil } from '@/ui/display/icon';
import { IconComponent } from '@/ui/display/icon/types/IconComponent';

View File

@@ -1,7 +1,7 @@
import { useContext } from 'react';
import { useRecoilValue } from 'recoil';
import { isFieldValueEmpty } from '@/object-record/field/utils/isFieldValueEmpty';
import { isFieldValueEmpty } from '@/object-record/record-field/utils/isFieldValueEmpty';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldContext } from '../contexts/FieldContext';

View File

@@ -1,10 +1,10 @@
import { useContext } from 'react';
import { useRecoilCallback } from 'recoil';
import { isFieldFullName } from '@/object-record/field/types/guards/isFieldFullName';
import { isFieldFullNameValue } from '@/object-record/field/types/guards/isFieldFullNameValue';
import { isFieldSelect } from '@/object-record/field/types/guards/isFieldSelect';
import { isFieldSelectValue } from '@/object-record/field/types/guards/isFieldSelectValue';
import { isFieldFullName } from '@/object-record/record-field/types/guards/isFieldFullName';
import { isFieldFullNameValue } from '@/object-record/record-field/types/guards/isFieldFullNameValue';
import { isFieldSelect } from '@/object-record/record-field/types/guards/isFieldSelect';
import { isFieldSelectValue } from '@/object-record/record-field/types/guards/isFieldSelectValue';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldContext } from '../contexts/FieldContext';

View File

@@ -0,0 +1,73 @@
import { useContext } from 'react';
import { isUndefined } from '@sniptt/guards';
import { useRecoilCallback, useSetRecoilState } from 'recoil';
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
import { useRecordFieldInputStates } from '@/object-record/record-field/hooks/internal/useRecordFieldInputStates';
import { FieldInputDraftValue } from '@/object-record/record-field/types/FieldInputDraftValue';
import { computeDraftValueFromFieldValue } from '@/object-record/record-field/utils/computeDraftValueFromFieldValue';
import { computeDraftValueFromString } from '@/object-record/record-field/utils/computeDraftValueFromString';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
export const useRecordFieldInput = <FieldValue>(
recordFieldInputId?: string,
) => {
const { scopeId, getDraftValueSelector } =
useRecordFieldInputStates<FieldValue>(recordFieldInputId);
const { entityId, fieldDefinition } = useContext(FieldContext);
const setDraftValue = useSetRecoilState(getDraftValueSelector());
const initDraftValue = useRecoilCallback(
({ set, snapshot }) =>
(value?: string) => {
const recordFieldValue = snapshot
.getLoadable(
recordStoreFamilySelector<FieldValue>({
recordId: entityId,
fieldName: fieldDefinition.metadata.fieldName,
}),
)
.getValue();
if (isUndefined(value)) {
set(
getDraftValueSelector(),
computeDraftValueFromFieldValue<FieldValue>({
fieldValue: recordFieldValue,
fieldDefinition,
}),
);
} else {
set(
getDraftValueSelector(),
computeDraftValueFromString<FieldValue>({ value, fieldDefinition }),
);
}
},
[entityId, fieldDefinition, getDraftValueSelector],
);
const isDraftValueEmpty = (
value: FieldInputDraftValue<FieldValue> | undefined,
) => {
if (value === null || value === undefined) {
return true;
}
if (typeof value === 'string' && value === '') {
return true;
}
return false;
};
return {
scopeId,
setDraftValue,
getDraftValueSelector,
initDraftValue,
isDraftValueEmpty,
};
};

View File

@@ -1,7 +1,7 @@
import {
FieldContext,
GenericFieldContextType,
} from '@/object-record/field/contexts/FieldContext';
} from '@/object-record/record-field/contexts/FieldContext';
type FieldContextProviderProps = {
children: React.ReactNode;

View File

@@ -1,5 +1,5 @@
import { RecordChip } from '@/object-record/components/RecordChip';
import { useChipField } from '@/object-record/field/meta-types/hooks/useChipField';
import { useChipField } from '@/object-record/record-field/meta-types/hooks/useChipField';
export const ChipFieldDisplay = () => {
const { objectNameSingular, record } = useChipField();

View File

@@ -3,7 +3,13 @@ import { CurrencyDisplay } from '@/ui/field/display/components/CurrencyDisplay';
import { useCurrencyField } from '../../hooks/useCurrencyField';
export const CurrencyFieldDisplay = () => {
const { initialAmount } = useCurrencyField();
const { fieldValue } = useCurrencyField();
return <CurrencyDisplay amount={initialAmount} />;
return (
<CurrencyDisplay
amount={
fieldValue.amountMicros ? fieldValue.amountMicros / 1000000 : null
}
/>
);
};

View File

@@ -1,4 +1,4 @@
import { useFullNameField } from '@/object-record/field/meta-types/hooks/useFullNameField';
import { useFullNameField } from '@/object-record/record-field/meta-types/hooks/useFullNameField';
import { TextDisplay } from '@/ui/field/display/components/TextDisplay';
export const FullNameFieldDisplay = () => {

View File

@@ -1,4 +1,4 @@
import { useUuidField } from '@/object-record/field/meta-types/hooks/useUuidField';
import { useUuidField } from '@/object-record/record-field/meta-types/hooks/useUuidField';
import { TextDisplay } from '@/ui/field/display/components/TextDisplay';
export const UuidFieldDisplay = () => {

View File

@@ -3,7 +3,7 @@ import { MemoryRouter } from 'react-router-dom';
import { Meta, StoryObj } from '@storybook/react';
import { useSetRecoilState } from 'recoil';
import { ChipFieldDisplay } from '@/object-record/field/meta-types/display/components/ChipFieldDisplay';
import { ChipFieldDisplay } from '@/object-record/record-field/meta-types/display/components/ChipFieldDisplay';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';

View File

@@ -1,9 +1,9 @@
import { useContext } from 'react';
import { useRecoilValue } from 'recoil';
import { isFieldFullName } from '@/object-record/field/types/guards/isFieldFullName';
import { isFieldNumber } from '@/object-record/field/types/guards/isFieldNumber';
import { isFieldText } from '@/object-record/field/types/guards/isFieldText';
import { isFieldFullName } from '@/object-record/record-field/types/guards/isFieldFullName';
import { isFieldNumber } from '@/object-record/record-field/types/guards/isFieldNumber';
import { isFieldText } from '@/object-record/record-field/types/guards/isFieldText';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { FieldContext } from '../../contexts/FieldContext';

View File

@@ -1,47 +1,18 @@
import { useContext } from 'react';
import { useRecoilState } from 'recoil';
import { useRecoilState, useRecoilValue } from 'recoil';
import { CurrencyCode } from '@/object-record/field/types/CurrencyCode';
import { FieldInitialValue } from '@/object-record/field/types/FieldInitialValue';
import { useRecordFieldInput } from '@/object-record/record-field/hooks/useRecordFieldInput';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { canBeCastAsIntegerOrNull } from '~/utils/cast-as-integer-or-null';
import {
convertCurrencyMicrosToCurrency,
convertCurrencyToCurrencyMicros,
} from '~/utils/convert-currency-amount';
import { convertCurrencyToCurrencyMicros } from '~/utils/convert-currency-amount';
import { FieldContext } from '../../contexts/FieldContext';
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
import { usePersistField } from '../../hooks/usePersistField';
import { FieldCurrencyValue } from '../../types/FieldMetadata';
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
import { isFieldCurrency } from '../../types/guards/isFieldCurrency';
import { isFieldCurrencyValue } from '../../types/guards/isFieldCurrencyValue';
const initializeValue = (
fieldInitialValue: FieldInitialValue | undefined,
fieldValue: FieldCurrencyValue,
) => {
if (fieldInitialValue?.isEmpty) {
return { amount: null, currencyCode: CurrencyCode.USD };
}
if (!isNaN(Number(fieldInitialValue?.value))) {
return {
amount: Number(fieldInitialValue?.value),
currencyCode: CurrencyCode.USD,
};
}
if (!fieldValue) {
return { amount: null, currencyCode: CurrencyCode.USD };
}
return {
amount: convertCurrencyMicrosToCurrency(fieldValue.amountMicros),
currencyCode: CurrencyCode.USD,
};
};
export const useCurrencyField = () => {
const { entityId, fieldDefinition, hotkeyScope } = useContext(FieldContext);
@@ -83,18 +54,16 @@ export const useCurrencyField = () => {
persistField(newCurrencyValue);
};
const fieldInitialValue = useFieldInitialValue();
const { setDraftValue, getDraftValueSelector } =
useRecordFieldInput<FieldCurrencyValue>(`${entityId}-${fieldName}`);
const initialValue = initializeValue(fieldInitialValue, fieldValue);
const initialAmount = initialValue.amount;
const initialCurrencyCode = initialValue.currencyCode;
const draftValue = useRecoilValue(getDraftValueSelector());
return {
fieldDefinition,
fieldValue,
initialAmount,
initialCurrencyCode,
draftValue,
setDraftValue,
setFieldValue,
hotkeyScope,
persistCurrencyField,

View File

@@ -1,6 +1,8 @@
import { useContext } from 'react';
import { useRecoilState } from 'recoil';
import { useRecordFieldInput } from '@/object-record/record-field/hooks/useRecordFieldInput';
import { FieldDateTimeValue } from '@/object-record/record-field/types/FieldMetadata';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldContext } from '../../contexts/FieldContext';
@@ -22,9 +24,14 @@ export const useDateTimeField = () => {
}),
);
const { setDraftValue } = useRecordFieldInput<FieldDateTimeValue>(
`${entityId}-${fieldName}`,
);
return {
fieldDefinition,
fieldValue,
setDraftValue,
setFieldValue,
hotkeyScope,
clearable,

View File

@@ -1,10 +1,11 @@
import { useContext } from 'react';
import { useRecoilState } from 'recoil';
import { useRecoilState, useRecoilValue } from 'recoil';
import { useRecordFieldInput } from '@/object-record/record-field/hooks/useRecordFieldInput';
import { FieldEmailValue } from '@/object-record/record-field/types/FieldMetadata';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldContext } from '../../contexts/FieldContext';
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
import { isFieldEmail } from '../../types/guards/isFieldEmail';
@@ -22,16 +23,16 @@ export const useEmailField = () => {
}),
);
const fieldInitialValue = useFieldInitialValue();
const { setDraftValue, getDraftValueSelector } =
useRecordFieldInput<FieldEmailValue>(`${entityId}-${fieldName}`);
const initialValue = fieldInitialValue?.isEmpty
? ''
: fieldInitialValue?.value ?? fieldValue;
const draftValue = useRecoilValue(getDraftValueSelector());
return {
fieldDefinition,
draftValue,
setDraftValue,
fieldValue,
initialValue,
setFieldValue,
hotkeyScope,
};

View File

@@ -1,10 +1,10 @@
import { useContext } from 'react';
import { useRecoilState } from 'recoil';
import { useRecoilState, useRecoilValue } from 'recoil';
import { useRecordFieldInput } from '@/object-record/record-field/hooks/useRecordFieldInput';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldContext } from '../../contexts/FieldContext';
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
import { usePersistField } from '../../hooks/usePersistField';
import { FieldFullNameValue } from '../../types/FieldMetadata';
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
@@ -35,17 +35,17 @@ export const useFullNameField = () => {
persistField(newValue);
};
const fieldInitialValue = useFieldInitialValue();
const { setDraftValue, getDraftValueSelector } =
useRecordFieldInput<FieldFullNameValue>(`${entityId}-${fieldName}`);
const initialValue: FieldFullNameValue = fieldInitialValue?.isEmpty
? { firstName: '', lastName: '' }
: fieldValue;
const draftValue = useRecoilValue(getDraftValueSelector());
return {
fieldDefinition,
fieldValue,
initialValue,
setFieldValue,
draftValue,
setDraftValue,
hotkeyScope,
persistFullNameField,
};

View File

@@ -1,10 +1,10 @@
import { useContext } from 'react';
import { useRecoilState } from 'recoil';
import { useRecoilState, useRecoilValue } from 'recoil';
import { useRecordFieldInput } from '@/object-record/record-field/hooks/useRecordFieldInput';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldContext } from '../../contexts/FieldContext';
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
import { usePersistField } from '../../hooks/usePersistField';
import { FieldLinkValue } from '../../types/FieldMetadata';
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
@@ -25,13 +25,10 @@ export const useLinkField = () => {
}),
);
const fieldInitialValue = useFieldInitialValue();
const { setDraftValue, getDraftValueSelector } =
useRecordFieldInput<FieldLinkValue>(`${entityId}-${fieldName}`);
const initialValue: FieldLinkValue = fieldInitialValue?.isEmpty
? { url: '', label: '' }
: fieldInitialValue?.value
? { url: fieldInitialValue.value, label: '' }
: fieldValue;
const draftValue = useRecoilValue(getDraftValueSelector());
const persistField = usePersistField();
@@ -46,7 +43,8 @@ export const useLinkField = () => {
return {
fieldDefinition,
fieldValue,
initialValue,
draftValue,
setDraftValue,
setFieldValue,
hotkeyScope,
persistLinkField,

View File

@@ -1,6 +1,8 @@
import { useContext } from 'react';
import { useRecoilState } from 'recoil';
import { useRecoilState, useRecoilValue } from 'recoil';
import { useRecordFieldInput } from '@/object-record/record-field/hooks/useRecordFieldInput';
import { FieldNumberValue } from '@/object-record/record-field/types/FieldMetadata';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import {
canBeCastAsIntegerOrNull,
@@ -8,7 +10,6 @@ import {
} from '~/utils/cast-as-integer-or-null';
import { FieldContext } from '../../contexts/FieldContext';
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
import { usePersistField } from '../../hooks/usePersistField';
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
import { isFieldNumber } from '../../types/guards/isFieldNumber';
@@ -39,18 +40,16 @@ export const useNumberField = () => {
persistField(castedValue);
};
const fieldInitialValue = useFieldInitialValue();
const { setDraftValue, getDraftValueSelector } =
useRecordFieldInput<FieldNumberValue>(`${entityId}-${fieldName}`);
const initialValue = fieldInitialValue?.isEmpty
? null
: !isNaN(Number(fieldInitialValue?.value))
? Number(fieldInitialValue?.value)
: null ?? fieldValue;
const draftValue = useRecoilValue(getDraftValueSelector());
return {
fieldDefinition,
fieldValue,
initialValue,
draftValue,
setDraftValue,
setFieldValue,
hotkeyScope,
persistNumberField,

View File

@@ -1,11 +1,12 @@
import { useContext } from 'react';
import { isPossiblePhoneNumber } from 'libphonenumber-js';
import { useRecoilState } from 'recoil';
import { useRecoilState, useRecoilValue } from 'recoil';
import { useRecordFieldInput } from '@/object-record/record-field/hooks/useRecordFieldInput';
import { FieldPhoneValue } from '@/object-record/record-field/types/FieldMetadata';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldContext } from '../../contexts/FieldContext';
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
import { usePersistField } from '../../hooks/usePersistField';
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
import { isFieldPhone } from '../../types/guards/isFieldPhone';
@@ -13,7 +14,6 @@ import { isFieldPhone } from '../../types/guards/isFieldPhone';
export const usePhoneField = () => {
const { entityId, fieldDefinition, hotkeyScope } = useContext(FieldContext);
//assertFieldMetadata('PHONE', isFieldPhone, fieldDefinition);
assertFieldMetadata('TEXT', isFieldPhone, fieldDefinition);
const fieldName = fieldDefinition.metadata.fieldName;
@@ -32,18 +32,17 @@ export const usePhoneField = () => {
persistField(newPhoneValue);
};
const { setDraftValue, getDraftValueSelector } =
useRecordFieldInput<FieldPhoneValue>(`${entityId}-${fieldName}`);
const fieldInitialValue = useFieldInitialValue();
const initialValue = fieldInitialValue?.isEmpty
? ''
: fieldInitialValue?.value ?? fieldValue;
const draftValue = useRecoilValue(getDraftValueSelector());
return {
fieldDefinition,
fieldValue,
initialValue,
setFieldValue,
draftValue,
setDraftValue,
hotkeyScope,
persistPhoneField,
};

View File

@@ -1,11 +1,12 @@
import { useContext } from 'react';
import { useRecoilState } from 'recoil';
import { useRecoilState, useRecoilValue } from 'recoil';
import { useGetButtonIcon } from '@/object-record/field/hooks/useGetButtonIcon';
import { useGetButtonIcon } from '@/object-record/record-field/hooks/useGetButtonIcon';
import { useRecordFieldInput } from '@/object-record/record-field/hooks/useRecordFieldInput';
import { FieldRelationValue } from '@/object-record/record-field/types/FieldMetadata';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldContext } from '../../contexts/FieldContext';
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
import { isFieldRelation } from '../../types/guards/isFieldRelation';
@@ -17,22 +18,20 @@ export const useRelationField = () => {
const fieldName = fieldDefinition.metadata.fieldName;
const [fieldValue, setFieldValue] = useRecoilState<any | null>(
const [fieldValue, setFieldValue] = useRecoilState<FieldRelationValue>(
recordStoreFamilySelector({ recordId: entityId, fieldName }),
);
const fieldInitialValue = useFieldInitialValue();
const { getDraftValueSelector } = useRecordFieldInput<FieldRelationValue>(
`${entityId}-${fieldName}`,
);
const draftValue = useRecoilValue(getDraftValueSelector());
const initialSearchValue = fieldInitialValue?.isEmpty
? null
: fieldInitialValue?.value;
const initialValue = fieldInitialValue?.isEmpty ? null : fieldValue;
const initialSearchValue = draftValue;
return {
fieldDefinition,
fieldValue,
initialValue,
initialSearchValue,
setFieldValue,
maxWidth: button && maxWidth ? maxWidth - 28 : maxWidth,

View File

@@ -1,12 +1,12 @@
import { useContext } from 'react';
import { useRecoilState } from 'recoil';
import { useRecoilState, useRecoilValue } from 'recoil';
import { usePersistField } from '@/object-record/field/hooks/usePersistField';
import { usePersistField } from '@/object-record/record-field/hooks/usePersistField';
import { useRecordFieldInput } from '@/object-record/record-field/hooks/useRecordFieldInput';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldMetadataType } from '~/generated/graphql';
import { FieldContext } from '../../contexts/FieldContext';
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
import { FieldSelectValue } from '../../types/FieldMetadata';
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
import { isFieldSelect } from '../../types/guards/isFieldSelect';
@@ -27,16 +27,18 @@ export const useSelectField = () => {
);
const fieldSelectValue = isFieldSelectValue(fieldValue) ? fieldValue : null;
const fieldInitialValue = useFieldInitialValue();
const persistField = usePersistField();
const { setDraftValue, getDraftValueSelector } =
useRecordFieldInput<FieldSelectValue>(`${entityId}-${fieldName}`);
const draftValue = useRecoilValue(getDraftValueSelector());
return {
fieldDefinition,
persistField,
fieldValue: fieldSelectValue,
initialValue: fieldInitialValue,
draftValue,
setDraftValue,
setFieldValue,
hotkeyScope,
};

View File

@@ -1,10 +1,11 @@
import { useContext } from 'react';
import { useRecoilState } from 'recoil';
import { useRecoilState, useRecoilValue } from 'recoil';
import { useRecordFieldInput } from '@/object-record/record-field/hooks/useRecordFieldInput';
import { FieldTextValue } from '@/object-record/record-field/types/FieldMetadata';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldContext } from '../../contexts/FieldContext';
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
import { isFieldText } from '../../types/guards/isFieldText';
import { isFieldTextValue } from '../../types/guards/isFieldTextValue';
@@ -17,7 +18,7 @@ export const useTextField = () => {
const fieldName = fieldDefinition.metadata.fieldName;
const [fieldValue, setFieldValue] = useRecoilState<string>(
const [fieldValue, setFieldValue] = useRecoilState<FieldTextValue>(
recordStoreFamilySelector({
recordId: entityId,
fieldName: fieldName,
@@ -25,17 +26,17 @@ export const useTextField = () => {
);
const fieldTextValue = isFieldTextValue(fieldValue) ? fieldValue : '';
const fieldInitialValue = useFieldInitialValue();
const { setDraftValue, getDraftValueSelector } =
useRecordFieldInput<FieldTextValue>(`${entityId}-${fieldName}`);
const initialValue = fieldInitialValue?.isEmpty
? ''
: fieldInitialValue?.value ?? fieldTextValue;
const draftValue = useRecoilValue(getDraftValueSelector());
return {
draftValue,
setDraftValue,
maxWidth,
fieldDefinition,
fieldValue: fieldTextValue,
initialValue,
setFieldValue,
hotkeyScope,
};

View File

@@ -1,11 +1,11 @@
import { useContext } from 'react';
import { useRecoilState } from 'recoil';
import { isFieldUuid } from '@/object-record/field/types/guards/isFieldUuid';
import { FieldUUidValue } from '@/object-record/record-field/types/FieldMetadata';
import { isFieldUuid } from '@/object-record/record-field/types/guards/isFieldUuid';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldContext } from '../../contexts/FieldContext';
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
import { isFieldTextValue } from '../../types/guards/isFieldTextValue';
@@ -16,7 +16,7 @@ export const useUuidField = () => {
const fieldName = fieldDefinition.metadata.fieldName;
const [fieldValue, setFieldValue] = useRecoilState<string>(
const [fieldValue, setFieldValue] = useRecoilState<FieldUUidValue>(
recordStoreFamilySelector({
recordId: entityId,
fieldName: fieldName,
@@ -24,16 +24,9 @@ export const useUuidField = () => {
);
const fieldTextValue = isFieldTextValue(fieldValue) ? fieldValue : '';
const fieldInitialValue = useFieldInitialValue();
const initialValue = fieldInitialValue?.isEmpty
? ''
: fieldInitialValue?.value ?? fieldTextValue;
return {
fieldDefinition,
fieldValue: fieldTextValue,
initialValue,
setFieldValue,
hotkeyScope,
};

View File

@@ -1,4 +1,4 @@
import { useSaveFieldEditModeValue } from '@/object-record/field/hooks/useSaveFieldEditModeValue';
import { CurrencyCode } from '@/object-record/record-field/types/CurrencyCode';
import { TextInput } from '@/ui/field/input/components/TextInput';
import { FieldInputOverlay } from '../../../../../ui/field/input/components/FieldInputOverlay';
@@ -21,20 +21,14 @@ export const CurrencyFieldInput = ({
onTab,
onShiftTab,
}: CurrencyFieldInputProps) => {
const {
hotkeyScope,
initialAmount,
initialCurrencyCode,
persistCurrencyField,
} = useCurrencyField();
const saveEditModeValue = useSaveFieldEditModeValue();
const { hotkeyScope, draftValue, persistCurrencyField, setDraftValue } =
useCurrencyField();
const handleEnter = (newValue: string) => {
onEnter?.(() => {
persistCurrencyField({
amountText: newValue,
currencyCode: initialCurrencyCode,
currencyCode: draftValue?.currencyCode ?? CurrencyCode.USD,
});
});
};
@@ -43,7 +37,7 @@ export const CurrencyFieldInput = ({
onEscape?.(() => {
persistCurrencyField({
amountText: newValue,
currencyCode: initialCurrencyCode,
currencyCode: draftValue?.currencyCode ?? CurrencyCode.USD,
});
});
};
@@ -55,7 +49,7 @@ export const CurrencyFieldInput = ({
onClickOutside?.(() => {
persistCurrencyField({
amountText: newValue,
currencyCode: initialCurrencyCode,
currencyCode: draftValue?.currencyCode ?? CurrencyCode.USD,
});
});
};
@@ -64,7 +58,7 @@ export const CurrencyFieldInput = ({
onTab?.(() => {
persistCurrencyField({
amountText: newValue,
currencyCode: initialCurrencyCode,
currencyCode: draftValue?.currencyCode ?? CurrencyCode.USD,
});
});
};
@@ -73,22 +67,22 @@ export const CurrencyFieldInput = ({
onShiftTab?.(() =>
persistCurrencyField({
amountText: newValue,
currencyCode: initialCurrencyCode,
currencyCode: draftValue?.currencyCode ?? CurrencyCode.USD,
}),
);
};
const handleChange = (newValue: string) => {
saveEditModeValue({
amountText: newValue,
currencyCode: initialCurrencyCode,
setDraftValue({
amount: newValue,
currencyCode: draftValue?.currencyCode ?? CurrencyCode.USD,
});
};
return (
<FieldInputOverlay>
<TextInput
value={initialAmount?.toString() ?? ''}
value={draftValue?.amount?.toString() ?? ''}
autoFocus
placeholder="Currency"
onClickOutside={handleClickOutside}

Some files were not shown because too many files have changed in this diff Show More