RICH_TEXT_V2 backend (#9848)
- Add RICH_TEXT_V2 composite type to backend. - Add `bodyV2` field to tasks and notes. - Minimum required frontend changes to avoid errors when creating a note [Testing instructions](https://github.com/twentyhq/twenty/pull/9690#issuecomment-2602378218) --------- Co-authored-by: ad-elias <elias@autodiligence.com> Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
@ -9,6 +9,7 @@ import { emailsCompositeType } from 'src/engine/metadata-modules/field-metadata/
|
||||
import { fullNameCompositeType } from 'src/engine/metadata-modules/field-metadata/composite-types/full-name.composite-type';
|
||||
import { linksCompositeType } from 'src/engine/metadata-modules/field-metadata/composite-types/links.composite-type';
|
||||
import { phonesCompositeType } from 'src/engine/metadata-modules/field-metadata/composite-types/phones.composite-type';
|
||||
import { richTextV2CompositeType } from 'src/engine/metadata-modules/field-metadata/composite-types/rich-text-v2.composite-type';
|
||||
|
||||
export const compositeTypeDefinitions = new Map<
|
||||
FieldMetadataType,
|
||||
@ -21,4 +22,5 @@ export const compositeTypeDefinitions = new Map<
|
||||
[FieldMetadataType.ACTOR, actorCompositeType],
|
||||
[FieldMetadataType.EMAILS, emailsCompositeType],
|
||||
[FieldMetadataType.PHONES, phonesCompositeType],
|
||||
[FieldMetadataType.RICH_TEXT_V2, richTextV2CompositeType],
|
||||
]);
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
import { FieldMetadataType } from 'twenty-shared';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { CompositeType } from 'src/engine/metadata-modules/field-metadata/interfaces/composite-type.interface';
|
||||
|
||||
export const richTextV2CompositeType: CompositeType = {
|
||||
type: FieldMetadataType.RICH_TEXT_V2,
|
||||
properties: [
|
||||
{
|
||||
name: 'blocknote',
|
||||
type: FieldMetadataType.TEXT,
|
||||
hidden: false,
|
||||
isRequired: false,
|
||||
},
|
||||
{
|
||||
name: 'markdown',
|
||||
type: FieldMetadataType.TEXT,
|
||||
hidden: false,
|
||||
isRequired: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const richTextV2ValueSchema = z.object({
|
||||
blocknote: z.string().nullable(),
|
||||
markdown: z.string().nullable(),
|
||||
});
|
||||
|
||||
export type RichTextV2Metadata = z.infer<typeof richTextV2ValueSchema>;
|
||||
@ -35,11 +35,22 @@ export class FieldMetadataDefaultValueRawJson {
|
||||
value: object | null;
|
||||
}
|
||||
|
||||
export class FieldMetadataDefaultValueRichTextV2 {
|
||||
@ValidateIf((object, value) => value !== null)
|
||||
@IsQuotedString()
|
||||
blocknote: string | null;
|
||||
|
||||
@ValidateIf((object, value) => value !== null)
|
||||
@IsQuotedString()
|
||||
markdown: string | null;
|
||||
}
|
||||
|
||||
export class FieldMetadataDefaultValueRichText {
|
||||
@ValidateIf((_object, value) => value !== null)
|
||||
@IsString()
|
||||
value: string | null;
|
||||
}
|
||||
|
||||
export class FieldMetadataDefaultValueNumber {
|
||||
@ValidateIf((object, value) => value !== null)
|
||||
@IsNumber()
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
import { FieldMetadataType } from 'twenty-shared';
|
||||
|
||||
import { computeCompositeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util';
|
||||
|
||||
describe('computeCompositeColumnName', () => {
|
||||
it('should compute composite column name for rich text v2 field', () => {
|
||||
const fieldMetadata = {
|
||||
name: 'bodyV2',
|
||||
type: FieldMetadataType.RICH_TEXT_V2,
|
||||
};
|
||||
|
||||
const property = {
|
||||
name: 'markdown',
|
||||
type: FieldMetadataType.TEXT,
|
||||
hidden: false,
|
||||
isRequired: false,
|
||||
};
|
||||
|
||||
expect(computeCompositeColumnName(fieldMetadata, property)).toEqual(
|
||||
'bodyV2Markdown',
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -47,6 +47,11 @@ export function generateDefaultValue(
|
||||
primaryPhoneCallingCode: "''",
|
||||
additionalPhones: null,
|
||||
};
|
||||
case FieldMetadataType.RICH_TEXT_V2:
|
||||
return {
|
||||
blocknote: "''",
|
||||
markdown: "''",
|
||||
};
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -9,7 +9,8 @@ export const isCompositeFieldMetadataType = (
|
||||
| FieldMetadataType.LINKS
|
||||
| FieldMetadataType.ACTOR
|
||||
| FieldMetadataType.EMAILS
|
||||
| FieldMetadataType.PHONES => {
|
||||
| FieldMetadataType.PHONES
|
||||
| FieldMetadataType.RICH_TEXT_V2 => {
|
||||
return [
|
||||
FieldMetadataType.CURRENCY,
|
||||
FieldMetadataType.FULL_NAME,
|
||||
@ -18,5 +19,6 @@ export const isCompositeFieldMetadataType = (
|
||||
FieldMetadataType.ACTOR,
|
||||
FieldMetadataType.EMAILS,
|
||||
FieldMetadataType.PHONES,
|
||||
FieldMetadataType.RICH_TEXT_V2,
|
||||
].includes(type);
|
||||
};
|
||||
|
||||
@ -21,6 +21,7 @@ import {
|
||||
FieldMetadataDefaultValueNumber,
|
||||
FieldMetadataDefaultValuePhones,
|
||||
FieldMetadataDefaultValueRawJson,
|
||||
FieldMetadataDefaultValueRichTextV2,
|
||||
FieldMetadataDefaultValueString,
|
||||
FieldMetadataDefaultValueStringArray,
|
||||
FieldMetadataDefaultValueUuidFunction,
|
||||
@ -47,6 +48,7 @@ export const defaultValueValidatorsMap = {
|
||||
[FieldMetadataType.SELECT]: [FieldMetadataDefaultValueString],
|
||||
[FieldMetadataType.MULTI_SELECT]: [FieldMetadataDefaultValueStringArray],
|
||||
[FieldMetadataType.ADDRESS]: [FieldMetadataDefaultValueAddress],
|
||||
[FieldMetadataType.RICH_TEXT_V2]: [FieldMetadataDefaultValueRichTextV2],
|
||||
[FieldMetadataType.RICH_TEXT]: [FieldMetadataDefaultValueString],
|
||||
[FieldMetadataType.RAW_JSON]: [FieldMetadataDefaultValueRawJson],
|
||||
[FieldMetadataType.LINKS]: [FieldMetadataDefaultValueLinks],
|
||||
|
||||
@ -26,7 +26,8 @@ export type CompositeFieldMetadataType =
|
||||
| FieldMetadataType.FULL_NAME
|
||||
| FieldMetadataType.LINKS
|
||||
| FieldMetadataType.EMAILS
|
||||
| FieldMetadataType.PHONES;
|
||||
| FieldMetadataType.PHONES
|
||||
| FieldMetadataType.RICH_TEXT_V2;
|
||||
|
||||
@Injectable()
|
||||
export class CompositeColumnActionFactory extends ColumnActionAbstractFactory<CompositeFieldMetadataType> {
|
||||
|
||||
@ -94,6 +94,10 @@ export class WorkspaceMigrationFactory {
|
||||
FieldMetadataType.TS_VECTOR,
|
||||
{ factory: this.tsVectorColumnActionFactory },
|
||||
],
|
||||
[
|
||||
FieldMetadataType.RICH_TEXT_V2,
|
||||
{ factory: this.compositeColumnActionFactory },
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user