Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78403581ae | ||
|
|
7da89c5267 | ||
|
|
4c2a2dbd4a | ||
|
|
0313464931 |
+15
-5
@@ -1,5 +1,5 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useStore } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { useRecordIndexTableLazyQuery } from '@/object-record/record-index/hooks/useRecordIndexTableLazyQuery';
|
||||
import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector';
|
||||
@@ -17,20 +17,20 @@ import { useReapplyRowSelection } from '@/object-record/record-table/virtualizat
|
||||
|
||||
import { useResetTableFocuses } from '@/object-record/record-table/virtualization/hooks/useResetTableFocuses';
|
||||
import { useResetVirtualizedRowTreadmill } from '@/object-record/record-table/virtualization/hooks/useResetVirtualizedRowTreadmill';
|
||||
import { dataLoadingStatusByRealIndexComponentState } from '@/object-record/record-table/virtualization/states/dataLoadingStatusByRealIndexComponentState';
|
||||
import { dataPagesLoadedComponentState } from '@/object-record/record-table/virtualization/states/dataPagesLoadedComponentState';
|
||||
import { isInitializingVirtualTableDataLoadingComponentState } from '@/object-record/record-table/virtualization/states/isInitializingVirtualTableDataLoadingComponentState';
|
||||
import { lastRealIndexSetComponentState } from '@/object-record/record-table/virtualization/states/lastRealIndexSetComponentState';
|
||||
import { lastScrollPositionComponentState } from '@/object-record/record-table/virtualization/states/lastScrollPositionComponentState';
|
||||
import { recordIdByRealIndexComponentState } from '@/object-record/record-table/virtualization/states/recordIdByRealIndexComponentState';
|
||||
import { scrollAtRealIndexComponentState } from '@/object-record/record-table/virtualization/states/scrollAtRealIndexComponentState';
|
||||
import { totalNumberOfRecordsToVirtualizeComponentState } from '@/object-record/record-table/virtualization/states/totalNumberOfRecordsToVirtualizeComponentState';
|
||||
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { SIGN_IN_BACKGROUND_MOCK_COMPANIES } from '@/sign-in-background-mock/constants/SignInBackgroundMockCompanies';
|
||||
import { useShowAuthModal } from '@/ui/layout/hooks/useShowAuthModal';
|
||||
import { useAtomComponentStateCallbackState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateCallbackState';
|
||||
import { dataLoadingStatusByRealIndexComponentState } from '@/object-record/record-table/virtualization/states/dataLoadingStatusByRealIndexComponentState';
|
||||
import { recordIdByRealIndexComponentState } from '@/object-record/record-table/virtualization/states/recordIdByRealIndexComponentState';
|
||||
import { useSetAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useSetAtomComponentState';
|
||||
import { useAtomComponentSelectorCallbackState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorCallbackState';
|
||||
import { useAtomComponentStateCallbackState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateCallbackState';
|
||||
import { useSetAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useSetAtomComponentState';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useTriggerInitialRecordTableDataLoad = () => {
|
||||
@@ -62,6 +62,11 @@ export const useTriggerInitialRecordTableDataLoad = () => {
|
||||
|
||||
const store = useStore();
|
||||
|
||||
// const recordIndexRecordIdsByGroupFamilyState =
|
||||
// useAtomComponentFamilyStateCallbackState(
|
||||
// recordIndexRecordIdsByGroupComponentFamilyState,
|
||||
// );
|
||||
|
||||
const recordIdByRealIndexCallbackState = useAtomComponentStateCallbackState(
|
||||
recordIdByRealIndexComponentState,
|
||||
);
|
||||
@@ -165,6 +170,11 @@ export const useTriggerInitialRecordTableDataLoad = () => {
|
||||
newDataLoadingStatusByRealIndex,
|
||||
);
|
||||
|
||||
// store.set(
|
||||
// recordIndexRecordIdsByGroupFamilyState(NO_RECORD_GROUP_FAMILY_KEY),
|
||||
// [],
|
||||
// );
|
||||
|
||||
const { records: findManyRecords, totalCount: findManyTotalCount } =
|
||||
await findManyRecordsLazy();
|
||||
|
||||
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
import { defaultMergeFieldValue } from 'src/engine/api/graphql/graphql-query-runner/utils/default-merge-field-value.util';
|
||||
|
||||
describe('defaultMergeFieldValue', () => {
|
||||
it('should return priority record value when available', () => {
|
||||
const recordsWithValues = [
|
||||
{
|
||||
recordId: '1',
|
||||
value: 'priority value',
|
||||
},
|
||||
{
|
||||
recordId: '2',
|
||||
value: 'other value',
|
||||
},
|
||||
];
|
||||
|
||||
const result = defaultMergeFieldValue(recordsWithValues, '1');
|
||||
|
||||
expect(result).toBe('priority value');
|
||||
});
|
||||
|
||||
it('should fall back to first record with value when priority record not found', () => {
|
||||
const recordsWithValues = [
|
||||
{
|
||||
recordId: '2',
|
||||
value: 'first value',
|
||||
},
|
||||
{
|
||||
recordId: '3',
|
||||
value: 'second value',
|
||||
},
|
||||
];
|
||||
|
||||
const result = defaultMergeFieldValue(recordsWithValues, '1');
|
||||
|
||||
expect(result).toBe('first value');
|
||||
});
|
||||
|
||||
it('should fall back to other record when priority record has null value', () => {
|
||||
const recordsWithValues = [
|
||||
{
|
||||
recordId: '1',
|
||||
value: null,
|
||||
},
|
||||
{
|
||||
recordId: '2',
|
||||
value: 'fallback value',
|
||||
},
|
||||
];
|
||||
|
||||
const result = defaultMergeFieldValue(recordsWithValues, '1');
|
||||
|
||||
expect(result).toBe('fallback value');
|
||||
});
|
||||
|
||||
it('should fall back to other record when priority record has empty string', () => {
|
||||
const recordsWithValues = [
|
||||
{
|
||||
recordId: '1',
|
||||
value: '',
|
||||
},
|
||||
{
|
||||
recordId: '2',
|
||||
value: 'fallback value',
|
||||
},
|
||||
];
|
||||
|
||||
const result = defaultMergeFieldValue(recordsWithValues, '1');
|
||||
|
||||
expect(result).toBe('fallback value');
|
||||
});
|
||||
|
||||
it('should fall back to other record when priority record has undefined value', () => {
|
||||
const recordsWithValues = [
|
||||
{
|
||||
recordId: '1',
|
||||
value: undefined,
|
||||
},
|
||||
{
|
||||
recordId: '2',
|
||||
value: 'fallback value',
|
||||
},
|
||||
];
|
||||
|
||||
const result = defaultMergeFieldValue(recordsWithValues, '1');
|
||||
|
||||
expect(result).toBe('fallback value');
|
||||
});
|
||||
|
||||
it('should return null when no records exist', () => {
|
||||
const result = defaultMergeFieldValue([], '1');
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it('should return null when no record has a value', () => {
|
||||
const recordsWithValues = [
|
||||
{
|
||||
recordId: '1',
|
||||
value: null,
|
||||
},
|
||||
{
|
||||
recordId: '2',
|
||||
value: '',
|
||||
},
|
||||
];
|
||||
|
||||
const result = defaultMergeFieldValue(recordsWithValues, '1');
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it('should handle complex object values', () => {
|
||||
const recordsWithValues = [
|
||||
{
|
||||
recordId: '1',
|
||||
value: { name: 'priority object', id: 1 },
|
||||
},
|
||||
{
|
||||
recordId: '2',
|
||||
value: { name: 'fallback object', id: 2 },
|
||||
},
|
||||
];
|
||||
|
||||
const result = defaultMergeFieldValue(recordsWithValues, '1');
|
||||
|
||||
expect(result).toEqual({ name: 'priority object', id: 1 });
|
||||
});
|
||||
});
|
||||
+9
-10
@@ -21,20 +21,19 @@ describe('mergeFieldValues', () => {
|
||||
expect(result).toBe('value2');
|
||||
});
|
||||
|
||||
it('should throw error when priority record is not found', () => {
|
||||
const recordsWithoutPriorityValue = [
|
||||
it('should fall back to first record with value when priority record is not found', () => {
|
||||
const recordsWithValues = [
|
||||
{ value: 'value1', recordId: 'record1' },
|
||||
{ value: null, recordId: PRIORITY_RECORD_ID },
|
||||
{ value: 'value3', recordId: 'record3' },
|
||||
];
|
||||
|
||||
expect(() =>
|
||||
mergeFieldValues(
|
||||
FieldMetadataType.TEXT,
|
||||
recordsWithoutPriorityValue,
|
||||
'non-existent-id',
|
||||
),
|
||||
).toThrow('Priority record with ID non-existent-id not found');
|
||||
const result = mergeFieldValues(
|
||||
FieldMetadataType.TEXT,
|
||||
recordsWithValues,
|
||||
'non-existent-id',
|
||||
);
|
||||
|
||||
expect(result).toBe('value1');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
-111
@@ -1,111 +0,0 @@
|
||||
import { selectPriorityFieldValue } from 'src/engine/api/graphql/graphql-query-runner/utils/select-priority-field-value.util';
|
||||
|
||||
describe('selectPriorityFieldValue', () => {
|
||||
it('should return priority record value when available', () => {
|
||||
const recordsWithValues = [
|
||||
{
|
||||
recordId: '1',
|
||||
value: 'priority value',
|
||||
},
|
||||
{
|
||||
recordId: '2',
|
||||
value: 'other value',
|
||||
},
|
||||
];
|
||||
|
||||
const result = selectPriorityFieldValue(recordsWithValues, '1');
|
||||
|
||||
expect(result).toBe('priority value');
|
||||
});
|
||||
|
||||
it('should throw error when priority record not found', () => {
|
||||
const recordsWithValues = [
|
||||
{
|
||||
recordId: '2',
|
||||
value: 'first value',
|
||||
},
|
||||
{
|
||||
recordId: '3',
|
||||
value: 'second value',
|
||||
},
|
||||
];
|
||||
|
||||
expect(() => selectPriorityFieldValue(recordsWithValues, '1')).toThrow(
|
||||
'Priority record with ID 1 not found in merge candidates',
|
||||
);
|
||||
});
|
||||
|
||||
it('should return null when priority record has no value', () => {
|
||||
const recordsWithValues = [
|
||||
{
|
||||
recordId: '1',
|
||||
value: null,
|
||||
},
|
||||
{
|
||||
recordId: '2',
|
||||
value: 'fallback value',
|
||||
},
|
||||
];
|
||||
|
||||
const result = selectPriorityFieldValue(recordsWithValues, '1');
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it('should return null when priority record has empty string', () => {
|
||||
const recordsWithValues = [
|
||||
{
|
||||
recordId: '1',
|
||||
value: '',
|
||||
},
|
||||
{
|
||||
recordId: '2',
|
||||
value: 'fallback value',
|
||||
},
|
||||
];
|
||||
|
||||
const result = selectPriorityFieldValue(recordsWithValues, '1');
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it('should return null when priority record has undefined value', () => {
|
||||
const recordsWithValues = [
|
||||
{
|
||||
recordId: '1',
|
||||
value: undefined,
|
||||
},
|
||||
{
|
||||
recordId: '2',
|
||||
value: 'fallback value',
|
||||
},
|
||||
];
|
||||
|
||||
const result = selectPriorityFieldValue(recordsWithValues, '1');
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it('should throw error when no records exist', () => {
|
||||
expect(() => selectPriorityFieldValue([], '1')).toThrow(
|
||||
'Priority record with ID 1 not found in merge candidates',
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle complex object values', () => {
|
||||
const recordsWithValues = [
|
||||
{
|
||||
recordId: '1',
|
||||
value: { name: 'priority object', id: 1 },
|
||||
},
|
||||
{
|
||||
recordId: '2',
|
||||
value: { name: 'fallback object', id: 2 },
|
||||
},
|
||||
];
|
||||
|
||||
const result = selectPriorityFieldValue(recordsWithValues, '1');
|
||||
|
||||
expect(result).toEqual({ name: 'priority object', id: 1 });
|
||||
});
|
||||
});
|
||||
+9
-7
@@ -2,7 +2,7 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { hasRecordFieldValue } from 'src/engine/api/graphql/graphql-query-runner/utils/has-record-field-value.util';
|
||||
|
||||
export const selectPriorityFieldValue = <T>(
|
||||
export const defaultMergeFieldValue = <T>(
|
||||
recordsWithValues: { value: T; recordId: string }[],
|
||||
priorityRecordId: string,
|
||||
): T | null => {
|
||||
@@ -10,14 +10,16 @@ export const selectPriorityFieldValue = <T>(
|
||||
(record) => record.recordId === priorityRecordId,
|
||||
);
|
||||
|
||||
if (!isDefined(priorityRecord)) {
|
||||
throw new Error(
|
||||
`Priority record with ID ${priorityRecordId} not found in merge candidates`,
|
||||
);
|
||||
if (isDefined(priorityRecord) && hasRecordFieldValue(priorityRecord.value)) {
|
||||
return priorityRecord.value;
|
||||
}
|
||||
|
||||
if (hasRecordFieldValue(priorityRecord.value)) {
|
||||
return priorityRecord.value;
|
||||
const fallbackRecord = recordsWithValues.find((record) =>
|
||||
hasRecordFieldValue(record.value),
|
||||
);
|
||||
|
||||
if (fallbackRecord) {
|
||||
return fallbackRecord.value;
|
||||
}
|
||||
|
||||
return null;
|
||||
+4
-4
@@ -1,9 +1,9 @@
|
||||
import {
|
||||
FieldMetadataType,
|
||||
type RelationType,
|
||||
type EmailsMetadata,
|
||||
type LinksMetadata,
|
||||
type PhonesMetadata,
|
||||
type RelationType,
|
||||
} from 'twenty-shared/types';
|
||||
|
||||
import { mergeArrayFieldValues } from './merge-array-field-values.util';
|
||||
@@ -11,7 +11,7 @@ import { mergeEmailsFieldValues } from './merge-emails-field-values.util';
|
||||
import { mergeLinksFieldValues } from './merge-links-field-values.util';
|
||||
import { mergePhonesFieldValues } from './merge-phones-field-values.util';
|
||||
import { mergeRelationFieldValuesForDryRunRecord } from './merge-relation-field-values-for-dry-run-record.util';
|
||||
import { selectPriorityFieldValue } from './select-priority-field-value.util';
|
||||
import { defaultMergeFieldValue } from './default-merge-field-value.util';
|
||||
|
||||
export const mergeFieldValues = (
|
||||
fieldType: FieldMetadataType,
|
||||
@@ -34,7 +34,7 @@ export const mergeFieldValues = (
|
||||
);
|
||||
}
|
||||
|
||||
return selectPriorityFieldValue(recordsWithValues, priorityRecordId);
|
||||
return defaultMergeFieldValue(recordsWithValues, priorityRecordId);
|
||||
|
||||
case FieldMetadataType.EMAILS:
|
||||
return mergeEmailsFieldValues(
|
||||
@@ -55,6 +55,6 @@ export const mergeFieldValues = (
|
||||
);
|
||||
|
||||
default:
|
||||
return selectPriorityFieldValue(recordsWithValues, priorityRecordId);
|
||||
return defaultMergeFieldValue(recordsWithValues, priorityRecordId);
|
||||
}
|
||||
};
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { type ObjectRecord, RelationType } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { selectPriorityFieldValue } from 'src/engine/api/graphql/graphql-query-runner/utils/select-priority-field-value.util';
|
||||
import { defaultMergeFieldValue } from 'src/engine/api/graphql/graphql-query-runner/utils/default-merge-field-value.util';
|
||||
|
||||
export const mergeRelationFieldValuesForDryRunRecord = (
|
||||
recordsWithValues: { value: unknown; recordId: string }[],
|
||||
@@ -12,7 +12,7 @@ export const mergeRelationFieldValuesForDryRunRecord = (
|
||||
return mergeOneToManyRelationArrays(recordsWithValues);
|
||||
}
|
||||
|
||||
return selectPriorityFieldValue(
|
||||
return defaultMergeFieldValue(
|
||||
recordsWithValues as { value: ObjectRecord | null; recordId: string }[],
|
||||
priorityRecordId,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user