Introduce ARRAY field type (#6862)
This PR was created by \[GitStart\](<https://gitstart.com/>) to address the requirements from this ticket: \[TWNTY-6447\](<https://clients.gitstart.com/twenty/5449/tickets/TWNTY-6447>). This ticket was imported from: <https://github.com/twentyhq/twenty/issues/6447> ### Description \- We added a new field type ### Refs #6447 ### Demo <https://jam.dev/c/2b4d7853-ea89-4e9d-a561-6edcb4fdb34b> Fixes #6447 --------- Co-authored-by: gitstart-twenty <gitstart-twenty@users.noreply.github.com> Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
committed by
GitHub
parent
bc99cfec98
commit
8208a3e976
@ -230,6 +230,13 @@ const fieldEmailsMock = {
|
||||
defaultValue: [{ primaryEmail: '', additionalEmails: {} }],
|
||||
};
|
||||
|
||||
const fieldArrayMock = {
|
||||
name: 'fieldArray',
|
||||
type: FieldMetadataType.ARRAY,
|
||||
isNullable: true,
|
||||
defaultValue: null,
|
||||
};
|
||||
|
||||
const fieldPhonesMock = {
|
||||
name: FIELD_PHONES_MOCK_NAME,
|
||||
type: FieldMetadataType.PHONES,
|
||||
@ -267,6 +274,7 @@ export const fields = [
|
||||
fieldRawJsonMock,
|
||||
fieldRichTextMock,
|
||||
fieldActorMock,
|
||||
fieldArrayMock,
|
||||
];
|
||||
|
||||
export const objectMetadataItemMock = {
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
import { GraphQLInputObjectType, GraphQLList, GraphQLString } from 'graphql';
|
||||
|
||||
export const ArrayFilterType = new GraphQLInputObjectType({
|
||||
name: 'ArrayFilter',
|
||||
fields: {
|
||||
contains: { type: new GraphQLList(GraphQLString) },
|
||||
contains_any: { type: new GraphQLList(GraphQLString) },
|
||||
not_contains: { type: new GraphQLList(GraphQLString) },
|
||||
},
|
||||
});
|
||||
@ -1,3 +1,4 @@
|
||||
export * from './array-filter.input-type';
|
||||
export * from './big-float-filter.input-type';
|
||||
export * from './big-int-filter.input-type';
|
||||
export * from './boolean-filter.input-type';
|
||||
|
||||
@ -18,6 +18,7 @@ import { FieldMetadataSettings } from 'src/engine/metadata-modules/field-metadat
|
||||
|
||||
import { OrderByDirectionType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/enum';
|
||||
import {
|
||||
ArrayFilterType,
|
||||
BigFloatFilterType,
|
||||
BooleanFilterType,
|
||||
DateFilterType,
|
||||
@ -45,6 +46,8 @@ export interface TypeOptions<T = any> {
|
||||
isIdField?: boolean;
|
||||
}
|
||||
|
||||
const StringArrayScalarType = new GraphQLList(GraphQLString);
|
||||
|
||||
@Injectable()
|
||||
export class TypeMapperService {
|
||||
mapToScalarType(
|
||||
@ -55,7 +58,6 @@ export class TypeMapperService {
|
||||
if (isIdField || settings?.isForeignKey) {
|
||||
return GraphQLID;
|
||||
}
|
||||
|
||||
const typeScalarMapping = new Map<FieldMetadataType, GraphQLScalarType>([
|
||||
[FieldMetadataType.UUID, UUIDScalarType],
|
||||
[FieldMetadataType.TEXT, GraphQLString],
|
||||
@ -74,6 +76,10 @@ export class TypeMapperService {
|
||||
[FieldMetadataType.NUMERIC, BigFloatScalarType],
|
||||
[FieldMetadataType.POSITION, PositionScalarType],
|
||||
[FieldMetadataType.RAW_JSON, RawJSONScalar],
|
||||
[
|
||||
FieldMetadataType.ARRAY,
|
||||
StringArrayScalarType as unknown as GraphQLScalarType,
|
||||
],
|
||||
[FieldMetadataType.RICH_TEXT, GraphQLString],
|
||||
]);
|
||||
|
||||
@ -111,6 +117,7 @@ export class TypeMapperService {
|
||||
[FieldMetadataType.POSITION, FloatFilterType],
|
||||
[FieldMetadataType.RAW_JSON, RawJsonFilterType],
|
||||
[FieldMetadataType.RICH_TEXT, StringFilterType],
|
||||
[FieldMetadataType.ARRAY, ArrayFilterType],
|
||||
]);
|
||||
|
||||
return typeFilterMapping.get(fieldMetadataType);
|
||||
@ -135,6 +142,7 @@ export class TypeMapperService {
|
||||
[FieldMetadataType.POSITION, OrderByDirectionType],
|
||||
[FieldMetadataType.RAW_JSON, OrderByDirectionType],
|
||||
[FieldMetadataType.RICH_TEXT, OrderByDirectionType],
|
||||
[FieldMetadataType.ARRAY, OrderByDirectionType],
|
||||
]);
|
||||
|
||||
return typeOrderByMapping.get(fieldMetadataType);
|
||||
|
||||
@ -31,6 +31,7 @@ export const mapFieldMetadataToGraphqlQuery = (
|
||||
FieldMetadataType.POSITION,
|
||||
FieldMetadataType.RAW_JSON,
|
||||
FieldMetadataType.RICH_TEXT,
|
||||
FieldMetadataType.ARRAY,
|
||||
].includes(fieldType);
|
||||
|
||||
if (fieldIsSimpleValue) {
|
||||
|
||||
@ -70,6 +70,12 @@ describe('computeSchemaComponents', () => {
|
||||
type: 'string',
|
||||
format: 'date',
|
||||
},
|
||||
fieldArray: {
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
type: 'array',
|
||||
},
|
||||
fieldBoolean: {
|
||||
type: 'boolean',
|
||||
},
|
||||
@ -246,6 +252,12 @@ describe('computeSchemaComponents', () => {
|
||||
type: 'string',
|
||||
format: 'date',
|
||||
},
|
||||
fieldArray: {
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
type: 'array',
|
||||
},
|
||||
fieldBoolean: {
|
||||
type: 'boolean',
|
||||
},
|
||||
@ -421,6 +433,12 @@ describe('computeSchemaComponents', () => {
|
||||
type: 'string',
|
||||
format: 'date',
|
||||
},
|
||||
fieldArray: {
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
type: 'array',
|
||||
},
|
||||
fieldBoolean: {
|
||||
type: 'boolean',
|
||||
},
|
||||
|
||||
@ -17,8 +17,8 @@ import {
|
||||
FieldMetadataType,
|
||||
} from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { capitalize } from 'src/utils/capitalize';
|
||||
import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
|
||||
import { capitalize } from 'src/utils/capitalize';
|
||||
|
||||
type Property = OpenAPIV3_1.SchemaObject;
|
||||
|
||||
@ -124,6 +124,14 @@ const getSchemaComponentsProperties = ({
|
||||
enum: field.options.map((option: { value: string }) => option.value),
|
||||
};
|
||||
break;
|
||||
case FieldMetadataType.ARRAY:
|
||||
itemProperty = {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
};
|
||||
break;
|
||||
case FieldMetadataType.RATING:
|
||||
itemProperty = {
|
||||
type: 'string',
|
||||
|
||||
@ -46,6 +46,7 @@ export enum FieldMetadataType {
|
||||
RAW_JSON = 'RAW_JSON',
|
||||
RICH_TEXT = 'RICH_TEXT',
|
||||
ACTOR = 'ACTOR',
|
||||
ARRAY = 'ARRAY',
|
||||
}
|
||||
|
||||
@Entity('fieldMetadata')
|
||||
|
||||
@ -29,7 +29,8 @@ export type BasicFieldMetadataType =
|
||||
| FieldMetadataType.POSITION
|
||||
| FieldMetadataType.DATE_TIME
|
||||
| FieldMetadataType.DATE
|
||||
| FieldMetadataType.POSITION;
|
||||
| FieldMetadataType.POSITION
|
||||
| FieldMetadataType.ARRAY;
|
||||
|
||||
@Injectable()
|
||||
export class BasicColumnActionFactory extends ColumnActionAbstractFactory<BasicFieldMetadataType> {
|
||||
@ -48,6 +49,7 @@ export class BasicColumnActionFactory extends ColumnActionAbstractFactory<BasicF
|
||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||
columnName,
|
||||
columnType: fieldMetadataTypeToColumnType(fieldMetadata.type),
|
||||
isArray: fieldMetadata.type === FieldMetadataType.ARRAY,
|
||||
isNullable: fieldMetadata.isNullable ?? true,
|
||||
defaultValue: serializedDefaultValue,
|
||||
},
|
||||
@ -81,6 +83,7 @@ export class BasicColumnActionFactory extends ColumnActionAbstractFactory<BasicF
|
||||
currentColumnDefinition: {
|
||||
columnName: currentColumnName,
|
||||
columnType: fieldMetadataTypeToColumnType(currentFieldMetadata.type),
|
||||
isArray: currentFieldMetadata.type === FieldMetadataType.ARRAY,
|
||||
isNullable: currentFieldMetadata.isNullable ?? true,
|
||||
defaultValue: serializeDefaultValue(
|
||||
currentFieldMetadata.defaultValue,
|
||||
@ -89,6 +92,7 @@ export class BasicColumnActionFactory extends ColumnActionAbstractFactory<BasicF
|
||||
alteredColumnDefinition: {
|
||||
columnName: alteredColumnName,
|
||||
columnType: fieldMetadataTypeToColumnType(alteredFieldMetadata.type),
|
||||
isArray: alteredFieldMetadata.type === FieldMetadataType.ARRAY,
|
||||
isNullable: alteredFieldMetadata.isNullable ?? true,
|
||||
defaultValue: serializedDefaultValue,
|
||||
},
|
||||
|
||||
@ -16,6 +16,7 @@ export const fieldMetadataTypeToColumnType = <Type extends FieldMetadataType>(
|
||||
return 'uuid';
|
||||
case FieldMetadataType.TEXT:
|
||||
case FieldMetadataType.RICH_TEXT:
|
||||
case FieldMetadataType.ARRAY:
|
||||
return 'text';
|
||||
case FieldMetadataType.PHONE:
|
||||
case FieldMetadataType.EMAIL:
|
||||
|
||||
@ -97,6 +97,7 @@ export class WorkspaceMigrationFactory {
|
||||
],
|
||||
[FieldMetadataType.LINKS, { factory: this.compositeColumnActionFactory }],
|
||||
[FieldMetadataType.ACTOR, { factory: this.compositeColumnActionFactory }],
|
||||
[FieldMetadataType.ARRAY, { factory: this.basicColumnActionFactory }],
|
||||
[
|
||||
FieldMetadataType.EMAILS,
|
||||
{ factory: this.compositeColumnActionFactory },
|
||||
|
||||
Reference in New Issue
Block a user