Files v2 - Add new FILES field type (#17236)

In this PR : 
- New field type FieldMetadataType.FILES added (as jsonb in DB)
- Backend: GraphQL types, validation, REST API schema, data processor
handling
- Frontend: field configuration in settings
- Feature flag IS_FILES_FIELD_ENABLED to gate the feature
- Integration tests for create/filter validation
- Dev seed: Feature flag enabled + FILES field on survey result object


To do in next PRs : 
- Backend : 
-- new workspaceFile controller (for download) & new workspaceFile
upload resolver (for upload)
-- pre-hook/post-hook to ensure fileId existence + listener to ensure
cleaning
- Frontend : FILES field display/edit in table view, record, ...
This commit is contained in:
Etienne
2026-01-20 18:03:49 +01:00
committed by GitHub
parent 41329a0ea9
commit 30c13fc947
72 changed files with 2278 additions and 92 deletions
@@ -0,0 +1 @@
export const FILES_FIELD_MAX_NUMBER_OF_VALUES = 10;
@@ -17,6 +17,7 @@ export { DEFAULT_RELATIVE_DATE_FILTER_VALUE } from './DefaultRelativeDateFilterV
export { FIELD_FOR_TOTAL_COUNT_AGGREGATE_OPERATION } from './FieldForTotalCountAggregateOperation';
export { MAX_OPTIONS_TO_DISPLAY } from './FieldMetadataMaxOptionsToDisplay';
export { FIELD_RESTRICTED_ADDITIONAL_PERMISSIONS_REQUIRED } from './FieldRestrictedAdditionalPermissionsRequired';
export { FILES_FIELD_MAX_NUMBER_OF_VALUES } from './FilesFieldMaxNumberOfValues';
export { GROUP_BY_DATE_GRANULARITY_THAT_REQUIRE_TIME_ZONE } from './GroupByDateGranularityThatRequireTimeZone';
export { LABEL_IDENTIFIER_FIELD_METADATA_TYPES } from './LabelIdentifierFieldMetadataTypes';
export { MULTI_ITEM_FIELD_DEFAULT_MAX_VALUES } from './MultiItemFieldDefaultMaxValues';
@@ -1,9 +1,9 @@
import { type AllowedAddressSubField } from '@/types/AddressFieldsType';
import { type FieldMetadataMultiItemSettings } from '@/types/FieldMetadataMultiItemSettings';
import { type RelationType } from '@/types/RelationType';
import { type FieldMetadataType } from '@/types/FieldMetadataType';
import { type IsExactly } from '@/types/IsExactly';
import { type RelationOnDeleteAction } from '@/types/RelationOnDeleteAction.type';
import { type RelationType } from '@/types/RelationType';
export enum NumberDataType {
FLOAT = 'float',
@@ -46,6 +46,10 @@ export type FieldMetadataAddressSettings = {
subFields?: AllowedAddressSubField[];
};
export type FieldMetadataFilesSettings = {
maxNumberOfValues: number;
};
export type FieldMetadataTsVectorSettings = {
asExpression?: string;
generatedType?: 'STORED' | 'VIRTUAL';
@@ -64,6 +68,7 @@ type FieldMetadataSettingsMapping = {
[FieldMetadataType.EMAILS]: FieldMetadataMultiItemSettings | null;
[FieldMetadataType.LINKS]: FieldMetadataMultiItemSettings | null;
[FieldMetadataType.ARRAY]: FieldMetadataMultiItemSettings | null;
[FieldMetadataType.FILES]: FieldMetadataFilesSettings;
};
export type AllFieldMetadataSettings =
@@ -1,27 +1,28 @@
export enum FieldMetadataType {
UUID = 'UUID',
TEXT = 'TEXT',
PHONES = 'PHONES',
EMAILS = 'EMAILS',
DATE_TIME = 'DATE_TIME',
DATE = 'DATE',
ACTOR = 'ACTOR',
ADDRESS = 'ADDRESS',
ARRAY = 'ARRAY',
BOOLEAN = 'BOOLEAN',
CURRENCY = 'CURRENCY',
DATE = 'DATE',
DATE_TIME = 'DATE_TIME',
EMAILS = 'EMAILS',
FILES = 'FILES',
FULL_NAME = 'FULL_NAME',
LINKS = 'LINKS',
MORPH_RELATION = 'MORPH_RELATION',
MULTI_SELECT = 'MULTI_SELECT',
NUMBER = 'NUMBER',
NUMERIC = 'NUMERIC',
LINKS = 'LINKS',
CURRENCY = 'CURRENCY',
FULL_NAME = 'FULL_NAME',
RATING = 'RATING',
SELECT = 'SELECT',
MULTI_SELECT = 'MULTI_SELECT',
RELATION = 'RELATION',
MORPH_RELATION = 'MORPH_RELATION',
PHONES = 'PHONES',
POSITION = 'POSITION',
ADDRESS = 'ADDRESS',
RATING = 'RATING',
RAW_JSON = 'RAW_JSON',
RELATION = 'RELATION',
RICH_TEXT = 'RICH_TEXT',
RICH_TEXT_V2 = 'RICH_TEXT_V2',
ACTOR = 'ACTOR',
ARRAY = 'ARRAY',
SELECT = 'SELECT',
TEXT = 'TEXT',
TS_VECTOR = 'TS_VECTOR',
UUID = 'UUID',
}
@@ -0,0 +1,12 @@
export const FILE_CATEGORIES = {
ARCHIVE: 'ARCHIVE',
AUDIO: 'AUDIO',
IMAGE: 'IMAGE',
PRESENTATION: 'PRESENTATION',
SPREADSHEET: 'SPREADSHEET',
TEXT_DOCUMENT: 'TEXT_DOCUMENT',
VIDEO: 'VIDEO',
OTHER: 'OTHER',
} as const;
export type FileCategory = keyof typeof FILE_CATEGORIES;
@@ -101,6 +101,7 @@ export type {
FieldMetadataDateTimeSettings,
FieldMetadataRelationSettings,
FieldMetadataAddressSettings,
FieldMetadataFilesSettings,
FieldMetadataTsVectorSettings,
AllFieldMetadataSettings,
FieldMetadataSettings,
@@ -108,6 +109,8 @@ export type {
export { NumberDataType, DateDisplayFormat } from './FieldMetadataSettings';
export { FieldMetadataType } from './FieldMetadataType';
export type { FieldRatingValue } from './FieldRatingValue';
export type { FileCategory } from './FileCategory';
export { FILE_CATEGORIES } from './FileCategory';
export { FileFolder } from './FileFolder';
export type {
FilterableFieldType,