Display RecordBoardCards on new board (#3657)

* Before remove saveEditModeValue logic

* Fixes

* Fix tests

* Fix tests
This commit is contained in:
Charles Bochet
2024-01-27 15:55:45 +01:00
committed by GitHub
parent 9053769616
commit d6f117c688
64 changed files with 479 additions and 192 deletions

View File

@ -13,7 +13,7 @@ export const useOpenCreateActivityDrawerForSelectedRowIds = (
) => { ) => {
const openCreateActivityDrawer = useOpenCreateActivityDrawer(); const openCreateActivityDrawer = useOpenCreateActivityDrawer();
const { selectedRowIdsSelector } = useRecordTableStates(recordTableId); const { getSelectedRowIdsSelector } = useRecordTableStates(recordTableId);
return useRecoilCallback( return useRecoilCallback(
({ snapshot }) => ({ snapshot }) =>
@ -24,7 +24,7 @@ export const useOpenCreateActivityDrawerForSelectedRowIds = (
) => { ) => {
const selectedRowIds = getSnapshotValue( const selectedRowIds = getSnapshotValue(
snapshot, snapshot,
selectedRowIdsSelector, getSelectedRowIdsSelector(),
); );
let activityTargetableEntityArray: ActivityTargetableObject[] = let activityTargetableEntityArray: ActivityTargetableObject[] =
@ -44,6 +44,6 @@ export const useOpenCreateActivityDrawerForSelectedRowIds = (
targetableObjects: activityTargetableEntityArray, targetableObjects: activityTargetableEntityArray,
}); });
}, },
[openCreateActivityDrawer, selectedRowIdsSelector], [openCreateActivityDrawer, getSelectedRowIdsSelector],
); );
}; };

View File

