Skip to content

Commit e61b666

Browse files
committed
Merge branch 'main' of github.com:twentyhq/twenty into update-blocknote
2 parents 41de5c4 + d212aed commit e61b666

File tree

172 files changed

+9132
-6879
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

172 files changed

+9132
-6879
lines changed

.yarn/releases/yarn-4.0.2.cjs

-893
This file was deleted.

.yarn/releases/yarn-4.3.1.cjs

+894
Large diffs are not rendered by default.

.yarnrc.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ enableInlineHunks: true
22

33
nodeLinker: node-modules
44

5-
yarnPath: .yarn/releases/yarn-4.0.2.cjs
5+
yarnPath: .yarn/releases/yarn-4.3.1.cjs

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@
348348
},
349349
"license": "AGPL-3.0",
350350
"name": "twenty",
351-
"packageManager": "yarn@4.0.2",
351+
"packageManager": "yarn@4.3.1",
352352
"resolutions": {
353353
"graphql": "16.8.0",
354354
"type-fest": "4.10.1",

packages/twenty-docker/twenty/entrypoint.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ if [ "${ENABLE_DB_MIGRATIONS}" = "true" ] && [ ! -f /app/docker-data/db_status ]
55
echo "Running database setup and migrations..."
66

77
# Run setup and migration scripts
8-
npx ts-node ./scripts/setup-db.ts
8+
NODE_OPTIONS="--max-old-space-size=1500" npx ts-node ./scripts/setup-db.ts
99
yarn database:migrate:prod
1010

1111
# Mark initialization as done

packages/twenty-front/src/hooks/useScrollRestoration.ts

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { scrollPositionState } from '@/ui/utilities/scroll/states/scrollPosition
77
import { isDefined } from '~/utils/isDefined';
88

99
/**
10+
* @deprecated We should now use useScrollToPosition instead
1011
* Note that `location.key` is used in the cache key, not `location.pathname`,
1112
* so the same path navigated to at different points in the history stack will
1213
* not share the same scroll position.

packages/twenty-front/src/modules/activities/timelineActivities/rows/main-object/components/EventFieldDiffValueEffect.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
55
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
66
import { useSetRecordValue } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
77
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
8+
import { isDefined } from 'twenty-ui';
89

910
export const EventFieldDiffValueEffect = ({
1011
diffArtificialRecordStoreId,
@@ -23,7 +24,7 @@ export const EventFieldDiffValueEffect = ({
2324
const setRecordValue = useSetRecordValue();
2425

2526
useEffect(() => {
26-
if (!diffRecord) return;
27+
if (!isDefined(diffRecord)) return;
2728

2829
const forgedObjectRecord = {
2930
__typename: mainObjectMetadataItem.nameSingular,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { FieldMetadataType } from '~/generated-metadata/graphql';
2+
3+
export const SORTABLE_FIELD_METADATA_TYPES = [
4+
FieldMetadataType.DateTime,
5+
FieldMetadataType.Date,
6+
FieldMetadataType.Number,
7+
FieldMetadataType.Text,
8+
FieldMetadataType.Boolean,
9+
FieldMetadataType.Select,
10+
FieldMetadataType.Phone,
11+
FieldMetadataType.Email,
12+
FieldMetadataType.FullName,
13+
FieldMetadataType.Rating,
14+
FieldMetadataType.Currency,
15+
];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
2+
import { useMemo } from 'react';
3+
4+
export const useActiveFieldMetadataItems = ({
5+
objectMetadataItem,
6+
}: {
7+
objectMetadataItem: ObjectMetadataItem;
8+
}) => {
9+
const activeFieldMetadataItems = useMemo(
10+
() =>
11+
objectMetadataItem
12+
? objectMetadataItem.fields.filter(
13+
({ isActive, isSystem }) => isActive && !isSystem,
14+
)
15+
: [],
16+
[objectMetadataItem],
17+
);
18+
19+
return { activeFieldMetadataItems };
20+
};

packages/twenty-front/src/modules/object-metadata/utils/formatFieldMetadataItemsAsSortDefinitions.ts

+2-15
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { SortDefinition } from '@/object-record/object-sort-dropdown/types/SortDefinition';
2-
import { FieldMetadataType } from '~/generated-metadata/graphql';
32

3+
import { SORTABLE_FIELD_METADATA_TYPES } from '@/object-metadata/constants/SortableFieldMetadataTypes';
44
import { ObjectMetadataItem } from '../types/ObjectMetadataItem';
55

66
export const formatFieldMetadataItemsAsSortDefinitions = ({
@@ -9,20 +9,7 @@ export const formatFieldMetadataItemsAsSortDefinitions = ({
99
fields: Array<ObjectMetadataItem['fields'][0]>;
1010
}): SortDefinition[] =>
1111
fields.reduce((acc, field) => {
12-
if (
13-
![
14-
FieldMetadataType.DateTime,
15-
FieldMetadataType.Date,
16-
FieldMetadataType.Number,
17-
FieldMetadataType.Text,
18-
FieldMetadataType.Boolean,
19-
FieldMetadataType.Select,
20-
FieldMetadataType.Phone,
21-
FieldMetadataType.Email,
22-
FieldMetadataType.FullName,
23-
FieldMetadataType.Rating,
24-
].includes(field.type)
25-
) {
12+
if (!SORTABLE_FIELD_METADATA_TYPES.includes(field.type)) {
2613
return acc;
2714
}
2815

packages/twenty-front/src/modules/object-metadata/utils/getObjectOrderByField.ts

+5-18
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
22
import { OrderBy } from '@/object-metadata/types/OrderBy';
33
import { getLabelIdentifierFieldMetadataItem } from '@/object-metadata/utils/getLabelIdentifierFieldMetadataItem';
4+
import { getOrderByForFieldMetadataType } from '@/object-metadata/utils/getOrderByForFieldMetadataType';
45
import { RecordGqlOperationOrderBy } from '@/object-record/graphql/types/RecordGqlOperationOrderBy';
5-
import { FieldMetadataType } from '~/generated-metadata/graphql';
66
import { isDefined } from '~/utils/isDefined';
77

88
export const getOrderByFieldForObjectMetadataItem = (
@@ -13,23 +13,10 @@ export const getOrderByFieldForObjectMetadataItem = (
1313
getLabelIdentifierFieldMetadataItem(objectMetadataItem);
1414

1515
if (isDefined(labelIdentifierFieldMetadata)) {
16-
switch (labelIdentifierFieldMetadata.type) {
17-
case FieldMetadataType.FullName:
18-
return [
19-
{
20-
[labelIdentifierFieldMetadata.name]: {
21-
firstName: orderBy ?? 'AscNullsLast',
22-
lastName: orderBy ?? 'AscNullsLast',
23-
},
24-
},
25-
];
26-
default:
27-
return [
28-
{
29-
[labelIdentifierFieldMetadata.name]: orderBy ?? 'AscNullsLast',
30-
},
31-
];
32-
}
16+
return getOrderByForFieldMetadataType(
17+
labelIdentifierFieldMetadata,
18+
orderBy,
19+
);
3320
} else {
3421
return [
3522
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
2+
import { OrderBy } from '@/object-metadata/types/OrderBy';
3+
import { RecordGqlOperationOrderBy } from '@/object-record/graphql/types/RecordGqlOperationOrderBy';
4+
import { FieldMetadataType } from '~/generated-metadata/graphql';
5+
6+
export const getOrderByForFieldMetadataType = (
7+
field: Pick<FieldMetadataItem, 'id' | 'name' | 'type'>,
8+
direction: OrderBy | null | undefined,
9+
): RecordGqlOperationOrderBy => {
10+
switch (field.type) {
11+
case FieldMetadataType.FullName:
12+
return [
13+
{
14+
[field.name]: {
15+
firstName: direction ?? 'AscNullsLast',
16+
lastName: direction ?? 'AscNullsLast',
17+
},
18+
},
19+
];
20+
case FieldMetadataType.Currency:
21+
return [
22+
{
23+
[field.name]: {
24+
amountMicros: direction ?? 'AscNullsLast',
25+
},
26+
},
27+
];
28+
default:
29+
return [
30+
{
31+
[field.name]: direction ?? 'AscNullsLast',
32+
},
33+
];
34+
}
35+
};

packages/twenty-front/src/modules/object-record/hooks/useFetchMoreRecordsWithPagination.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -209,15 +209,16 @@ export const useFetchMoreRecordsWithPagination = <
209209

210210
const totalCount = data?.[objectMetadataItem.namePlural]?.totalCount;
211211

212+
const recordConnection = data?.[objectMetadataItem.namePlural];
213+
212214
const records = useMemo(
213215
() =>
214-
data?.[objectMetadataItem.namePlural]
216+
isDefined(recordConnection)
215217
? getRecordsFromRecordConnection<T>({
216-
recordConnection: data?.[objectMetadataItem.namePlural],
218+
recordConnection,
217219
})
218-
: ([] as T[]),
219-
220-
[data, objectMetadataItem.namePlural],
220+
: [],
221+
[recordConnection],
221222
);
222223

223224
return {

packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownRatingInput.tsx

+7-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import { FieldRatingValue } from '@/object-record/record-field/types/FieldMetada
77
import { RatingInput } from '@/ui/field/input/components/RatingInput';
88
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
99

10-
const convertFieldRatingValueToNumber = (rating: FieldRatingValue): string => {
10+
const convertFieldRatingValueToNumber = (
11+
rating: Exclude<FieldRatingValue, null>,
12+
): string => {
1113
return rating.split('_')[1];
1214
};
1315

@@ -51,6 +53,10 @@ export const ObjectFilterDropdownRatingInput = () => {
5153
<RatingInput
5254
value={selectedFilter?.value as FieldRatingValue}
5355
onChange={(newValue: FieldRatingValue) => {
56+
if (!newValue) {
57+
return;
58+
}
59+
5460
selectFilter?.({
5561
id: selectedFilter?.id ? selectedFilter.id : v4(),
5662
fieldMetadataId: filterDefinitionUsedInDropdown.fieldMetadataId,

packages/twenty-front/src/modules/object-record/object-sort-dropdown/utils/turnSortsIntoOrderBy.ts

+13-22
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,23 @@ import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
22
import { OrderBy } from '@/object-metadata/types/OrderBy';
33
import { hasPositionField } from '@/object-metadata/utils/hasPositionField';
44
import { RecordGqlOperationOrderBy } from '@/object-record/graphql/types/RecordGqlOperationOrderBy';
5-
import { Field, FieldMetadataType } from '~/generated/graphql';
65
import { mapArrayToObject } from '~/utils/array/mapArrayToObject';
76
import { isDefined } from '~/utils/isDefined';
87
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
98

9+
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
10+
import { getOrderByForFieldMetadataType } from '@/object-metadata/utils/getOrderByForFieldMetadataType';
1011
import { Sort } from '../types/Sort';
1112

1213
export const turnSortsIntoOrderBy = (
1314
objectMetadataItem: ObjectMetadataItem,
1415
sorts: Sort[],
1516
): RecordGqlOperationOrderBy => {
16-
const fields: Pick<Field, 'id' | 'name' | 'type'>[] =
17+
const fields: Pick<FieldMetadataItem, 'id' | 'name' | 'type'>[] =
1718
objectMetadataItem?.fields ?? [];
19+
1820
const fieldsById = mapArrayToObject(fields, ({ id }) => id);
21+
1922
const sortsOrderBy = sorts
2023
.map((sort) => {
2124
const correspondingField = fieldsById[sort.fieldMetadataId];
@@ -32,26 +35,14 @@ export const turnSortsIntoOrderBy = (
3235
.filter(isDefined);
3336

3437
if (hasPositionField(objectMetadataItem)) {
35-
return [...sortsOrderBy, { position: 'AscNullsFirst' }];
36-
}
38+
const positionOrderBy = [
39+
{
40+
position: 'AscNullsFirst',
41+
},
42+
] satisfies RecordGqlOperationOrderBy;
3743

38-
return sortsOrderBy;
39-
};
40-
41-
const getOrderByForFieldMetadataType = (
42-
field: Pick<Field, 'id' | 'name' | 'type'>,
43-
direction: OrderBy,
44-
) => {
45-
switch (field.type) {
46-
case FieldMetadataType.FullName:
47-
return {
48-
[field.name]: {
49-
firstName: direction,
50-
lastName: direction,
51-
},
52-
};
53-
54-
default:
55-
return { [field.name]: direction };
44+
return [...sortsOrderBy, ...positionOrderBy].flat();
5645
}
46+
47+
return sortsOrderBy.flat();
5748
};

packages/twenty-front/src/modules/object-record/record-action-bar/hooks/useRecordActionBar.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,6 @@ export const useRecordActionBar = ({
136136
accent: 'danger',
137137
onClick: () => {
138138
setIsDeleteRecordsModalOpen(true);
139-
handleDeleteClick();
140139
},
141140
ConfirmationModal: (
142141
<ConfirmationModal

packages/twenty-front/src/modules/object-record/record-board/components/RecordBoard.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@ export type RecordBoardProps = {
2525

2626
const StyledContainer = styled.div`
2727
border-top: 1px solid ${({ theme }) => theme.border.color.light};
28+
overflow: auto;
2829
display: flex;
2930
flex: 1;
3031
flex-direction: row;
32+
min-height: calc(100% - 1px);
3133
`;
3234

3335
const StyledWrapper = styled.div`

packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
RecordUpdateHookParams,
1414
} from '@/object-record/record-field/contexts/FieldContext';
1515
import { getFieldButtonIcon } from '@/object-record/record-field/utils/getFieldButtonIcon';
16-
import { RecordIndexRecordChip } from '@/object-record/record-index/components/RecordIndexRecordChip';
16+
import { RecordIdentifierChip } from '@/object-record/record-index/components/RecordIndexRecordChip';
1717
import { RecordInlineCell } from '@/object-record/record-inline-cell/components/RecordInlineCell';
1818
import { InlineCellHotkeyScope } from '@/object-record/record-inline-cell/types/InlineCellHotkeyScope';
1919
import { RecordValueSetterEffect } from '@/object-record/record-store/components/RecordValueSetterEffect';
@@ -222,7 +222,7 @@ export const RecordBoardCard = () => {
222222
}}
223223
>
224224
<StyledBoardCardHeader showCompactView={isCompactModeActive}>
225-
<RecordIndexRecordChip
225+
<RecordIdentifierChip
226226
objectNameSingular={objectMetadataItem.nameSingular}
227227
record={record}
228228
variant={AvatarChipVariant.Transparent}

packages/twenty-front/src/modules/object-record/record-field/components/FieldDisplay.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import { BooleanFieldDisplay } from '@/object-record/record-field/meta-types/dis
44
import { LinksFieldDisplay } from '@/object-record/record-field/meta-types/display/components/LinksFieldDisplay';
55
import { RatingFieldDisplay } from '@/object-record/record-field/meta-types/display/components/RatingFieldDisplay';
66
import { RelationFromManyFieldDisplay } from '@/object-record/record-field/meta-types/display/components/RelationFromManyFieldDisplay';
7-
import { isFieldChipDisplay } from '@/object-record/record-field/meta-types/display/utils/isFieldChipDisplay';
7+
8+
import { isFieldIdentifierDisplay } from '@/object-record/record-field/meta-types/display/utils/isFieldIdentifierDisplay';
89
import { isFieldBoolean } from '@/object-record/record-field/types/guards/isFieldBoolean';
910
import { isFieldDisplayedAsPhone } from '@/object-record/record-field/types/guards/isFieldDisplayedAsPhone';
1011
import { isFieldLinks } from '@/object-record/record-field/types/guards/isFieldLinks';
@@ -46,7 +47,10 @@ import { isFieldUuid } from '../types/guards/isFieldUuid';
4647
export const FieldDisplay = () => {
4748
const { fieldDefinition, isLabelIdentifier } = useContext(FieldContext);
4849

49-
const isChipDisplay = isFieldChipDisplay(fieldDefinition, isLabelIdentifier);
50+
const isChipDisplay = isFieldIdentifierDisplay(
51+
fieldDefinition,
52+
isLabelIdentifier,
53+
);
5054

5155
return isChipDisplay ? (
5256
<ChipFieldDisplay />

packages/twenty-front/src/modules/object-record/record-field/meta-types/display/components/ChipFieldDisplay.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { RecordChip } from '@/object-record/components/RecordChip';
22
import { useChipFieldDisplay } from '@/object-record/record-field/meta-types/hooks/useChipFieldDisplay';
3-
import { RecordIndexRecordChip } from '@/object-record/record-index/components/RecordIndexRecordChip';
3+
import { RecordIdentifierChip } from '@/object-record/record-index/components/RecordIndexRecordChip';
44

55
export const ChipFieldDisplay = () => {
66
const { recordValue, objectNameSingular, isLabelIdentifier } =
@@ -11,7 +11,7 @@ export const ChipFieldDisplay = () => {
1111
}
1212

1313
return isLabelIdentifier ? (
14-
<RecordIndexRecordChip
14+
<RecordIdentifierChip
1515
objectNameSingular={objectNameSingular}
1616
record={recordValue}
1717
/>
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { isNonEmptyString } from '@sniptt/guards';
22

33
import { useFullNameFieldDisplay } from '@/object-record/record-field/meta-types/hooks/useFullNameFieldDisplay';
4-
import { TextDisplay } from '@/ui/field/display/components/TextDisplay';
4+
import { OverflowingTextWithTooltip } from 'twenty-ui';
55

66
export const FullNameFieldDisplay = () => {
77
const { fieldValue } = useFullNameFieldDisplay();
@@ -10,5 +10,5 @@ export const FullNameFieldDisplay = () => {
1010
.filter(isNonEmptyString)
1111
.join(' ');
1212

13-
return <TextDisplay text={content} />;
13+
return <OverflowingTextWithTooltip text={content} />;
1414
};

packages/twenty-front/src/modules/object-record/record-field/meta-types/display/components/TextFieldDisplay.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useTextFieldDisplay } from '@/object-record/record-field/meta-types/hoo
22
import { TextDisplay } from '@/ui/field/display/components/TextDisplay';
33

44
export const TextFieldDisplay = () => {
5-
const { fieldValue, maxWidth } = useTextFieldDisplay();
5+
const { fieldValue } = useTextFieldDisplay();
66

7-
return <TextDisplay text={fieldValue} maxWidth={maxWidth} />;
7+
return <TextDisplay text={fieldValue} />;
88
};

0 commit comments

Comments
 (0)