Files
twenty/packages/twenty-server/test/integration/utils/view-test.util.ts
T
6aca1dd013 Introducing view field group syncable entity (#17867)
## Context
Introduces a new viewFieldGroup entity that allows grouping view fields
into sections (e.g. "General", "Additional", "Other") within a view.

The page layout fields widget needs a way to organize fields into
sections. Today, views have no concept of field grouping. This PR
introduces the viewFieldGroup entity which sits between a view and its
viewFields, enabling section-based organization.

<img width="401" height="724" alt="Layout - V2 (customize visibility)"
src="https://github.com/user-attachments/assets/6376e2ab-44db-42bf-9d2c-758f56f6b548"
/>

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-02-11 22:02:58 +01:00

127 lines
4.4 KiB
TypeScript

import { type ViewFieldGroupDTO } from 'src/engine/metadata-modules/view-field-group/dtos/view-field-group.dto';
import { type ViewFieldEntity } from 'src/engine/metadata-modules/view-field/entities/view-field.entity';
import { type ViewFilterGroupEntity } from 'src/engine/metadata-modules/view-filter-group/entities/view-filter-group.entity';
import { ViewFilterGroupLogicalOperator } from 'src/engine/metadata-modules/view-filter-group/enums/view-filter-group-logical-operator';
import { type ViewFilterEntity } from 'src/engine/metadata-modules/view-filter/entities/view-filter.entity';
import { type ViewGroupEntity } from 'src/engine/metadata-modules/view-group/entities/view-group.entity';
import { type ViewSortEntity } from 'src/engine/metadata-modules/view-sort/entities/view-sort.entity';
import { type ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
export const assertViewStructure = (
view: ViewEntity,
expectedFields?: Partial<ViewEntity>,
) => {
expect(view).toBeDefined();
expect(view.id).toBeDefined();
expect(view.name).toBeDefined();
expect(view.objectMetadataId).toBeDefined();
expect(view.workspaceId).toBeDefined();
expect(view.createdAt).toBeDefined();
expect(view.updatedAt).toBeDefined();
if (expectedFields) {
expect(view).toMatchObject(expectedFields);
}
};
export const assertViewFieldGroupStructure = (
viewFieldGroup: ViewFieldGroupDTO,
expectedFields?: Partial<ViewFieldGroupDTO>,
) => {
expect(viewFieldGroup).toBeDefined();
expect(viewFieldGroup.id).toBeDefined();
expect(viewFieldGroup.name).toBeDefined();
expect(viewFieldGroup.viewId).toBeDefined();
expect(typeof viewFieldGroup.position).toBe('number');
expect(typeof viewFieldGroup.isVisible).toBe('boolean');
if (expectedFields) {
expect(viewFieldGroup).toMatchObject(expectedFields);
}
};
export const assertViewFieldStructure = (
viewField: ViewFieldEntity,
expectedFields?: Partial<ViewFieldEntity>,
) => {
expect(viewField).toBeDefined();
expect(viewField.id).toBeDefined();
expect(viewField.fieldMetadataId).toBeDefined();
expect(viewField.viewId).toBeDefined();
expect(typeof viewField.position).toBe('number');
expect(typeof viewField.isVisible).toBe('boolean');
expect(typeof viewField.size).toBe('number');
if (expectedFields) {
expect(viewField).toMatchObject(expectedFields);
}
};
export const assertViewSortStructure = (
viewSort: ViewSortEntity,
expectedFields?: Partial<ViewSortEntity>,
) => {
expect(viewSort).toBeDefined();
expect(viewSort.id).toBeDefined();
expect(viewSort.fieldMetadataId).toBeDefined();
expect(viewSort.viewId).toBeDefined();
expect(viewSort.direction).toBeDefined();
expect(['ASC', 'DESC']).toContain(viewSort.direction);
if (expectedFields) {
expect(viewSort).toMatchObject(expectedFields);
}
};
export const assertViewFilterStructure = (
viewFilter: ViewFilterEntity,
expectedFields?: Partial<ViewFilterEntity>,
) => {
expect(viewFilter).toBeDefined();
expect(viewFilter.id).toBeDefined();
expect(viewFilter.fieldMetadataId).toBeDefined();
expect(viewFilter.viewId).toBeDefined();
expect(viewFilter.operand).toBeDefined();
expect(viewFilter.value).toBeDefined();
if (expectedFields) {
expect(viewFilter).toMatchObject(expectedFields);
}
};
export const assertViewGroupStructure = (
viewGroup: ViewGroupEntity,
expectedFields?: Partial<ViewGroupEntity>,
) => {
expect(viewGroup).toBeDefined();
expect(viewGroup.id).toBeDefined();
expect(viewGroup.viewId).toBeDefined();
expect(viewGroup.fieldValue).toBeDefined();
expect(typeof viewGroup.isVisible).toBe('boolean');
expect(typeof viewGroup.position).toBe('number');
if (expectedFields) {
expect(viewGroup).toMatchObject(expectedFields);
}
};
export const assertViewFilterGroupStructure = (
viewFilterGroup: ViewFilterGroupEntity,
expectedFields?: Partial<ViewFilterGroupEntity>,
validLogicalOperators: string[] = [
ViewFilterGroupLogicalOperator.AND,
ViewFilterGroupLogicalOperator.OR,
ViewFilterGroupLogicalOperator.NOT,
],
) => {
expect(viewFilterGroup).toBeDefined();
expect(viewFilterGroup.id).toBeDefined();
expect(viewFilterGroup.viewId).toBeDefined();
expect(viewFilterGroup.logicalOperator).toBeDefined();
expect(validLogicalOperators).toContain(viewFilterGroup.logicalOperator);
if (expectedFields) {
expect(viewFilterGroup).toMatchObject(expectedFields);
}
};