@ -1,12 +1,12 @@
import React from 'react'; import React from 'react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { useRecoilState } from 'recoil'; import { useSetRecoilState } from 'recoil';
import { ActivityEditor } from '@/activities/components/ActivityEditor'; import { ActivityEditor } from '@/activities/components/ActivityEditor';
import { Activity } from '@/activities/types/Activity'; import { Activity } from '@/activities/types/Activity';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { entityFieldsFamilyState } from '@/object-record/field/states/entityFieldsFamilyState';
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord'; import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
const StyledContainer = styled.div` const StyledContainer = styled.div`
box-sizing: border-box; box-sizing: border-box;
@ -29,9 +29,7 @@ export const RightDrawerActivity = ({
showComment = true, showComment = true,
autoFillTitle = false, autoFillTitle = false,
}: RightDrawerActivityProps) => { }: RightDrawerActivityProps) => {
const [, setEntityFields] = useRecoilState( const setEntityFields = useSetRecoilState(recordStoreFamilyState(activityId));
entityFieldsFamilyState(activityId),
);
const { record: activity } = useFindOneRecord({ const { record: activity } = useFindOneRecord({
objectNameSingular: CoreObjectNameSingular.Activity, objectNameSingular: CoreObjectNameSingular.Activity,

View File

@ -5,7 +5,7 @@ import { RecoilRoot, useSetRecoilState } from 'recoil';
import { phoneFieldDefinition } from '@/object-record/field/__mocks__/fieldDefinitions'; import { phoneFieldDefinition } from '@/object-record/field/__mocks__/fieldDefinitions';
import { FieldContext } from '@/object-record/field/contexts/FieldContext'; import { FieldContext } from '@/object-record/field/contexts/FieldContext';
import { useIsFieldEmpty } from '@/object-record/field/hooks/useIsFieldEmpty'; import { useIsFieldEmpty } from '@/object-record/field/hooks/useIsFieldEmpty';
import { entityFieldsFamilyState } from '@/object-record/field/states/entityFieldsFamilyState'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
const entityId = 'entityId'; const entityId = 'entityId';
@ -27,7 +27,7 @@ describe('useIsFieldEmpty', () => {
const { result } = renderHook( const { result } = renderHook(
() => { () => {
const setFieldState = useSetRecoilState( const setFieldState = useSetRecoilState(
entityFieldsFamilyState(entityId), recordStoreFamilyState(entityId),
); );
return { return {
setFieldState, setFieldState,

View File

@ -15,10 +15,10 @@ import {
RecordUpdateHookParams, RecordUpdateHookParams,
} from '@/object-record/field/contexts/FieldContext'; } from '@/object-record/field/contexts/FieldContext';
import { usePersistField } from '@/object-record/field/hooks/usePersistField'; import { usePersistField } from '@/object-record/field/hooks/usePersistField';
import { entityFieldsFamilySelector } from '@/object-record/field/states/selectors/entityFieldsFamilySelector';
import { FieldDefinition } from '@/object-record/field/types/FieldDefinition'; import { FieldDefinition } from '@/object-record/field/types/FieldDefinition';
import { FieldMetadata } from '@/object-record/field/types/FieldMetadata'; import { FieldMetadata } from '@/object-record/field/types/FieldMetadata';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
jest.mock('@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery', () => ({ jest.mock('@/object-metadata/hooks/useMapFieldMetadataToGraphQLQuery', () => ({
useMapFieldMetadataToGraphQLQuery: () => () => '\n', useMapFieldMetadataToGraphQLQuery: () => () => '\n',
@ -113,7 +113,7 @@ describe('usePersistField', () => {
const { result } = renderHook( const { result } = renderHook(
() => { () => {
const entityFields = useRecoilValue( const entityFields = useRecoilValue(
entityFieldsFamilySelector({ entityId, fieldName }), recordStoreFamilySelector({ recordId: entityId, fieldName }),
); );
return { return {
@ -137,7 +137,7 @@ describe('usePersistField', () => {
const { result } = renderHook( const { result } = renderHook(
() => { () => {
const entityFields = useRecoilValue( const entityFields = useRecoilValue(
entityFieldsFamilySelector({ entityId, fieldName }), recordStoreFamilySelector({ recordId: entityId, fieldName }),
); );
return { return {

View File

@ -1,21 +1,22 @@
import { useContext } from 'react'; import { useContext } from 'react';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { isFieldValueEmpty } from '@/object-record/field/utils/isFieldValueEmpty';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldContext } from '../contexts/FieldContext'; import { FieldContext } from '../contexts/FieldContext';
import { isEntityFieldEmptyFamilySelector } from '../states/selectors/isEntityFieldEmptyFamilySelector';
export const useIsFieldEmpty = () => { export const useIsFieldEmpty = () => {
const { entityId, fieldDefinition } = useContext(FieldContext); const { entityId, fieldDefinition } = useContext(FieldContext);
const fieldValue = useRecoilValue(
const isFieldEmpty = useRecoilValue( recordStoreFamilySelector({
isEntityFieldEmptyFamilySelector({
fieldDefinition: {
type: fieldDefinition.type,
},
fieldName: fieldDefinition.metadata.fieldName, fieldName: fieldDefinition.metadata.fieldName,
entityId, recordId: entityId,
}), }),
); );
return isFieldEmpty; return isFieldValueEmpty({
fieldDefinition,
fieldValue,
});
}; };

View File

@ -5,9 +5,9 @@ import { isFieldFullName } from '@/object-record/field/types/guards/isFieldFullN
import { isFieldFullNameValue } from '@/object-record/field/types/guards/isFieldFullNameValue'; import { isFieldFullNameValue } from '@/object-record/field/types/guards/isFieldFullNameValue';
import { isFieldSelect } from '@/object-record/field/types/guards/isFieldSelect'; import { isFieldSelect } from '@/object-record/field/types/guards/isFieldSelect';
import { isFieldSelectValue } from '@/object-record/field/types/guards/isFieldSelectValue'; import { isFieldSelectValue } from '@/object-record/field/types/guards/isFieldSelectValue';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldContext } from '../contexts/FieldContext'; import { FieldContext } from '../contexts/FieldContext';
import { entityFieldsFamilySelector } from '../states/selectors/entityFieldsFamilySelector';
import { isFieldBoolean } from '../types/guards/isFieldBoolean'; import { isFieldBoolean } from '../types/guards/isFieldBoolean';
import { isFieldBooleanValue } from '../types/guards/isFieldBooleanValue'; import { isFieldBooleanValue } from '../types/guards/isFieldBooleanValue';
import { isFieldCurrency } from '../types/guards/isFieldCurrency'; import { isFieldCurrency } from '../types/guards/isFieldCurrency';
@ -86,7 +86,7 @@ export const usePersistField = () => {
const fieldName = fieldDefinition.metadata.fieldName; const fieldName = fieldDefinition.metadata.fieldName;
set( set(
entityFieldsFamilySelector({ entityId, fieldName }), recordStoreFamilySelector({ recordId: entityId, fieldName }),
valueToPersist, valueToPersist,
); );
@ -114,7 +114,7 @@ export const usePersistField = () => {
) { ) {
const fieldName = fieldDefinition.metadata.fieldName; const fieldName = fieldDefinition.metadata.fieldName;
set( set(
entityFieldsFamilySelector({ entityId, fieldName }), recordStoreFamilySelector({ recordId: entityId, fieldName }),
valueToPersist, valueToPersist,
); );

View File

@ -1,8 +1,9 @@
import { useContext } from 'react'; import { useContext } from 'react';
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldContext } from '../contexts/FieldContext'; import { FieldContext } from '../contexts/FieldContext';
import { entityFieldsFamilySelector } from '../states/selectors/entityFieldsFamilySelector';
import { isFieldBoolean } from '../types/guards/isFieldBoolean'; import { isFieldBoolean } from '../types/guards/isFieldBoolean';
export const useToggleEditOnlyInput = () => { export const useToggleEditOnlyInput = () => {
@ -22,11 +23,13 @@ export const useToggleEditOnlyInput = () => {
if (fieldIsBoolean) { if (fieldIsBoolean) {
const fieldName = fieldDefinition.metadata.fieldName; const fieldName = fieldDefinition.metadata.fieldName;
const oldValue = snapshot const oldValue = snapshot
.getLoadable(entityFieldsFamilySelector({ entityId, fieldName })) .getLoadable(
.valueOrThrow(); recordStoreFamilySelector({ recordId: entityId, fieldName }),
)
.getValue();
const valueToPersist = !oldValue; const valueToPersist = !oldValue;
set( set(
entityFieldsFamilySelector({ entityId, fieldName }), recordStoreFamilySelector({ recordId: entityId, fieldName }),
valueToPersist, valueToPersist,
); );

View File

@ -4,13 +4,13 @@ import { Meta, StoryObj } from '@storybook/react';
import { useSetRecoilState } from 'recoil'; import { useSetRecoilState } from 'recoil';
import { ChipFieldDisplay } from '@/object-record/field/meta-types/display/components/ChipFieldDisplay'; import { ChipFieldDisplay } from '@/object-record/field/meta-types/display/components/ChipFieldDisplay';
import { entityFieldsFamilyState } from '@/object-record/field/states/entityFieldsFamilyState'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator'; import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { FieldContext } from '../../../../contexts/FieldContext'; import { FieldContext } from '../../../../contexts/FieldContext';
const ChipFieldValueSetterEffect = () => { const ChipFieldValueSetterEffect = () => {
const setEntityFields = useSetRecoilState(entityFieldsFamilyState('123')); const setEntityFields = useSetRecoilState(recordStoreFamilyState('123'));
useEffect(() => { useEffect(() => {
setEntityFields({ setEntityFields({

View File

@ -1,8 +1,9 @@
import { useContext } from 'react'; import { useContext } from 'react';
import { useRecoilState } from 'recoil'; import { useRecoilState } from 'recoil';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldContext } from '../../contexts/FieldContext'; import { FieldContext } from '../../contexts/FieldContext';
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata'; import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
import { isFieldBoolean } from '../../types/guards/isFieldBoolean'; import { isFieldBoolean } from '../../types/guards/isFieldBoolean';
@ -14,8 +15,8 @@ export const useBooleanField = () => {
const fieldName = fieldDefinition.metadata.fieldName; const fieldName = fieldDefinition.metadata.fieldName;
const [fieldValue, setFieldValue] = useRecoilState<boolean>( const [fieldValue, setFieldValue] = useRecoilState<boolean>(
entityFieldsFamilySelector({ recordStoreFamilySelector({
entityId: entityId, recordId: entityId,
fieldName: fieldName, fieldName: fieldName,
}), }),
); );

View File

@ -1,10 +1,10 @@
import { useContext } from 'react'; import { useContext } from 'react';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { entityFieldsFamilyState } from '@/object-record/field/states/entityFieldsFamilyState';
import { isFieldFullName } from '@/object-record/field/types/guards/isFieldFullName'; import { isFieldFullName } from '@/object-record/field/types/guards/isFieldFullName';
import { isFieldNumber } from '@/object-record/field/types/guards/isFieldNumber'; import { isFieldNumber } from '@/object-record/field/types/guards/isFieldNumber';
import { isFieldText } from '@/object-record/field/types/guards/isFieldText'; import { isFieldText } from '@/object-record/field/types/guards/isFieldText';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { FieldContext } from '../../contexts/FieldContext'; import { FieldContext } from '../../contexts/FieldContext';
@ -18,7 +18,7 @@ export const useChipField = () => {
? fieldDefinition.metadata.objectMetadataNameSingular ? fieldDefinition.metadata.objectMetadataNameSingular
: undefined; : undefined;
const record = useRecoilValue(entityFieldsFamilyState(entityId)); const record = useRecoilValue(recordStoreFamilyState(entityId));
return { return {
objectNameSingular, objectNameSingular,

View File

@ -3,6 +3,7 @@ import { useRecoilState } from 'recoil';
import { CurrencyCode } from '@/object-record/field/types/CurrencyCode'; import { CurrencyCode } from '@/object-record/field/types/CurrencyCode';
import { FieldInitialValue } from '@/object-record/field/types/FieldInitialValue'; import { FieldInitialValue } from '@/object-record/field/types/FieldInitialValue';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { canBeCastAsIntegerOrNull } from '~/utils/cast-as-integer-or-null'; import { canBeCastAsIntegerOrNull } from '~/utils/cast-as-integer-or-null';
import { import {
convertCurrencyMicrosToCurrency, convertCurrencyMicrosToCurrency,
@ -12,7 +13,6 @@ import {
import { FieldContext } from '../../contexts/FieldContext'; import { FieldContext } from '../../contexts/FieldContext';
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue'; import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
import { usePersistField } from '../../hooks/usePersistField'; import { usePersistField } from '../../hooks/usePersistField';
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
import { FieldCurrencyValue } from '../../types/FieldMetadata'; import { FieldCurrencyValue } from '../../types/FieldMetadata';
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata'; import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
import { isFieldCurrency } from '../../types/guards/isFieldCurrency'; import { isFieldCurrency } from '../../types/guards/isFieldCurrency';
@ -50,8 +50,8 @@ export const useCurrencyField = () => {
const fieldName = fieldDefinition.metadata.fieldName; const fieldName = fieldDefinition.metadata.fieldName;
const [fieldValue, setFieldValue] = useRecoilState<FieldCurrencyValue>( const [fieldValue, setFieldValue] = useRecoilState<FieldCurrencyValue>(
entityFieldsFamilySelector({ recordStoreFamilySelector({
entityId: entityId, recordId: entityId,
fieldName: fieldName, fieldName: fieldName,
}), }),
); );

View File

@ -1,8 +1,9 @@
import { useContext } from 'react'; import { useContext } from 'react';
import { useRecoilState } from 'recoil'; import { useRecoilState } from 'recoil';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldContext } from '../../contexts/FieldContext'; import { FieldContext } from '../../contexts/FieldContext';
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata'; import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
import { isFieldDateTime } from '../../types/guards/isFieldDateTime'; import { isFieldDateTime } from '../../types/guards/isFieldDateTime';
@ -15,8 +16,8 @@ export const useDateTimeField = () => {
const fieldName = fieldDefinition.metadata.fieldName; const fieldName = fieldDefinition.metadata.fieldName;
const [fieldValue, setFieldValue] = useRecoilState<string>( const [fieldValue, setFieldValue] = useRecoilState<string>(
entityFieldsFamilySelector({ recordStoreFamilySelector({
entityId: entityId, recordId: entityId,
fieldName: fieldName, fieldName: fieldName,
}), }),
); );

View File

@ -1,9 +1,10 @@
import { useContext } from 'react'; import { useContext } from 'react';
import { useRecoilState } from 'recoil'; import { useRecoilState } from 'recoil';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldContext } from '../../contexts/FieldContext'; import { FieldContext } from '../../contexts/FieldContext';
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue'; import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata'; import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
import { isFieldEmail } from '../../types/guards/isFieldEmail'; import { isFieldEmail } from '../../types/guards/isFieldEmail';
@ -15,8 +16,8 @@ export const useEmailField = () => {
const fieldName = fieldDefinition.metadata.fieldName; const fieldName = fieldDefinition.metadata.fieldName;
const [fieldValue, setFieldValue] = useRecoilState<string>( const [fieldValue, setFieldValue] = useRecoilState<string>(
entityFieldsFamilySelector({ recordStoreFamilySelector({
entityId: entityId, recordId: entityId,
fieldName: fieldName, fieldName: fieldName,
}), }),
); );

View File

@ -1,10 +1,11 @@
import { useContext } from 'react'; import { useContext } from 'react';
import { useRecoilState } from 'recoil'; import { useRecoilState } from 'recoil';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldContext } from '../../contexts/FieldContext'; import { FieldContext } from '../../contexts/FieldContext';
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue'; import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
import { usePersistField } from '../../hooks/usePersistField'; import { usePersistField } from '../../hooks/usePersistField';
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
import { FieldFullNameValue } from '../../types/FieldMetadata'; import { FieldFullNameValue } from '../../types/FieldMetadata';
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata'; import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
import { isFieldFullName } from '../../types/guards/isFieldFullName'; import { isFieldFullName } from '../../types/guards/isFieldFullName';
@ -18,8 +19,8 @@ export const useFullNameField = () => {
const fieldName = fieldDefinition.metadata.fieldName; const fieldName = fieldDefinition.metadata.fieldName;
const [fieldValue, setFieldValue] = useRecoilState<FieldFullNameValue>( const [fieldValue, setFieldValue] = useRecoilState<FieldFullNameValue>(
entityFieldsFamilySelector({ recordStoreFamilySelector({
entityId: entityId, recordId: entityId,
fieldName: fieldName, fieldName: fieldName,
}), }),
); );

View File

@ -1,10 +1,11 @@
import { useContext } from 'react'; import { useContext } from 'react';
import { useRecoilState } from 'recoil'; import { useRecoilState } from 'recoil';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldContext } from '../../contexts/FieldContext'; import { FieldContext } from '../../contexts/FieldContext';
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue'; import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
import { usePersistField } from '../../hooks/usePersistField'; import { usePersistField } from '../../hooks/usePersistField';
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
import { FieldLinkValue } from '../../types/FieldMetadata'; import { FieldLinkValue } from '../../types/FieldMetadata';
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata'; import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
import { isFieldLink } from '../../types/guards/isFieldLink'; import { isFieldLink } from '../../types/guards/isFieldLink';
@ -18,8 +19,8 @@ export const useLinkField = () => {
const fieldName = fieldDefinition.metadata.fieldName; const fieldName = fieldDefinition.metadata.fieldName;
const [fieldValue, setFieldValue] = useRecoilState<FieldLinkValue>( const [fieldValue, setFieldValue] = useRecoilState<FieldLinkValue>(
entityFieldsFamilySelector({ recordStoreFamilySelector({
entityId: entityId, recordId: entityId,
fieldName: fieldName, fieldName: fieldName,
}), }),
); );

View File

@ -1,6 +1,7 @@
import { useContext } from 'react'; import { useContext } from 'react';
import { useRecoilState } from 'recoil'; import { useRecoilState } from 'recoil';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { import {
canBeCastAsIntegerOrNull, canBeCastAsIntegerOrNull,
castAsIntegerOrNull, castAsIntegerOrNull,
@ -9,7 +10,6 @@ import {
import { FieldContext } from '../../contexts/FieldContext'; import { FieldContext } from '../../contexts/FieldContext';
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue'; import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
import { usePersistField } from '../../hooks/usePersistField'; import { usePersistField } from '../../hooks/usePersistField';
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata'; import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
import { isFieldNumber } from '../../types/guards/isFieldNumber'; import { isFieldNumber } from '../../types/guards/isFieldNumber';
@ -21,8 +21,8 @@ export const useNumberField = () => {
const fieldName = fieldDefinition.metadata.fieldName; const fieldName = fieldDefinition.metadata.fieldName;
const [fieldValue, setFieldValue] = useRecoilState<number | null>( const [fieldValue, setFieldValue] = useRecoilState<number | null>(
entityFieldsFamilySelector({ recordStoreFamilySelector({
entityId: entityId, recordId: entityId,
fieldName: fieldName, fieldName: fieldName,
}), }),
); );

View File

@ -2,10 +2,11 @@ import { useContext } from 'react';
import { isPossiblePhoneNumber } from 'libphonenumber-js'; import { isPossiblePhoneNumber } from 'libphonenumber-js';
import { useRecoilState } from 'recoil'; import { useRecoilState } from 'recoil';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldContext } from '../../contexts/FieldContext'; import { FieldContext } from '../../contexts/FieldContext';
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue'; import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
import { usePersistField } from '../../hooks/usePersistField'; import { usePersistField } from '../../hooks/usePersistField';
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata'; import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
import { isFieldPhone } from '../../types/guards/isFieldPhone'; import { isFieldPhone } from '../../types/guards/isFieldPhone';
@ -18,8 +19,8 @@ export const usePhoneField = () => {
const fieldName = fieldDefinition.metadata.fieldName; const fieldName = fieldDefinition.metadata.fieldName;
const [fieldValue, setFieldValue] = useRecoilState<string>( const [fieldValue, setFieldValue] = useRecoilState<string>(
entityFieldsFamilySelector({ recordStoreFamilySelector({
entityId: entityId, recordId: entityId,
fieldName: fieldName, fieldName: fieldName,
}), }),
); );

View File

@ -1,10 +1,10 @@
import { useContext } from 'react'; import { useContext } from 'react';
import { useRecoilState } from 'recoil'; import { useRecoilState } from 'recoil';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldMetadataType } from '~/generated-metadata/graphql'; import { FieldMetadataType } from '~/generated-metadata/graphql';
import { FieldContext } from '../../contexts/FieldContext'; import { FieldContext } from '../../contexts/FieldContext';
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
import { FieldRatingValue } from '../../types/FieldMetadata'; import { FieldRatingValue } from '../../types/FieldMetadata';
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata'; import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
import { isFieldRating } from '../../types/guards/isFieldRating'; import { isFieldRating } from '../../types/guards/isFieldRating';
@ -17,8 +17,8 @@ export const useRatingField = () => {
const fieldName = fieldDefinition.metadata.fieldName; const fieldName = fieldDefinition.metadata.fieldName;
const [fieldValue, setFieldValue] = useRecoilState<FieldRatingValue | null>( const [fieldValue, setFieldValue] = useRecoilState<FieldRatingValue | null>(
entityFieldsFamilySelector({ recordStoreFamilySelector({
entityId: entityId, recordId: entityId,
fieldName: fieldName, fieldName: fieldName,
}), }),
); );

View File

@ -2,10 +2,10 @@ import { useContext } from 'react';
import { useRecoilState } from 'recoil'; import { useRecoilState } from 'recoil';
import { useGetButtonIcon } from '@/object-record/field/hooks/useGetButtonIcon'; import { useGetButtonIcon } from '@/object-record/field/hooks/useGetButtonIcon';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldContext } from '../../contexts/FieldContext'; import { FieldContext } from '../../contexts/FieldContext';
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue'; import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata'; import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
import { isFieldRelation } from '../../types/guards/isFieldRelation'; import { isFieldRelation } from '../../types/guards/isFieldRelation';
@ -18,7 +18,7 @@ export const useRelationField = () => {
const fieldName = fieldDefinition.metadata.fieldName; const fieldName = fieldDefinition.metadata.fieldName;
const [fieldValue, setFieldValue] = useRecoilState<any | null>( const [fieldValue, setFieldValue] = useRecoilState<any | null>(
entityFieldsFamilySelector({ entityId, fieldName }), recordStoreFamilySelector({ recordId: entityId, fieldName }),
); );
const fieldInitialValue = useFieldInitialValue(); const fieldInitialValue = useFieldInitialValue();

View File

@ -2,11 +2,11 @@ import { useContext } from 'react';
import { useRecoilState } from 'recoil'; import { useRecoilState } from 'recoil';
import { usePersistField } from '@/object-record/field/hooks/usePersistField'; import { usePersistField } from '@/object-record/field/hooks/usePersistField';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldMetadataType } from '~/generated/graphql'; import { FieldMetadataType } from '~/generated/graphql';
import { FieldContext } from '../../contexts/FieldContext'; import { FieldContext } from '../../contexts/FieldContext';
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue'; import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
import { FieldSelectValue } from '../../types/FieldMetadata'; import { FieldSelectValue } from '../../types/FieldMetadata';
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata'; import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
import { isFieldSelect } from '../../types/guards/isFieldSelect'; import { isFieldSelect } from '../../types/guards/isFieldSelect';
@ -20,8 +20,8 @@ export const useSelectField = () => {
const { fieldName } = fieldDefinition.metadata; const { fieldName } = fieldDefinition.metadata;
const [fieldValue, setFieldValue] = useRecoilState<FieldSelectValue>( const [fieldValue, setFieldValue] = useRecoilState<FieldSelectValue>(
entityFieldsFamilySelector({ recordStoreFamilySelector({
entityId: entityId, recordId: entityId,
fieldName: fieldName, fieldName: fieldName,
}), }),
); );

View File

@ -1,9 +1,10 @@
import { useContext } from 'react'; import { useContext } from 'react';
import { useRecoilState } from 'recoil'; import { useRecoilState } from 'recoil';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldContext } from '../../contexts/FieldContext'; import { FieldContext } from '../../contexts/FieldContext';
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue'; import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata'; import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
import { isFieldText } from '../../types/guards/isFieldText'; import { isFieldText } from '../../types/guards/isFieldText';
import { isFieldTextValue } from '../../types/guards/isFieldTextValue'; import { isFieldTextValue } from '../../types/guards/isFieldTextValue';
@ -17,8 +18,8 @@ export const useTextField = () => {
const fieldName = fieldDefinition.metadata.fieldName; const fieldName = fieldDefinition.metadata.fieldName;
const [fieldValue, setFieldValue] = useRecoilState<string>( const [fieldValue, setFieldValue] = useRecoilState<string>(
entityFieldsFamilySelector({ recordStoreFamilySelector({
entityId: entityId, recordId: entityId,
fieldName: fieldName, fieldName: fieldName,
}), }),
); );

View File

@ -2,10 +2,10 @@ import { useContext } from 'react';
import { useRecoilState } from 'recoil'; import { useRecoilState } from 'recoil';
import { isFieldUuid } from '@/object-record/field/types/guards/isFieldUuid'; import { isFieldUuid } from '@/object-record/field/types/guards/isFieldUuid';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { FieldContext } from '../../contexts/FieldContext'; import { FieldContext } from '../../contexts/FieldContext';
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue'; import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata'; import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
import { isFieldTextValue } from '../../types/guards/isFieldTextValue'; import { isFieldTextValue } from '../../types/guards/isFieldTextValue';
@ -17,8 +17,8 @@ export const useUuidField = () => {
const fieldName = fieldDefinition.metadata.fieldName; const fieldName = fieldDefinition.metadata.fieldName;
const [fieldValue, setFieldValue] = useRecoilState<string>( const [fieldValue, setFieldValue] = useRecoilState<string>(
entityFieldsFamilySelector({ recordStoreFamilySelector({
entityId: entityId, recordId: entityId,
fieldName: fieldName, fieldName: fieldName,
}), }),
); );

View File

@ -3,7 +3,7 @@ import { Meta, StoryObj } from '@storybook/react';
import { expect, fn, userEvent, within } from '@storybook/test'; import { expect, fn, userEvent, within } from '@storybook/test';
import { useSetRecoilState } from 'recoil'; import { useSetRecoilState } from 'recoil';
import { entityFieldsFamilyState } from '@/object-record/field/states/entityFieldsFamilyState'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { FieldContextProvider } from '../../../__stories__/FieldContextProvider'; import { FieldContextProvider } from '../../../__stories__/FieldContextProvider';
import { import {
@ -18,7 +18,7 @@ const BooleanFieldValueSetterEffect = ({
value: boolean; value: boolean;
entityId: string; entityId: string;
}) => { }) => {
const setField = useSetRecoilState(entityFieldsFamilyState(entityId)); const setField = useSetRecoilState(recordStoreFamilyState(entityId));
useEffect(() => { useEffect(() => {
setField({ id: entityId, Boolean: value }); setField({ id: entityId, Boolean: value });

View File

@ -1,8 +0,0 @@
import { atomFamily } from 'recoil';
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
export const entityFieldsFamilyState = atomFamily<ObjectRecord | null, string>({
key: 'entityFieldsFamilyState',
default: null,
});

View File

@ -1,17 +0,0 @@
import { selectorFamily } from 'recoil';
import { entityFieldsFamilyState } from '../entityFieldsFamilyState';
export const entityFieldsFamilySelector = selectorFamily({
key: 'entityFieldsFamilySelector',
get:
<T>({ fieldName, entityId }: { fieldName: string; entityId: string }) =>
({ get }) =>
get(entityFieldsFamilyState(entityId))?.[fieldName] as T,
set:
<T>({ fieldName, entityId }: { fieldName: string; entityId: string }) =>
({ set }, newValue: T) =>
set(entityFieldsFamilyState(entityId), (prevState) =>
prevState ? { ...prevState, [fieldName]: newValue } : null,
),
});

View File

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

View File

@ -5,9 +5,9 @@ import { useRecoilCallback, useRecoilValue, useSetRecoilState } from 'recoil';
import { useOpenCreateActivityDrawerForSelectedRowIds } from '@/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds'; import { useOpenCreateActivityDrawerForSelectedRowIds } from '@/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds';
import { useFavorites } from '@/favorites/hooks/useFavorites'; import { useFavorites } from '@/favorites/hooks/useFavorites';
import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural'; import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural';
import { entityFieldsFamilyState } from '@/object-record/field/states/entityFieldsFamilyState';
import { useDeleteManyRecords } from '@/object-record/hooks/useDeleteManyRecords'; import { useDeleteManyRecords } from '@/object-record/hooks/useDeleteManyRecords';
import { useExecuteQuickActionOnOneRecord } from '@/object-record/hooks/useExecuteQuickActionOnOneRecord'; import { useExecuteQuickActionOnOneRecord } from '@/object-record/hooks/useExecuteQuickActionOnOneRecord';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates'; import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates';
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable'; import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
import { import {
@ -38,9 +38,11 @@ export const useRecordTableContextMenuEntries = (
const setContextMenuEntries = useSetRecoilState(contextMenuEntriesState); const setContextMenuEntries = useSetRecoilState(contextMenuEntriesState);
const setActionBarEntriesState = useSetRecoilState(actionBarEntriesState); const setActionBarEntriesState = useSetRecoilState(actionBarEntriesState);
const { selectedRowIdsSelector } = useRecordTableStates(props?.recordTableId); const { getSelectedRowIdsSelector } = useRecordTableStates(
props?.recordTableId,
);
const selectedRowIds = useRecoilValue(selectedRowIdsSelector); const selectedRowIds = useRecoilValue(getSelectedRowIdsSelector());
const { resetTableRowSelection } = useRecordTable({ const { resetTableRowSelection } = useRecordTable({
recordTableId: props?.recordTableId, recordTableId: props?.recordTableId,
@ -53,12 +55,15 @@ export const useRecordTableContextMenuEntries = (
const { createFavorite, favorites, deleteFavorite } = useFavorites(); const { createFavorite, favorites, deleteFavorite } = useFavorites();
const handleFavoriteButtonClick = useRecoilCallback(({ snapshot }) => () => { const handleFavoriteButtonClick = useRecoilCallback(({ snapshot }) => () => {
const selectedRowIds = getSnapshotValue(snapshot, selectedRowIdsSelector); const selectedRowIds = getSnapshotValue(
snapshot,
getSelectedRowIdsSelector(),
);
const selectedRowId = selectedRowIds.length === 1 ? selectedRowIds[0] : ''; const selectedRowId = selectedRowIds.length === 1 ? selectedRowIds[0] : '';
const selectedRecord = snapshot const selectedRecord = snapshot
.getLoadable(entityFieldsFamilyState(selectedRowId)) .getLoadable(recordStoreFamilyState(selectedRowId))
.getValue(); .getValue();
const foundFavorite = favorites?.find( const foundFavorite = favorites?.find(
@ -89,13 +94,13 @@ export const useRecordTableContextMenuEntries = (
async () => { async () => {
const rowIdsToDelete = getSnapshotValue( const rowIdsToDelete = getSnapshotValue(
snapshot, snapshot,
selectedRowIdsSelector, getSelectedRowIdsSelector(),
); );
resetTableRowSelection(); resetTableRowSelection();
await deleteManyRecords(rowIdsToDelete); await deleteManyRecords(rowIdsToDelete);
}, },
[deleteManyRecords, resetTableRowSelection, selectedRowIdsSelector], [deleteManyRecords, resetTableRowSelection, getSelectedRowIdsSelector],
); );
const handleExecuteQuickActionOnClick = useRecoilCallback( const handleExecuteQuickActionOnClick = useRecoilCallback(
@ -103,7 +108,7 @@ export const useRecordTableContextMenuEntries = (
async () => { async () => {
const rowIdsToExecuteQuickActionOn = getSnapshotValue( const rowIdsToExecuteQuickActionOn = getSnapshotValue(
snapshot, snapshot,
selectedRowIdsSelector, getSelectedRowIdsSelector(),
); );
resetTableRowSelection(); resetTableRowSelection();
@ -116,7 +121,7 @@ export const useRecordTableContextMenuEntries = (
[ [
executeQuickActionOnOneRecord, executeQuickActionOnOneRecord,
resetTableRowSelection, resetTableRowSelection,
selectedRowIdsSelector, getSelectedRowIdsSelector,
], ],
); );

View File

@ -1,6 +1,6 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { entityFieldsFamilySelector } from '@/object-record/field/states/selectors/entityFieldsFamilySelector'; import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
export const useUpsertRecordFieldFromState = () => export const useUpsertRecordFieldFromState = () =>
@ -14,7 +14,7 @@ export const useUpsertRecordFieldFromState = () =>
fieldName: F extends string ? F : never; fieldName: F extends string ? F : never;
}) => }) =>
set( set(
entityFieldsFamilySelector({ entityId: record.id, fieldName }), recordStoreFamilySelector({ recordId: record.id, fieldName }),
(previousField) => (previousField) =>
isDeeplyEqual(previousField, record[fieldName]) isDeeplyEqual(previousField, record[fieldName])
? previousField ? previousField

View File

@ -1,6 +1,6 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { entityFieldsFamilyState } from '@/object-record/field/states/entityFieldsFamilyState'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
// TODO: refactor with scoped state later // TODO: refactor with scoped state later
@ -8,7 +8,7 @@ export const useUpsertRecordFromState = () =>
useRecoilCallback( useRecoilCallback(
({ set }) => ({ set }) =>
<T extends { id: string }>(record: T) => <T extends { id: string }>(record: T) =>
set(entityFieldsFamilyState(record.id), (previousRecord) => set(recordStoreFamilyState(record.id), (previousRecord) =>
isDeeplyEqual(previousRecord, record) ? previousRecord : record, isDeeplyEqual(previousRecord, record) ? previousRecord : record,
), ),
[], [],

View File

@ -1,9 +1,9 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { entityFieldsFamilyState } from '@/object-record/field/states/entityFieldsFamilyState';
import { useRecordBoardDeprecatedScopedStates } from '@/object-record/record-board-deprecated/hooks/internal/useRecordBoardDeprecatedScopedStates'; import { useRecordBoardDeprecatedScopedStates } from '@/object-record/record-board-deprecated/hooks/internal/useRecordBoardDeprecatedScopedStates';
import { recordBoardCardIdsByColumnIdFamilyState } from '@/object-record/record-board-deprecated/states/recordBoardCardIdsByColumnIdFamilyState'; import { recordBoardCardIdsByColumnIdFamilyState } from '@/object-record/record-board-deprecated/states/recordBoardCardIdsByColumnIdFamilyState';
import { BoardColumnDefinition } from '@/object-record/record-board-deprecated/types/BoardColumnDefinition'; import { BoardColumnDefinition } from '@/object-record/record-board-deprecated/types/BoardColumnDefinition';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { currentPipelineStepsState } from '@/pipeline/states/currentPipelineStepsState'; import { currentPipelineStepsState } from '@/pipeline/states/currentPipelineStepsState';
import { Opportunity } from '@/pipeline/types/Opportunity'; import { Opportunity } from '@/pipeline/types/Opportunity';
import { PipelineStep } from '@/pipeline/types/PipelineStep'; import { PipelineStep } from '@/pipeline/types/PipelineStep';
@ -72,7 +72,7 @@ export const useUpdateCompanyBoardColumnsInternal = () => {
if (!isDeeplyEqual(currentCompanyProgress, companyProgress)) { if (!isDeeplyEqual(currentCompanyProgress, companyProgress)) {
set(companyProgressesFamilyState(id), companyProgress); set(companyProgressesFamilyState(id), companyProgress);
set(entityFieldsFamilyState(id), companyProgress.opportunity); set(recordStoreFamilyState(id), companyProgress.opportunity);
} }
} }

View File

@ -1,16 +1,20 @@
import { RecordBoardScopeInternalContext } from '@/object-record/record-board/scopes/scope-internal-context/RecordBoardScopeInternalContext'; import { RecordBoardScopeInternalContext } from '@/object-record/record-board/scopes/scope-internal-context/RecordBoardScopeInternalContext';
import { isFirstRecordBoardColumnFamilyStateScopeMap } from '@/object-record/record-board/states/isFirstRecordBoardColumnFamilyStateScopeMap'; import { isFirstRecordBoardColumnFamilyStateScopeMap } from '@/object-record/record-board/states/isFirstRecordBoardColumnFamilyStateScopeMap';
import { isLastRecordBoardColumnFamilyStateScopeMap } from '@/object-record/record-board/states/isLastRecordBoardColumnFamilyStateScopeMap'; import { isLastRecordBoardColumnFamilyStateScopeMap } from '@/object-record/record-board/states/isLastRecordBoardColumnFamilyStateScopeMap';
import { isRecordBoardCardSelectedFamilyStateScopeMap } from '@/object-record/record-board/states/isRecordBoardCardSelectedFamilyStateScopeMap';
import { isRecordBoardCompactModeActiveStateScopeMap } from '@/object-record/record-board/states/isRecordBoardCompactModeActiveStateScopeMap';
import { recordBoardColumnIdsStateScopeMap } from '@/object-record/record-board/states/recordBoardColumnIdsStateScopeMap'; import { recordBoardColumnIdsStateScopeMap } from '@/object-record/record-board/states/recordBoardColumnIdsStateScopeMap';
import { recordBoardFieldDefinitionsStateScopeMap } from '@/object-record/record-board/states/recordBoardFieldDefinitionsStateScopeMap'; import { recordBoardFieldDefinitionsStateScopeMap } from '@/object-record/record-board/states/recordBoardFieldDefinitionsStateScopeMap';
import { recordBoardFiltersStateScopeMap } from '@/object-record/record-board/states/recordBoardFiltersStateScopeMap'; import { recordBoardFiltersStateScopeMap } from '@/object-record/record-board/states/recordBoardFiltersStateScopeMap';
import { recordBoardObjectMetadataSingularNameStateScopeMap } from '@/object-record/record-board/states/recordBoardObjectMetadataSingularNameStateScopeMap'; import { recordBoardObjectSingularNameStateScopeMap } from '@/object-record/record-board/states/recordBoardObjectSingularNameStateScopeMap';
import { recordBoardRecordIdsByColumnIdFamilyStateScopeMap } from '@/object-record/record-board/states/recordBoardRecordIdsByColumnIdFamilyStateScopeMap'; import { recordBoardRecordIdsByColumnIdFamilyStateScopeMap } from '@/object-record/record-board/states/recordBoardRecordIdsByColumnIdFamilyStateScopeMap';
import { recordBoardSortsStateScopeMap } from '@/object-record/record-board/states/recordBoardSortsStateScopeMap'; import { recordBoardSortsStateScopeMap } from '@/object-record/record-board/states/recordBoardSortsStateScopeMap';
import { recordBoardColumnsFamilySelectorScopeMap } from '@/object-record/record-board/states/selectors/recordBoardColumnsFamilySelectorScopeMap'; import { recordBoardColumnsFamilySelectorScopeMap } from '@/object-record/record-board/states/selectors/recordBoardColumnsFamilySelectorScopeMap';
import { recordBoardVisibleFieldDefinitionsScopedSelector } from '@/object-record/record-board/states/selectors/recordBoardVisibleFieldDefinitionsScopedSelector';
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId'; import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
import { getFamilyState } from '@/ui/utilities/recoil-scope/utils/getFamilyState'; import { getFamilyState } from '@/ui/utilities/recoil-scope/utils/getFamilyState';
import { getScopeIdOrUndefinedFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdOrUndefinedFromComponentId'; import { getScopeIdOrUndefinedFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdOrUndefinedFromComponentId';
import { getSelector } from '@/ui/utilities/recoil-scope/utils/getSelector';
import { getState } from '@/ui/utilities/recoil-scope/utils/getState'; import { getState } from '@/ui/utilities/recoil-scope/utils/getState';
export const useRecordBoardStates = (recordBoardId?: string) => { export const useRecordBoardStates = (recordBoardId?: string) => {
@ -21,8 +25,8 @@ export const useRecordBoardStates = (recordBoardId?: string) => {
return { return {
scopeId, scopeId,
getObjectMetadataSingularNameState: getState( getObjectSingularNameState: getState(
recordBoardObjectMetadataSingularNameStateScopeMap, recordBoardObjectSingularNameStateScopeMap,
scopeId, scopeId,
), ),
getColumnIdsState: getState(recordBoardColumnIdsStateScopeMap, scopeId), getColumnIdsState: getState(recordBoardColumnIdsStateScopeMap, scopeId),
@ -45,10 +49,23 @@ export const useRecordBoardStates = (recordBoardId?: string) => {
recordBoardFieldDefinitionsStateScopeMap, recordBoardFieldDefinitionsStateScopeMap,
scopeId, scopeId,
), ),
getVisibleFieldDefinitionsState: getSelector(
recordBoardVisibleFieldDefinitionsScopedSelector,
scopeId,
),
recordBoardRecordIdsByColumnIdFamilyState: getFamilyState( recordBoardRecordIdsByColumnIdFamilyState: getFamilyState(
recordBoardRecordIdsByColumnIdFamilyStateScopeMap, recordBoardRecordIdsByColumnIdFamilyStateScopeMap,
scopeId, scopeId,
), ),
isRecordBoardCardSelectedFamilyState: getFamilyState(
isRecordBoardCardSelectedFamilyStateScopeMap,
scopeId,
),
getIsCompactModeActiveState: getState(
isRecordBoardCompactModeActiveStateScopeMap,
scopeId,
),
}; };
}; };

View File

@ -5,17 +5,19 @@ import { useSetRecordBoardColumns } from '@/object-record/record-board/hooks/int
import { useSetRecordBoardRecordIds } from '@/object-record/record-board/hooks/internal/useSetRecordBoardRecordIds'; import { useSetRecordBoardRecordIds } from '@/object-record/record-board/hooks/internal/useSetRecordBoardRecordIds';
export const useRecordBoard = (recordBoardId?: string) => { export const useRecordBoard = (recordBoardId?: string) => {
const { scopeId, getFieldDefinitionsState } = const { scopeId, getFieldDefinitionsState, getObjectSingularNameState } =
useRecordBoardStates(recordBoardId); useRecordBoardStates(recordBoardId);
const { setColumns } = useSetRecordBoardColumns(recordBoardId); const { setColumns } = useSetRecordBoardColumns(recordBoardId);
const { setRecordIds } = useSetRecordBoardRecordIds(recordBoardId); const { setRecordIds } = useSetRecordBoardRecordIds(recordBoardId);
const setFieldDefinitions = useSetRecoilState(getFieldDefinitionsState()); const setFieldDefinitions = useSetRecoilState(getFieldDefinitionsState());
const setObjectSingularName = useSetRecoilState(getObjectSingularNameState());
return { return {
scopeId, scopeId,
setColumns, setColumns,
setRecordIds, setRecordIds,
setFieldDefinitions, setFieldDefinitions,
setObjectSingularName,
}; };
}; };

View File

@ -0,0 +1,226 @@
import { ReactNode, useContext, useState } from 'react';
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 { 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';
import { IconEye } from '@/ui/display/icon/index';
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
import { Checkbox, CheckboxVariant } from '@/ui/input/components/Checkbox';
import { AnimatedEaseInOut } from '@/ui/utilities/animation/components/AnimatedEaseInOut';
const StyledBoardCard = styled.div<{ selected: boolean }>`
background-color: ${({ theme, selected }) =>
selected ? theme.accent.quaternary : theme.background.secondary};
border: 1px solid
${({ theme, selected }) =>
selected ? theme.accent.secondary : theme.border.color.medium};
border-radius: ${({ theme }) => theme.border.radius.sm};
box-shadow: ${({ theme }) => theme.boxShadow.light};
color: ${({ theme }) => theme.font.color.primary};
&:hover {
background-color: ${({ theme, selected }) =>
selected && theme.accent.tertiary};
border: 1px solid
${({ theme, selected }) =>
selected ? theme.accent.primary : theme.border.color.medium};
}
cursor: pointer;
.checkbox-container {
transition: all ease-in-out 160ms;
opacity: ${({ selected }) => (selected ? 1 : 0)};
}
&:hover .checkbox-container {
opacity: 1;
}
.compact-icon-container {
transition: all ease-in-out 160ms;
opacity: 0;
}
&:hover .compact-icon-container {
opacity: 1;
}
`;
const StyledBoardCardWrapper = styled.div`
padding-bottom: ${({ theme }) => theme.spacing(2)};
width: 100%;
`;
const StyledBoardCardHeader = styled.div<{
showCompactView: boolean;
}>`
align-items: center;
display: flex;
flex-direction: row;
font-weight: ${({ theme }) => theme.font.weight.medium};
height: 24px;
padding-bottom: ${({ theme, showCompactView }) =>
theme.spacing(showCompactView ? 0 : 1)};
padding-left: ${({ theme }) => theme.spacing(2)};
padding-right: ${({ theme }) => theme.spacing(2)};
padding-top: ${({ theme }) => theme.spacing(2)};
transition: padding ease-in-out 160ms;
img {
height: ${({ theme }) => theme.icon.size.md}px;
margin-right: ${({ theme }) => theme.spacing(2)};
object-fit: cover;
width: ${({ theme }) => theme.icon.size.md}px;
}
`;
const StyledBoardCardBody = styled.div`
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(0.5)};
padding-bottom: ${({ theme }) => theme.spacing(2)};
padding-left: ${({ theme }) => theme.spacing(2.5)};
padding-right: ${({ theme }) => theme.spacing(2)};
span {
align-items: center;
display: flex;
flex-direction: row;
svg {
color: ${({ theme }) => theme.font.color.tertiary};
margin-right: ${({ theme }) => theme.spacing(2)};
}
}
`;
const StyledCheckboxContainer = styled.div`
display: flex;
flex: 1;
justify-content: end;
`;
const StyledFieldContainer = styled.div`
display: flex;
flex-direction: row;
width: 100%;
`;
const StyledCompactIconContainer = styled.div`
align-items: center;
display: flex;
justify-content: center;
`;
export const RecordBoardCard = () => {
const { recordId } = useContext(RecordBoardCardContext);
const {
getObjectSingularNameState,
getIsCompactModeActiveState,
isRecordBoardCardSelectedFamilyState,
getVisibleFieldDefinitionsState,
} = useRecordBoardStates();
const isCompactModeActive = useRecoilValue(getIsCompactModeActiveState());
const objectNameSingular = useRecoilValue(getObjectSingularNameState());
const [isCardInCompactMode, setIsCardInCompactMode] =
useState(isCompactModeActive);
const [isCurrentCardSelected, setIsCurrentCardSelected] = useRecoilState(
isRecordBoardCardSelectedFamilyState(recordId),
);
const visibleBoardCardFieldDefinitions = useRecoilValue(
getVisibleFieldDefinitionsState(),
);
const record = useRecoilValue(recordStoreFamilyState(recordId));
const PreventSelectOnClickContainer = ({
children,
}: {
children: ReactNode;
}) => (
<StyledFieldContainer
onClick={(e) => {
e.stopPropagation();
}}
>
{children}
</StyledFieldContainer>
);
const onMouseLeaveBoard = () => {
if (isCompactModeActive) {
setIsCardInCompactMode(true);
}
};
if (!objectNameSingular || !record) {
return null;
}
return (
<StyledBoardCardWrapper>
<StyledBoardCard
selected={isCurrentCardSelected}
onMouseLeave={onMouseLeaveBoard}
onClick={() => setIsCurrentCardSelected(!isCurrentCardSelected)}
>
<StyledBoardCardHeader showCompactView={isCompactModeActive}>
<RecordChip objectNameSingular={objectNameSingular} record={record} />
{isCompactModeActive && (
<StyledCompactIconContainer className="compact-icon-container">
<LightIconButton
Icon={IconEye}
accent="tertiary"
onClick={(e) => {
e.stopPropagation();
setIsCardInCompactMode(false);
}}
/>
</StyledCompactIconContainer>
)}
<StyledCheckboxContainer className="checkbox-container">
<Checkbox
checked={isCurrentCardSelected}
onChange={() => setIsCurrentCardSelected(!isCurrentCardSelected)}
variant={CheckboxVariant.Secondary}
/>
</StyledCheckboxContainer>
</StyledBoardCardHeader>
<StyledBoardCardBody>
<AnimatedEaseInOut isOpen={!isCardInCompactMode} initial={false}>
{visibleBoardCardFieldDefinitions.map((fieldDefinition) => (
<PreventSelectOnClickContainer
key={fieldDefinition.fieldMetadataId}
>
<FieldContext.Provider
value={{
entityId: recordId,
maxWidth: 156,
recoilScopeId: recordId + fieldDefinition.fieldMetadataId,
isLabelIdentifier: false,
fieldDefinition: {
fieldMetadataId: fieldDefinition.fieldMetadataId,
label: fieldDefinition.label,
iconName: fieldDefinition.iconName,
type: fieldDefinition.type,
metadata: fieldDefinition.metadata,
},
hotkeyScope: InlineCellHotkeyScope.InlineCell,
}}
>
<RecordInlineCell />
</FieldContext.Provider>
</PreventSelectOnClickContainer>
))}
</AnimatedEaseInOut>
</StyledBoardCardBody>
</StyledBoardCard>
</StyledBoardCardWrapper>
);
};

View File

@ -0,0 +1,8 @@
import { createContext } from 'react';
type RecordBoardCardContextProps = {
recordId: string;
};
export const RecordBoardCardContext =
createContext<RecordBoardCardContextProps>({} as RecordBoardCardContextProps);

View File

@ -2,11 +2,12 @@ import styled from '@emotion/styled';
import { Droppable } from '@hello-pangea/dnd'; import { Droppable } from '@hello-pangea/dnd';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { RecordBoardColumnContext } from '@/object-record/record-board/contexts/RecordBoardColumnContext';
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates'; import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
import { RecordBoardCard } from '@/object-record/record-board/record-board-card/components/RecordBoardCard';
import { RecordBoardCardContext } from '@/object-record/record-board/record-board-card/contexts/RecordBoardCardContext';
import { RecordBoardColumnCardsContainer } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnCardsContainer'; import { RecordBoardColumnCardsContainer } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnCardsContainer';
import { RecordBoardColumnHeader } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnHeader'; import { RecordBoardColumnHeader } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnHeader';
import { BoardCardIdContext } from '@/object-record/record-board-deprecated/contexts/BoardCardIdContext'; import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
const StyledColumn = styled.div<{ isFirstColumn: boolean }>` const StyledColumn = styled.div<{ isFirstColumn: boolean }>`
background-color: ${({ theme }) => theme.background.primary}; background-color: ${({ theme }) => theme.background.primary};
@ -71,9 +72,12 @@ export const RecordBoardColumn = ({
droppableProvided={droppableProvided} droppableProvided={droppableProvided}
> >
{recordIds.map((recordId) => ( {recordIds.map((recordId) => (
<BoardCardIdContext.Provider value={recordId} key={recordId}> <RecordBoardCardContext.Provider
<div>Card</div> value={{ recordId }}
</BoardCardIdContext.Provider> key={recordId}
>
<RecordBoardCard />
</RecordBoardCardContext.Provider>
))} ))}
</RecordBoardColumnCardsContainer> </RecordBoardColumnCardsContainer>
</StyledColumn> </StyledColumn>

View File

@ -2,7 +2,7 @@ import { useCallback, useContext, useRef } from 'react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { MenuItem } from 'tsup.ui.index'; import { MenuItem } from 'tsup.ui.index';
import { RecordBoardColumnContext } from '@/object-record/record-board/contexts/RecordBoardColumnContext'; import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu'; import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside'; import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';

View File

@ -1,8 +1,8 @@
import React, { useContext, useState } from 'react'; import React, { useContext, useState } from 'react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { RecordBoardColumnContext } from '@/object-record/record-board/contexts/RecordBoardColumnContext';
import { RecordBoardColumnDropdownMenu } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnDropdownMenu'; import { RecordBoardColumnDropdownMenu } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnDropdownMenu';
import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
import { BoardColumnHotkeyScope } from '@/object-record/record-board-deprecated/types/BoardColumnHotkeyScope'; import { BoardColumnHotkeyScope } from '@/object-record/record-board-deprecated/types/BoardColumnHotkeyScope';
import { IconDotsVertical } from '@/ui/display/icon'; import { IconDotsVertical } from '@/ui/display/icon';
import { Tag } from '@/ui/display/tag/components/Tag'; import { Tag } from '@/ui/display/tag/components/Tag';

View File

@ -0,0 +1,7 @@
import { createFamilyStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createFamilyStateScopeMap';
export const isRecordBoardCardSelectedFamilyStateScopeMap =
createFamilyStateScopeMap<boolean, string>({
key: 'isRecordBoardCardSelectedFamilyStateScopeMap',
defaultValue: false,
});

View File

@ -0,0 +1,7 @@
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
export const isRecordBoardCompactModeActiveStateScopeMap =
createStateScopeMap<boolean>({
key: 'isRecordBoardCompactModeActiveStateScopeMap',
defaultValue: false,
});

View File

@ -1,7 +0,0 @@
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
export const recordBoardObjectMetadataSingularNameStateScopeMap =
createStateScopeMap<string | undefined>({
key: 'recordBoardObjectMetadataSingularNameStateScopeMap',
defaultValue: undefined,
});

View File

@ -0,0 +1,8 @@
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
export const recordBoardObjectSingularNameStateScopeMap = createStateScopeMap<
string | undefined
>({
key: 'recordBoardObjectSingularNameStateScopeMap',
defaultValue: undefined,
});

View File

@ -0,0 +1,13 @@
import { recordBoardFieldDefinitionsStateScopeMap } from '@/object-record/record-board/states/recordBoardFieldDefinitionsStateScopeMap';
import { createSelectorScopeMap } from '@/ui/utilities/recoil-scope/utils/createSelectorScopeMap';
export const recordBoardVisibleFieldDefinitionsScopedSelector =
createSelectorScopeMap({
key: 'recordBoardVisibleFieldDefinitionsScopedSelector',
get:
({ scopeId }) =>
({ get }) =>
get(recordBoardFieldDefinitionsStateScopeMap({ scopeId }))
.filter((field) => field.isVisible)
.sort((a, b) => a.position - b.position),
});

View File

@ -28,7 +28,11 @@ export const RecordIndexBoardContainerEffect = ({
navigate(`/settings/objects/${objectMetadataItem.namePlural}`); navigate(`/settings/objects/${objectMetadataItem.namePlural}`);
}, [navigate, objectMetadataItem.namePlural]); }, [navigate, objectMetadataItem.namePlural]);
const { setColumns } = useRecordBoard(recordBoardId); const { setColumns, setObjectSingularName } = useRecordBoard(recordBoardId);
useEffect(() => {
setObjectSingularName(objectNameSingular);
}, [objectNameSingular, setObjectSingularName]);
useEffect(() => { useEffect(() => {
setColumns( setColumns(

View File

@ -10,10 +10,10 @@ import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSi
import { FieldDisplay } from '@/object-record/field/components/FieldDisplay'; import { FieldDisplay } from '@/object-record/field/components/FieldDisplay';
import { FieldContext } from '@/object-record/field/contexts/FieldContext'; import { FieldContext } from '@/object-record/field/contexts/FieldContext';
import { usePersistField } from '@/object-record/field/hooks/usePersistField'; import { usePersistField } from '@/object-record/field/hooks/usePersistField';
import { entityFieldsFamilyState } from '@/object-record/field/states/entityFieldsFamilyState';
import { FieldRelationMetadata } from '@/object-record/field/types/FieldMetadata'; import { FieldRelationMetadata } from '@/object-record/field/types/FieldMetadata';
import { useFieldContext } from '@/object-record/hooks/useFieldContext'; import { useFieldContext } from '@/object-record/hooks/useFieldContext';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { ObjectRecord } from '@/object-record/types/ObjectRecord'; import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { IconDotsVertical, IconUnlink } from '@/ui/display/icon'; import { IconDotsVertical, IconUnlink } from '@/ui/display/icon';
import { CardContent } from '@/ui/layout/card/components/CardContent'; import { CardContent } from '@/ui/layout/card/components/CardContent';
@ -100,7 +100,7 @@ export const RecordRelationFieldCardContent = ({
// TODO: temporary as ChipDisplay expect to find the entity in the entityFieldsFamilyState // TODO: temporary as ChipDisplay expect to find the entity in the entityFieldsFamilyState
const setRelationEntityFields = useSetRecoilState( const setRelationEntityFields = useSetRecoilState(
entityFieldsFamilyState(relationRecord.id), recordStoreFamilyState(relationRecord.id),
); );
useEffect(() => { useEffect(() => {

View File

@ -10,12 +10,12 @@ import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadata
import { parseFieldRelationType } from '@/object-metadata/utils/parseFieldRelationType'; import { parseFieldRelationType } from '@/object-metadata/utils/parseFieldRelationType';
import { FieldContext } from '@/object-record/field/contexts/FieldContext'; import { FieldContext } from '@/object-record/field/contexts/FieldContext';
import { usePersistField } from '@/object-record/field/hooks/usePersistField'; import { usePersistField } from '@/object-record/field/hooks/usePersistField';
import { entityFieldsFamilyState } from '@/object-record/field/states/entityFieldsFamilyState';
import { entityFieldsFamilySelector } from '@/object-record/field/states/selectors/entityFieldsFamilySelector';
import { FieldRelationMetadata } from '@/object-record/field/types/FieldMetadata'; import { FieldRelationMetadata } from '@/object-record/field/types/FieldMetadata';
import { useModifyRecordFromCache } from '@/object-record/hooks/useModifyRecordFromCache'; import { useModifyRecordFromCache } from '@/object-record/hooks/useModifyRecordFromCache';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import { RecordRelationFieldCardContent } from '@/object-record/record-relation-card/components/RecordRelationFieldCardContent'; import { RecordRelationFieldCardContent } from '@/object-record/record-relation-card/components/RecordRelationFieldCardContent';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { SingleEntitySelectMenuItemsWithSearch } from '@/object-record/relation-picker/components/SingleEntitySelectMenuItemsWithSearch'; import { SingleEntitySelectMenuItemsWithSearch } from '@/object-record/relation-picker/components/SingleEntitySelectMenuItemsWithSearch';
import { useRelationPicker } from '@/object-record/relation-picker/hooks/useRelationPicker'; import { useRelationPicker } from '@/object-record/relation-picker/hooks/useRelationPicker';
import { RelationPickerScope } from '@/object-record/relation-picker/scopes/RelationPickerScope'; import { RelationPickerScope } from '@/object-record/relation-picker/scopes/RelationPickerScope';
@ -91,7 +91,7 @@ export const RecordRelationFieldCardSection = () => {
relationType, relationType,
objectMetadataNameSingular, objectMetadataNameSingular,
} = fieldDefinition.metadata as FieldRelationMetadata; } = fieldDefinition.metadata as FieldRelationMetadata;
const record = useRecoilValue(entityFieldsFamilyState(entityId)); const record = useRecoilValue(recordStoreFamilyState(entityId));
const { const {
labelIdentifierFieldMetadata: relationLabelIdentifierFieldMetadata, labelIdentifierFieldMetadata: relationLabelIdentifierFieldMetadata,
@ -110,7 +110,7 @@ export const RecordRelationFieldCardSection = () => {
const fieldValue = useRecoilValue< const fieldValue = useRecoilValue<
({ id: string } & Record<string, any>) | null ({ id: string } & Record<string, any>) | null
>(entityFieldsFamilySelector({ entityId, fieldName })); >(recordStoreFamilySelector({ recordId: entityId, fieldName }));
const isToOneObject = relationType === 'TO_ONE_OBJECT'; const isToOneObject = relationType === 'TO_ONE_OBJECT';

View File

@ -10,13 +10,13 @@ import {
RecordUpdateHook, RecordUpdateHook,
RecordUpdateHookParams, RecordUpdateHookParams,
} from '@/object-record/field/contexts/FieldContext'; } from '@/object-record/field/contexts/FieldContext';
import { entityFieldsFamilyState } from '@/object-record/field/states/entityFieldsFamilyState';
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord'; import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell'; import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell';
import { PropertyBox } from '@/object-record/record-inline-cell/property-box/components/PropertyBox'; import { PropertyBox } from '@/object-record/record-inline-cell/property-box/components/PropertyBox';
import { InlineCellHotkeyScope } from '@/object-record/record-inline-cell/types/InlineCellHotkeyScope'; import { InlineCellHotkeyScope } from '@/object-record/record-inline-cell/types/InlineCellHotkeyScope';
import { RecordRelationFieldCardSection } from '@/object-record/record-relation-card/components/RecordRelationFieldCardSection'; import { RecordRelationFieldCardSection } from '@/object-record/record-relation-card/components/RecordRelationFieldCardSection';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { isFieldMetadataItemAvailable } from '@/object-record/utils/isFieldMetadataItemAvailable'; import { isFieldMetadataItemAvailable } from '@/object-record/utils/isFieldMetadataItemAvailable';
import { ShowPageContainer } from '@/ui/layout/page/ShowPageContainer'; import { ShowPageContainer } from '@/ui/layout/page/ShowPageContainer';
import { ShowPageLeftContainer } from '@/ui/layout/show-page/components/ShowPageLeftContainer'; import { ShowPageLeftContainer } from '@/ui/layout/show-page/components/ShowPageLeftContainer';
@ -48,7 +48,7 @@ export const RecordShowContainer = ({
}); });
const setEntityFields = useSetRecoilState( const setEntityFields = useSetRecoilState(
entityFieldsFamilyState(objectRecordId ?? ''), recordStoreFamilyState(objectRecordId),
); );
const { record, loading } = useFindOneRecord({ const { record, loading } = useFindOneRecord({

View File

@ -8,9 +8,9 @@ export const RecordTableActionBar = ({
}: { }: {
recordTableId: string; recordTableId: string;
}) => { }) => {
const { selectedRowIdsSelector } = useRecordTableStates(recordTableId); const { getSelectedRowIdsSelector } = useRecordTableStates(recordTableId);
const selectedRowIds = useRecoilValue(selectedRowIdsSelector); const selectedRowIds = useRecoilValue(getSelectedRowIdsSelector());
return <ActionBar selectedIds={selectedRowIds} />; return <ActionBar selectedIds={selectedRowIds} />;
}; };

View File

@ -56,17 +56,16 @@ export const RecordTableHeader = ({
}: { }: {
createRecord: () => void; createRecord: () => void;
}) => { }) => {
const { hiddenTableColumnsSelector, visibleTableColumnsSelector } = const { getHiddenTableColumnsSelector, getVisibleTableColumnsSelector } =
useRecordTableStates(); useRecordTableStates();
const hiddenTableColumns = useRecoilValue(hiddenTableColumnsSelector);
const scrollWrapper = useScrollWrapperScopedRef(); const scrollWrapper = useScrollWrapperScopedRef();
const isTableWiderThanScreen = const isTableWiderThanScreen =
(scrollWrapper.current?.clientWidth ?? 0) < (scrollWrapper.current?.clientWidth ?? 0) <
(scrollWrapper.current?.scrollWidth ?? 0); (scrollWrapper.current?.scrollWidth ?? 0);
const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector); const visibleTableColumns = useRecoilValue(getVisibleTableColumnsSelector());
const hiddenTableColumns = useRecoilValue(getHiddenTableColumnsSelector());
const theme = useTheme(); const theme = useTheme();

View File

@ -83,8 +83,8 @@ export const RecordTableHeaderCell = ({
const { const {
getResizeFieldOffsetState, getResizeFieldOffsetState,
getTableColumnsState, getTableColumnsState,
tableColumnsByKeySelector, getTableColumnsByKeySelector,
visibleTableColumnsSelector, getVisibleTableColumnsSelector,
} = useRecordTableStates(); } = useRecordTableStates();
const [resizeFieldOffset, setResizeFieldOffset] = useRecoilState( const [resizeFieldOffset, setResizeFieldOffset] = useRecoilState(
@ -92,8 +92,8 @@ export const RecordTableHeaderCell = ({
); );
const tableColumns = useRecoilValue(getTableColumnsState()); const tableColumns = useRecoilValue(getTableColumnsState());
const tableColumnsByKey = useRecoilValue(tableColumnsByKeySelector); const tableColumnsByKey = useRecoilValue(getTableColumnsByKeySelector());
const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector); const visibleTableColumns = useRecoilValue(getVisibleTableColumnsSelector());
const [initialPointerPositionX, setInitialPointerPositionX] = useState< const [initialPointerPositionX, setInitialPointerPositionX] = useState<
number | null number | null

View File

@ -18,9 +18,9 @@ import { ColumnDefinition } from '../types/ColumnDefinition';
export const RecordTableHeaderPlusButtonContent = () => { export const RecordTableHeaderPlusButtonContent = () => {
const { closeDropdown } = useDropdown(); const { closeDropdown } = useDropdown();
const { hiddenTableColumnsSelector } = useRecordTableStates(); const { getHiddenTableColumnsSelector } = useRecordTableStates();
const hiddenTableColumns = useRecoilValue(hiddenTableColumnsSelector); const hiddenTableColumns = useRecoilValue(getHiddenTableColumnsSelector());
const { getIcon } = useIcons(); const { getIcon } = useIcons();
const { handleColumnVisibilityChange } = useTableColumns(); const { handleColumnVisibilityChange } = useTableColumns();

View File

@ -26,9 +26,9 @@ const StyledPlaceholder = styled.td`
`; `;
export const RecordTableRow = ({ rowId }: RecordTableRowProps) => { export const RecordTableRow = ({ rowId }: RecordTableRowProps) => {
const { visibleTableColumnsSelector } = useRecordTableStates(); const { getVisibleTableColumnsSelector } = useRecordTableStates();
const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector); const visibleTableColumns = useRecoilValue(getVisibleTableColumnsSelector());
const { currentRowSelected } = useCurrentRowSelected(); const { currentRowSelected } = useCurrentRowSelected();

View File

@ -16,9 +16,11 @@ const StyledContainer = styled.div`
`; `;
export const SelectAllCheckbox = () => { export const SelectAllCheckbox = () => {
const { allRowsSelectedStatusSelector } = useRecordTableStates(); const { getAllRowsSelectedStatusSelector } = useRecordTableStates();
const allRowsSelectedStatus = useRecoilValue(allRowsSelectedStatusSelector); const allRowsSelectedStatus = useRecoilValue(
getAllRowsSelectedStatusSelector(),
);
const { selectAllRows } = useRecordTable(); const { selectAllRows } = useRecordTable();
const checked = allRowsSelectedStatus === 'all'; const checked = allRowsSelectedStatus === 'all';

View File

@ -8,9 +8,9 @@ export const RecordTableContextMenu = ({
}: { }: {
recordTableId: string; recordTableId: string;
}) => { }) => {
const { selectedRowIdsSelector } = useRecordTableStates(recordTableId); const { getSelectedRowIdsSelector } = useRecordTableStates(recordTableId);
const selectedRowIds = useRecoilValue(selectedRowIdsSelector); const selectedRowIds = useRecoilValue(getSelectedRowIdsSelector());
return <ContextMenu selectedIds={selectedRowIds} />; return <ContextMenu selectedIds={selectedRowIds} />;
}; };

View File

@ -94,27 +94,27 @@ export const useRecordTableStates = (recordTableId?: string) => {
isRowSelectedFamilyStateScopeMap, isRowSelectedFamilyStateScopeMap,
scopeId, scopeId,
), ),
allRowsSelectedStatusSelector: getSelector( getAllRowsSelectedStatusSelector: getSelector(
allRowsSelectedStatusSelectorScopeMap, allRowsSelectedStatusSelectorScopeMap,
scopeId, scopeId,
), ),
hiddenTableColumnsSelector: getSelector( getHiddenTableColumnsSelector: getSelector(
hiddenTableColumnsSelectorScopeMap, hiddenTableColumnsSelectorScopeMap,
scopeId, scopeId,
), ),
numberOfTableColumnsSelector: getSelector( getNumberOfTableColumnsSelector: getSelector(
numberOfTableColumnsSelectorScopeMap, numberOfTableColumnsSelectorScopeMap,
scopeId, scopeId,
), ),
selectedRowIdsSelector: getSelector( getSelectedRowIdsSelector: getSelector(
selectedRowIdsSelectorScopeMap, selectedRowIdsSelectorScopeMap,
scopeId, scopeId,
), ),
tableColumnsByKeySelector: getSelector( getTableColumnsByKeySelector: getSelector(
tableColumnsByKeySelectorScopeMap, tableColumnsByKeySelectorScopeMap,
scopeId, scopeId,
), ),
visibleTableColumnsSelector: getSelector( getVisibleTableColumnsSelector: getSelector(
visibleTableColumnsSelectorScopeMap, visibleTableColumnsSelectorScopeMap,
scopeId, scopeId,
), ),

View File

@ -5,7 +5,7 @@ import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotV
export const useSelectAllRows = (recordTableId?: string) => { export const useSelectAllRows = (recordTableId?: string) => {
const { const {
allRowsSelectedStatusSelector, getAllRowsSelectedStatusSelector,
getTableRowIdsState, getTableRowIdsState,
isRowSelectedFamilyState, isRowSelectedFamilyState,
} = useRecordTableStates(recordTableId); } = useRecordTableStates(recordTableId);
@ -15,7 +15,7 @@ export const useSelectAllRows = (recordTableId?: string) => {
() => { () => {
const allRowsSelectedStatus = getSnapshotValue( const allRowsSelectedStatus = getSnapshotValue(
snapshot, snapshot,
allRowsSelectedStatusSelector, getAllRowsSelectedStatusSelector(),
); );
const tableRowIds = getSnapshotValue(snapshot, getTableRowIdsState()); const tableRowIds = getSnapshotValue(snapshot, getTableRowIdsState());
@ -34,7 +34,7 @@ export const useSelectAllRows = (recordTableId?: string) => {
} }
}, },
[ [
allRowsSelectedStatusSelector, getAllRowsSelectedStatusSelector,
getTableRowIdsState, getTableRowIdsState,
isRowSelectedFamilyState, isRowSelectedFamilyState,
], ],

View File

@ -1,6 +1,6 @@
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
import { entityFieldsFamilyState } from '@/object-record/field/states/entityFieldsFamilyState'; import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates'; import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates';
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue'; import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
@ -23,11 +23,11 @@ export const useSetRecordTableData = ({
for (const entity of newEntityArray) { for (const entity of newEntityArray) {
// TODO: refactor with scoped state later // TODO: refactor with scoped state later
const currentEntity = snapshot const currentEntity = snapshot
.getLoadable(entityFieldsFamilyState(entity.id)) .getLoadable(recordStoreFamilyState(entity.id))
.valueOrThrow(); .valueOrThrow();
if (JSON.stringify(currentEntity) !== JSON.stringify(entity)) { if (JSON.stringify(currentEntity) !== JSON.stringify(entity)) {
set(entityFieldsFamilyState(entity.id), entity); set(recordStoreFamilyState(entity.id), entity);
} }
} }
const currentRowIds = getSnapshotValue(snapshot, getTableRowIdsState()); const currentRowIds = getSnapshotValue(snapshot, getTableRowIdsState());

View File

@ -40,8 +40,8 @@ export const useRecordTable = (props?: useRecordTableProps) => {
getOnColumnsChangeState, getOnColumnsChangeState,
getIsRecordTableInitialLoadingState, getIsRecordTableInitialLoadingState,
getTableLastRowVisibleState, getTableLastRowVisibleState,
numberOfTableColumnsSelector, getNumberOfTableColumnsSelector,
selectedRowIdsSelector, getSelectedRowIdsSelector,
} = useRecordTableStates(recordTableId); } = useRecordTableStates(recordTableId);
const setAvailableTableColumns = useSetRecoilState( const setAvailableTableColumns = useSetRecoilState(
@ -176,7 +176,7 @@ export const useRecordTable = (props?: useRecordTableProps) => {
const numberOfTableColumns = getSnapshotValue( const numberOfTableColumns = getSnapshotValue(
snapshot, snapshot,
numberOfTableColumnsSelector, getNumberOfTableColumnsSelector(),
); );
const numberOfTableRows = getSnapshotValue( const numberOfTableRows = getSnapshotValue(
@ -215,7 +215,7 @@ export const useRecordTable = (props?: useRecordTableProps) => {
}, },
[ [
getSoftFocusPositionState, getSoftFocusPositionState,
numberOfTableColumnsSelector, getNumberOfTableColumnsSelector,
getNumberOfTableRowsState, getNumberOfTableRowsState,
setSoftFocusPosition, setSoftFocusPosition,
], ],
@ -231,7 +231,7 @@ export const useRecordTable = (props?: useRecordTableProps) => {
const numberOfTableColumns = getSnapshotValue( const numberOfTableColumns = getSnapshotValue(
snapshot, snapshot,
numberOfTableColumnsSelector, getNumberOfTableColumnsSelector(),
); );
const currentColumnNumber = softFocusPosition.column; const currentColumnNumber = softFocusPosition.column;
@ -262,8 +262,8 @@ export const useRecordTable = (props?: useRecordTableProps) => {
} }
}, },
[ [
getNumberOfTableColumnsSelector,
getSoftFocusPositionState, getSoftFocusPositionState,
numberOfTableColumnsSelector,
setSoftFocusPosition, setSoftFocusPosition,
], ],
); );
@ -352,6 +352,6 @@ export const useRecordTable = (props?: useRecordTableProps) => {
setRecordTableLastRowVisible, setRecordTableLastRowVisible,
setSoftFocusPosition, setSoftFocusPosition,
isSomeCellInEditModeState, isSomeCellInEditModeState,
selectedRowIdsSelector, getSelectedRowIdsSelector,
}; };
}; };

View File

@ -20,13 +20,13 @@ export const useTableColumns = (props?: useRecordTableProps) => {
const { const {
getAvailableTableColumnsState, getAvailableTableColumnsState,
getTableColumnsState, getTableColumnsState,
visibleTableColumnsSelector, getVisibleTableColumnsSelector,
} = useRecordTableStates(props?.recordTableId); } = useRecordTableStates(props?.recordTableId);
const availableTableColumns = useRecoilValue(getAvailableTableColumnsState()); const availableTableColumns = useRecoilValue(getAvailableTableColumnsState());
const tableColumns = useRecoilValue(getTableColumnsState()); const tableColumns = useRecoilValue(getTableColumnsState());
const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector); const visibleTableColumns = useRecoilValue(getVisibleTableColumnsSelector());
const { handleColumnMove } = useMoveViewColumns(); const { handleColumnMove } = useMoveViewColumns();

View File

@ -42,11 +42,11 @@ export const TableOptionsDropdownContent = ({
const viewEditInputRef = useRef<HTMLInputElement>(null); const viewEditInputRef = useRef<HTMLInputElement>(null);
const { hiddenTableColumnsSelector, visibleTableColumnsSelector } = const { getHiddenTableColumnsSelector, getVisibleTableColumnsSelector } =
useRecordTableStates(recordTableId); useRecordTableStates(recordTableId);
const hiddenTableColumns = useRecoilValue(hiddenTableColumnsSelector); const hiddenTableColumns = useRecoilValue(getHiddenTableColumnsSelector());
const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector); const visibleTableColumns = useRecoilValue(getVisibleTableColumnsSelector());
const { handleColumnVisibilityChange, handleColumnReorder } = useTableColumns( const { handleColumnVisibilityChange, handleColumnReorder } = useTableColumns(
{ recordTableId }, { recordTableId },

View File

@ -1,7 +1,7 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import { useRecoilState } from 'recoil'; import { useSetRecoilState } from 'recoil';
import { entityFieldsFamilySelector } from '@/object-record/field/states/selectors/entityFieldsFamilySelector'; import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
type SettingsObjectFieldPreviewValueEffectProps = { type SettingsObjectFieldPreviewValueEffectProps = {
entityId: string; entityId: string;
@ -14,9 +14,9 @@ export const SettingsObjectFieldPreviewValueEffect = ({
fieldName, fieldName,
value, value,
}: SettingsObjectFieldPreviewValueEffectProps) => { }: SettingsObjectFieldPreviewValueEffectProps) => {
const [, setFieldValue] = useRecoilState( const setFieldValue = useSetRecoilState(
entityFieldsFamilySelector({ recordStoreFamilySelector({
entityId, recordId: entityId,
fieldName, fieldName,
}), }),
); );

View File

@ -8,5 +8,5 @@ export const getSelector = <StateType>(
) => RecoilValueReadOnly<StateType>, ) => RecoilValueReadOnly<StateType>,
scopeId: string, scopeId: string,
) => { ) => {
return stateScopeMap({ scopeId }); return () => stateScopeMap({ scopeId });
}; };

View File

@ -4,8 +4,8 @@ import { useSetRecoilState } from 'recoil';
import { useFavorites } from '@/favorites/hooks/useFavorites'; import { useFavorites } from '@/favorites/hooks/useFavorites';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { entityFieldsFamilyState } from '@/object-record/field/states/entityFieldsFamilyState';
import { RecordShowContainer } from '@/object-record/record-show/components/RecordShowContainer'; import { RecordShowContainer } from '@/object-record/record-show/components/RecordShowContainer';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { IconBuildingSkyscraper } from '@/ui/display/icon'; import { IconBuildingSkyscraper } from '@/ui/display/icon';
import { PageBody } from '@/ui/layout/page/PageBody'; import { PageBody } from '@/ui/layout/page/PageBody';
import { PageContainer } from '@/ui/layout/page/PageContainer'; import { PageContainer } from '@/ui/layout/page/PageContainer';
@ -39,7 +39,7 @@ export const RecordShowPage = () => {
const { favorites, createFavorite, deleteFavorite } = useFavorites(); const { favorites, createFavorite, deleteFavorite } = useFavorites();
const setEntityFields = useSetRecoilState( const setEntityFields = useSetRecoilState(
entityFieldsFamilyState(objectRecordId ?? ''), recordStoreFamilyState(objectRecordId),
); );
const { record } = useFindOneRecord({ const { record } = useFindOneRecord({

View File

@ -12,6 +12,12 @@ const getRandomProbability = () => {
const getRandomPipelineStepId = (pipelineStepIds: { id: string }[]) => const getRandomPipelineStepId = (pipelineStepIds: { id: string }[]) =>
pipelineStepIds[Math.floor(Math.random() * pipelineStepIds.length)].id; pipelineStepIds[Math.floor(Math.random() * pipelineStepIds.length)].id;
const getRandomStage = () => {
const stages = ['new', 'screening', 'meeting', 'proposal', 'customer'];
return stages[Math.floor(Math.random() * stages.length)];
};
const generateRandomAmountMicros = () => { const generateRandomAmountMicros = () => {
const firstDigit = Math.floor(Math.random() * 9) + 1; const firstDigit = Math.floor(Math.random() * 9) + 1;
@ -31,6 +37,7 @@ const generateOpportunities = (
amountAmountMicros: generateRandomAmountMicros(), amountAmountMicros: generateRandomAmountMicros(),
amountCurrencyCode: 'USD', amountCurrencyCode: 'USD',
closeDate: new Date(), closeDate: new Date(),
stage: getRandomStage(),
probability: getRandomProbability(), probability: getRandomProbability(),
pipelineStepId: getRandomPipelineStepId(pipelineStepIds), pipelineStepId: getRandomPipelineStepId(pipelineStepIds),
pointOfContactId: company.personId, pointOfContactId: company.personId,
@ -65,6 +72,7 @@ export const seedDemoOpportunity = async (
'amountAmountMicros', 'amountAmountMicros',
'amountCurrencyCode', 'amountCurrencyCode',
'closeDate', 'closeDate',
'stage',
'probability', 'probability',
'pipelineStepId', 'pipelineStepId',
'pointOfContactId', 'pointOfContactId',