Sync views and navigation items (#18003)

Both objects are necessary to fully enjoy objects within applications

<img width="770" height="311" alt="Capture d’écran 2026-02-17 à 15 19
43"
src="https://github.com/user-attachments/assets/48c51fa4-63f4-45b2-a40a-df73f3aa79be"
/>
This commit is contained in:
Thomas Trompette
2026-02-17 16:32:41 +01:00
committed by GitHub
parent 63a3f93a78
commit b4e924b671
134 changed files with 1029 additions and 180 deletions
@@ -139,7 +139,8 @@ export const triggerUpdateRecordOptimisticEffect = ({
if (
rootQueryNextEdgesShouldBeSorted &&
Object.getOwnPropertyNames(rootQueryOrderBy).length > 0
Array.isArray(rootQueryOrderBy) &&
rootQueryOrderBy.length > 0
) {
rootQueryNextEdges = sortCachedObjectEdges({
edges: rootQueryNextEdges,
@@ -409,6 +409,8 @@ export const EXPECTED_MANIFEST: Manifest = {
universalIdentifier: 'b648f87b-1d26-4961-b974-0908fd991061',
},
],
views: [],
navigationMenuItems: [],
logicFunctions: [
{
builtHandlerChecksum: '[checksum]',
@@ -139,6 +139,8 @@ export const EXPECTED_MANIFEST: Manifest = {
builtComponentChecksum: '[checksum]',
},
],
views: [],
navigationMenuItems: [],
roles: [
{
universalIdentifier: 'e1e2e3e4-e5e6-4000-8000-000000000040',
@@ -32,6 +32,8 @@ const validManifest: Manifest = {
logicFunctions: [],
roles: [],
publicAssets: [],
views: [],
navigationMenuItems: [],
};
describe('manifestValidate', () => {
@@ -11,6 +11,7 @@ import {
type LogicFunctionConfig,
} from '@/sdk';
import { type ObjectConfig } from '@/sdk/objects/object-config';
import { type ViewConfig } from '@/sdk/views/view-config';
import { glob } from 'fast-glob';
import { readFile } from 'fs-extra';
import { basename, extname, relative } from 'path';
@@ -22,8 +23,10 @@ import {
type FrontComponentManifest,
type LogicFunctionManifest,
type Manifest,
type NavigationMenuItemManifest,
type ObjectManifest,
type RoleManifest,
type ViewManifest,
} from 'twenty-shared/application';
import { getInputSchemaFromSourceCode } from 'twenty-shared/logic-function';
import { assertUnreachable } from 'twenty-shared/utils';
@@ -62,6 +65,8 @@ export const buildManifest = async (
const logicFunctions: LogicFunctionManifest[] = [];
const frontComponents: FrontComponentManifest[] = [];
const publicAssets: AssetManifest[] = [];
const views: ViewManifest[] = [];
const navigationMenuItems: NavigationMenuItemManifest[] = [];
const applicationFilePaths: string[] = [];
const objectsFilePaths: string[] = [];
@@ -70,6 +75,8 @@ export const buildManifest = async (
const logicFunctionsFilePaths: string[] = [];
const frontComponentsFilePaths: string[] = [];
const publicAssetsFilePaths: string[] = [];
const viewsFilePaths: string[] = [];
const navigationMenuItemsFilePaths: string[] = [];
for (const filePath of filePaths) {
const fileContent = await readFile(filePath, 'utf-8');
@@ -206,6 +213,32 @@ export const buildManifest = async (
frontComponentsFilePaths.push(relativePath);
break;
}
case ManifestEntityKey.Views: {
const extract = await extractManifestFromFile<ViewConfig>({
appPath,
filePath,
});
const viewManifest: ViewManifest = {
...extract.config,
};
views.push(viewManifest);
errors.push(...extract.errors);
viewsFilePaths.push(relativePath);
break;
}
case ManifestEntityKey.NavigationMenuItems: {
const extract =
await extractManifestFromFile<NavigationMenuItemManifest>({
appPath,
filePath,
});
navigationMenuItems.push(extract.config);
errors.push(...extract.errors);
navigationMenuItemsFilePaths.push(relativePath);
break;
}
case ManifestEntityKey.PublicAssets: {
// Public assets are handled below
break;
@@ -244,6 +277,8 @@ export const buildManifest = async (
logicFunctions,
frontComponents,
publicAssets,
views,
navigationMenuItems,
};
const entityFilePaths: EntityFilePaths = {
@@ -254,6 +289,8 @@ export const buildManifest = async (
logicFunctions: logicFunctionsFilePaths,
frontComponents: frontComponentsFilePaths,
publicAssets: publicAssetsFilePaths,
views: viewsFilePaths,
navigationMenuItems: navigationMenuItemsFilePaths,
};
return { manifest, filePaths: entityFilePaths, errors };
@@ -7,6 +7,8 @@ export enum TargetFunction {
DefineObject = 'defineObject',
DefineRole = 'defineRole',
DefineFrontComponent = 'defineFrontComponent',
DefineView = 'defineView',
DefineNavigationMenuItem = 'defineNavigationMenuItem',
}
export enum ManifestEntityKey {
@@ -17,6 +19,8 @@ export enum ManifestEntityKey {
Roles = 'roles',
FrontComponents = 'frontComponents',
PublicAssets = 'publicAssets',
Views = 'views',
NavigationMenuItems = 'navigationMenuItems',
}
export type EntityFilePaths = Record<ManifestEntityKey, string[]>;
@@ -31,6 +35,9 @@ export const TARGET_FUNCTION_TO_ENTITY_KEY_MAPPING: Record<
[TargetFunction.DefineObject]: ManifestEntityKey.Objects,
[TargetFunction.DefineRole]: ManifestEntityKey.Roles,
[TargetFunction.DefineFrontComponent]: ManifestEntityKey.FrontComponents,
[TargetFunction.DefineView]: ManifestEntityKey.Views,
[TargetFunction.DefineNavigationMenuItem]:
ManifestEntityKey.NavigationMenuItems,
};
const computeIsTargetFunctionCall = (node: ts.Node): string | undefined => {
@@ -2,8 +2,10 @@ import { type ApplicationConfig } from '@/sdk/application/application-config';
import { type FrontComponentConfig } from '@/sdk/front-component-config';
import { type LogicFunctionConfig } from '@/sdk/logic-functions/logic-function-config';
import { type ObjectConfig } from '@/sdk/objects/object-config';
import { type ViewConfig } from '@/sdk/views/view-config';
import {
type FieldManifest,
type NavigationMenuItemManifest,
type RoleManifest,
} from 'twenty-shared/application';
@@ -19,7 +21,9 @@ export type DefinableEntity =
| FieldManifest
| FrontComponentConfig
| LogicFunctionConfig
| RoleManifest;
| RoleManifest
| ViewConfig
| NavigationMenuItemManifest;
export type DefineEntity<T extends DefinableEntity = DefinableEntity> = (
config: T,
+3
View File
@@ -45,10 +45,13 @@ export type {
ObjectRecordUpsertEvent,
} from './logic-functions/triggers/database-event-payload-type';
export type { RoutePayload } from './logic-functions/triggers/route-payload-type';
export { defineNavigationMenuItem } from './navigation-menu-items/define-navigation-menu-item';
export { defineObject } from './objects/define-object';
export { STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS } from './objects/standard-object-ids';
export { defineRole } from './roles/define-role';
export { PermissionFlag } from './roles/permission-flag-type';
export { defineView } from './views/define-view';
export type { ViewConfig } from './views/view-config';
// Front Component API exports
export {
@@ -0,0 +1,19 @@
import { type DefineEntity } from '@/sdk/common/types/define-entity.type';
import { createValidationResult } from '@/sdk/common/utils/create-validation-result';
import { type NavigationMenuItemManifest } from 'twenty-shared/application';
export const defineNavigationMenuItem: DefineEntity<
NavigationMenuItemManifest
> = (config) => {
const errors: string[] = [];
if (!config.universalIdentifier) {
errors.push('NavigationMenuItem must have a universalIdentifier');
}
if (typeof config.position !== 'number') {
errors.push('NavigationMenuItem must have a position');
}
return createValidationResult({ config, errors });
};
@@ -0,0 +1,67 @@
import { type DefineEntity } from '@/sdk/common/types/define-entity.type';
import { createValidationResult } from '@/sdk/common/utils/create-validation-result';
import { type ViewConfig } from '@/sdk/views/view-config';
export const defineView: DefineEntity<ViewConfig> = (config) => {
const errors: string[] = [];
if (!config.universalIdentifier) {
errors.push('View must have a universalIdentifier');
}
if (!config.name) {
errors.push('View must have a name');
}
if (!config.objectUniversalIdentifier) {
errors.push('View must have an objectUniversalIdentifier');
}
if (config.fields) {
for (const field of config.fields) {
if (!field.universalIdentifier) {
errors.push('ViewField must have a universalIdentifier');
}
if (!field.fieldMetadataUniversalIdentifier) {
errors.push('ViewField must have a fieldMetadataUniversalIdentifier');
}
}
}
if (config.filters) {
for (const filter of config.filters) {
if (!filter.universalIdentifier) {
errors.push('ViewFilter must have a universalIdentifier');
}
if (!filter.fieldMetadataUniversalIdentifier) {
errors.push('ViewFilter must have a fieldMetadataUniversalIdentifier');
}
}
}
if (config.filterGroups) {
for (const filterGroup of config.filterGroups) {
if (!filterGroup.universalIdentifier) {
errors.push('ViewFilterGroup must have a universalIdentifier');
}
}
}
if (config.groups) {
for (const group of config.groups) {
if (!group.universalIdentifier) {
errors.push('ViewGroup must have a universalIdentifier');
}
}
}
if (config.fieldGroups) {
for (const fieldGroup of config.fieldGroups) {
if (!fieldGroup.universalIdentifier) {
errors.push('ViewFieldGroup must have a universalIdentifier');
}
}
}
return createValidationResult({ config, errors });
};
@@ -0,0 +1,3 @@
import { type ViewManifest } from 'twenty-shared/application';
export type ViewConfig = ViewManifest;
@@ -1,6 +1,4 @@
import { FieldMetadataType } from 'twenty-shared/types';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { AggregateOperations, FieldMetadataType } from 'twenty-shared/types';
export const computeIsNumericReturningAggregate = (
operation: AggregateOperations,
@@ -1,6 +1,6 @@
import { AggregateOperations } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { type AggregationField } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-available-aggregations-from-object-fields.util';
import { type WorkspaceSelectQueryBuilder } from 'src/engine/twenty-orm/repository/workspace-select-query-builder';
import { formatColumnNamesFromCompositeFieldAndSubfields } from 'src/engine/twenty-orm/utils/format-column-names-from-composite-field-and-subfield.util';
@@ -16,6 +16,7 @@ import {
} from 'graphql';
import GraphQLJSON from 'graphql-type-json';
import {
AggregateOperations,
type FieldMetadataSettings,
FieldMetadataType,
NumberDataType,
@@ -23,7 +24,6 @@ import {
} from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { OrderByDirectionType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/enum';
import {
ArrayFilterType,
@@ -2,10 +2,9 @@ import { GraphQLISODateTime } from '@nestjs/graphql';
import { GraphQLFloat, GraphQLInt, type GraphQLScalarType } from 'graphql';
import { FIELD_FOR_TOTAL_COUNT_AGGREGATE_OPERATION } from 'twenty-shared/constants';
import { FieldMetadataType } from 'twenty-shared/types';
import { AggregateOperations, FieldMetadataType } from 'twenty-shared/types';
import { capitalize, isFieldMetadataDateKind } from 'twenty-shared/utils';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { getSubfieldsForAggregateOperation } from 'src/engine/twenty-orm/utils/get-subfields-for-aggregate-operation.util';
@@ -6,6 +6,13 @@ export const APPLICATION_MANIFEST_METADATA_NAMES = [
'logicFunction',
'frontComponent',
'role',
'view',
'viewField',
'viewFieldGroup',
'viewFilter',
'viewFilterGroup',
'viewGroup',
'navigationMenuItem',
] as const satisfies AllMetadataName[];
export type ApplicationManifestMetadataName =
@@ -0,0 +1,53 @@
import { fromNavigationMenuItemManifestToUniversalFlatNavigationMenuItem } from 'src/engine/core-modules/application/utils/from-navigation-menu-item-manifest-to-universal-flat-navigation-menu-item.util';
describe('fromNavigationMenuItemManifestToUniversalFlatNavigationMenuItem', () => {
const now = '2026-01-01T00:00:00.000Z';
const applicationUniversalIdentifier = 'app-uuid-1';
it('should convert a minimal navigation menu item manifest', () => {
const result =
fromNavigationMenuItemManifestToUniversalFlatNavigationMenuItem({
navigationMenuItemManifest: {
universalIdentifier: 'nav-uuid-1',
position: 0,
},
applicationUniversalIdentifier,
now,
});
expect(result.universalIdentifier).toBe('nav-uuid-1');
expect(result.applicationUniversalIdentifier).toBe(
applicationUniversalIdentifier,
);
expect(result.position).toBe(0);
expect(result.name).toBeNull();
expect(result.viewUniversalIdentifier).toBeNull();
expect(result.link).toBeNull();
expect(result.folderUniversalIdentifier).toBeNull();
expect(result.targetObjectMetadataUniversalIdentifier).toBeNull();
expect(result.targetRecordId).toBeNull();
expect(result.userWorkspaceId).toBeNull();
});
it('should convert a fully specified navigation menu item manifest', () => {
const result =
fromNavigationMenuItemManifestToUniversalFlatNavigationMenuItem({
navigationMenuItemManifest: {
universalIdentifier: 'nav-uuid-2',
name: 'Recipes Board',
position: 1,
viewUniversalIdentifier: 'view-uuid-1',
folderUniversalIdentifier: 'nav-folder-uuid-1',
targetObjectUniversalIdentifier: 'obj-uuid-1',
},
applicationUniversalIdentifier,
now,
});
expect(result.name).toBe('Recipes Board');
expect(result.position).toBe(1);
expect(result.viewUniversalIdentifier).toBe('view-uuid-1');
expect(result.folderUniversalIdentifier).toBe('nav-folder-uuid-1');
expect(result.targetObjectMetadataUniversalIdentifier).toBe('obj-uuid-1');
});
});
@@ -0,0 +1,54 @@
import { AggregateOperations } from 'twenty-shared/types';
import { fromViewFieldManifestToUniversalFlatViewField } from 'src/engine/core-modules/application/utils/from-view-field-manifest-to-universal-flat-view-field.util';
describe('fromViewFieldManifestToUniversalFlatViewField', () => {
const now = '2026-01-01T00:00:00.000Z';
const applicationUniversalIdentifier = 'app-uuid-1';
const viewUniversalIdentifier = 'view-uuid-1';
it('should convert a view field manifest with defaults', () => {
const result = fromViewFieldManifestToUniversalFlatViewField({
viewFieldManifest: {
universalIdentifier: 'vf-uuid-1',
fieldMetadataUniversalIdentifier: 'field-uuid-1',
position: 0,
},
viewUniversalIdentifier,
applicationUniversalIdentifier,
now,
});
expect(result.universalIdentifier).toBe('vf-uuid-1');
expect(result.fieldMetadataUniversalIdentifier).toBe('field-uuid-1');
expect(result.viewUniversalIdentifier).toBe(viewUniversalIdentifier);
expect(result.isVisible).toBe(true);
expect(result.size).toBe(0);
expect(result.position).toBe(0);
expect(result.aggregateOperation).toBeNull();
expect(result.viewFieldGroupUniversalIdentifier).toBeNull();
});
it('should respect explicit values', () => {
const result = fromViewFieldManifestToUniversalFlatViewField({
viewFieldManifest: {
universalIdentifier: 'vf-uuid-2',
fieldMetadataUniversalIdentifier: 'field-uuid-2',
position: 5,
isVisible: false,
size: 200,
aggregateOperation: AggregateOperations.COUNT,
viewFieldGroupUniversalIdentifier: 'vfg-uuid-1',
},
viewUniversalIdentifier,
applicationUniversalIdentifier,
now,
});
expect(result.isVisible).toBe(false);
expect(result.size).toBe(200);
expect(result.position).toBe(5);
expect(result.aggregateOperation).toBe(AggregateOperations.COUNT);
expect(result.viewFieldGroupUniversalIdentifier).toBe('vfg-uuid-1');
});
});
@@ -0,0 +1,53 @@
import { ViewFilterOperand } from 'twenty-shared/types';
import { fromViewFilterManifestToUniversalFlatViewFilter } from 'src/engine/core-modules/application/utils/from-view-filter-manifest-to-universal-flat-view-filter.util';
describe('fromViewFilterManifestToUniversalFlatViewFilter', () => {
const now = '2026-01-01T00:00:00.000Z';
const applicationUniversalIdentifier = 'app-uuid-1';
const viewUniversalIdentifier = 'view-uuid-1';
it('should convert a view filter manifest with defaults', () => {
const result = fromViewFilterManifestToUniversalFlatViewFilter({
viewFilterManifest: {
universalIdentifier: 'vfilter-uuid-1',
fieldMetadataUniversalIdentifier: 'field-uuid-1',
operand: ViewFilterOperand.CONTAINS,
value: 'test',
},
viewUniversalIdentifier,
applicationUniversalIdentifier,
now,
});
expect(result.universalIdentifier).toBe('vfilter-uuid-1');
expect(result.fieldMetadataUniversalIdentifier).toBe('field-uuid-1');
expect(result.viewUniversalIdentifier).toBe(viewUniversalIdentifier);
expect(result.operand).toBe(ViewFilterOperand.CONTAINS);
expect(result.value).toBe('test');
expect(result.subFieldName).toBeNull();
expect(result.viewFilterGroupUniversalIdentifier).toBeNull();
expect(result.positionInViewFilterGroup).toBeNull();
});
it('should respect explicit optional values', () => {
const result = fromViewFilterManifestToUniversalFlatViewFilter({
viewFilterManifest: {
universalIdentifier: 'vfilter-uuid-2',
fieldMetadataUniversalIdentifier: 'field-uuid-2',
operand: ViewFilterOperand.IS,
value: ['a', 'b'],
subFieldName: 'city',
viewFilterGroupUniversalIdentifier: 'vfg-uuid-1',
positionInViewFilterGroup: 2,
},
viewUniversalIdentifier,
applicationUniversalIdentifier,
now,
});
expect(result.subFieldName).toBe('city');
expect(result.viewFilterGroupUniversalIdentifier).toBe('vfg-uuid-1');
expect(result.positionInViewFilterGroup).toBe(2);
});
});
@@ -0,0 +1,66 @@
import {
ViewOpenRecordIn,
ViewType,
ViewVisibility,
} from 'twenty-shared/types';
import { fromViewManifestToUniversalFlatView } from 'src/engine/core-modules/application/utils/from-view-manifest-to-universal-flat-view.util';
describe('fromViewManifestToUniversalFlatView', () => {
const now = '2026-01-01T00:00:00.000Z';
const applicationUniversalIdentifier = 'app-uuid-1';
it('should convert a minimal view manifest to universal flat view', () => {
const result = fromViewManifestToUniversalFlatView({
viewManifest: {
universalIdentifier: 'view-uuid-1',
name: 'All Records',
objectUniversalIdentifier: 'object-uuid-1',
},
applicationUniversalIdentifier,
now,
});
expect(result.universalIdentifier).toBe('view-uuid-1');
expect(result.applicationUniversalIdentifier).toBe(
applicationUniversalIdentifier,
);
expect(result.name).toBe('All Records');
expect(result.objectMetadataUniversalIdentifier).toBe('object-uuid-1');
expect(result.type).toBe(ViewType.TABLE);
expect(result.icon).toBe('IconList');
expect(result.position).toBe(0);
expect(result.isCompact).toBe(false);
expect(result.isCustom).toBe(true);
expect(result.visibility).toBe(ViewVisibility.WORKSPACE);
expect(result.openRecordIn).toBe(ViewOpenRecordIn.SIDE_PANEL);
expect(result.key).toBeNull();
expect(result.createdAt).toBe(now);
expect(result.updatedAt).toBe(now);
});
it('should respect explicit values from the manifest', () => {
const result = fromViewManifestToUniversalFlatView({
viewManifest: {
universalIdentifier: 'view-uuid-2',
name: 'Kanban Board',
objectUniversalIdentifier: 'object-uuid-1',
type: ViewType.KANBAN,
icon: 'IconLayoutKanban',
position: 3,
isCompact: true,
visibility: ViewVisibility.UNLISTED,
openRecordIn: ViewOpenRecordIn.RECORD_PAGE,
},
applicationUniversalIdentifier,
now,
});
expect(result.type).toBe(ViewType.KANBAN);
expect(result.icon).toBe('IconLayoutKanban');
expect(result.position).toBe(3);
expect(result.isCompact).toBe(true);
expect(result.visibility).toBe(ViewVisibility.UNLISTED);
expect(result.openRecordIn).toBe(ViewOpenRecordIn.RECORD_PAGE);
});
});
@@ -4,8 +4,15 @@ import { type ApplicationManifestMetadataName } from 'src/engine/core-modules/ap
import { fromFieldManifestToUniversalFlatFieldMetadata } from 'src/engine/core-modules/application/utils/from-field-manifest-to-universal-flat-field-metadata.util';
import { fromFrontComponentManifestToUniversalFlatFrontComponent } from 'src/engine/core-modules/application/utils/from-front-component-manifest-to-universal-flat-front-component.util';
import { fromLogicFunctionManifestToUniversalFlatLogicFunction } from 'src/engine/core-modules/application/utils/from-logic-function-manifest-to-universal-flat-logic-function.util';
import { fromNavigationMenuItemManifestToUniversalFlatNavigationMenuItem } from 'src/engine/core-modules/application/utils/from-navigation-menu-item-manifest-to-universal-flat-navigation-menu-item.util';
import { fromObjectManifestToUniversalFlatObjectMetadata } from 'src/engine/core-modules/application/utils/from-object-manifest-to-universal-flat-object-metadata.util';
import { fromRoleManifestToUniversalFlatRole } from 'src/engine/core-modules/application/utils/from-role-manifest-to-universal-flat-role.util';
import { fromViewFieldGroupManifestToUniversalFlatViewFieldGroup } from 'src/engine/core-modules/application/utils/from-view-field-group-manifest-to-universal-flat-view-field-group.util';
import { fromViewFieldManifestToUniversalFlatViewField } from 'src/engine/core-modules/application/utils/from-view-field-manifest-to-universal-flat-view-field.util';
import { fromViewFilterGroupManifestToUniversalFlatViewFilterGroup } from 'src/engine/core-modules/application/utils/from-view-filter-group-manifest-to-universal-flat-view-filter-group.util';
import { fromViewFilterManifestToUniversalFlatViewFilter } from 'src/engine/core-modules/application/utils/from-view-filter-manifest-to-universal-flat-view-filter.util';
import { fromViewGroupManifestToUniversalFlatViewGroup } from 'src/engine/core-modules/application/utils/from-view-group-manifest-to-universal-flat-view-group.util';
import { fromViewManifestToUniversalFlatView } from 'src/engine/core-modules/application/utils/from-view-manifest-to-universal-flat-view.util';
import { getEmptyApplicationManifestAllUniversalFlatEntityMaps } from 'src/engine/core-modules/application/utils/get-empty-application-manifest-all-universal-flat-entity-maps.util';
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
import { type MetadataToFlatEntityMapsKey } from 'src/engine/metadata-modules/flat-entity/types/metadata-to-flat-entity-maps-key';
@@ -123,5 +130,111 @@ export const computeApplicationManifestAllUniversalFlatEntityMaps = ({
);
}
for (const viewManifest of manifest.views ?? []) {
addUniversalFlatEntityToUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow(
{
metadataName: 'view',
universalFlatEntity: fromViewManifestToUniversalFlatView({
viewManifest,
applicationUniversalIdentifier,
now,
}),
universalFlatEntityAndRelatedMapsToMutate: allUniversalFlatEntityMaps,
},
);
for (const viewFieldGroupManifest of viewManifest.fieldGroups ?? []) {
addUniversalFlatEntityToUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow(
{
metadataName: 'viewFieldGroup',
universalFlatEntity:
fromViewFieldGroupManifestToUniversalFlatViewFieldGroup({
viewFieldGroupManifest,
viewUniversalIdentifier: viewManifest.universalIdentifier,
applicationUniversalIdentifier,
now,
}),
universalFlatEntityAndRelatedMapsToMutate: allUniversalFlatEntityMaps,
},
);
}
for (const viewFieldManifest of viewManifest.fields ?? []) {
addUniversalFlatEntityToUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow(
{
metadataName: 'viewField',
universalFlatEntity: fromViewFieldManifestToUniversalFlatViewField({
viewFieldManifest,
viewUniversalIdentifier: viewManifest.universalIdentifier,
applicationUniversalIdentifier,
now,
}),
universalFlatEntityAndRelatedMapsToMutate: allUniversalFlatEntityMaps,
},
);
}
for (const viewFilterGroupManifest of viewManifest.filterGroups ?? []) {
addUniversalFlatEntityToUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow(
{
metadataName: 'viewFilterGroup',
universalFlatEntity:
fromViewFilterGroupManifestToUniversalFlatViewFilterGroup({
viewFilterGroupManifest,
viewUniversalIdentifier: viewManifest.universalIdentifier,
applicationUniversalIdentifier,
now,
}),
universalFlatEntityAndRelatedMapsToMutate: allUniversalFlatEntityMaps,
},
);
}
for (const viewFilterManifest of viewManifest.filters ?? []) {
addUniversalFlatEntityToUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow(
{
metadataName: 'viewFilter',
universalFlatEntity: fromViewFilterManifestToUniversalFlatViewFilter({
viewFilterManifest,
viewUniversalIdentifier: viewManifest.universalIdentifier,
applicationUniversalIdentifier,
now,
}),
universalFlatEntityAndRelatedMapsToMutate: allUniversalFlatEntityMaps,
},
);
}
for (const viewGroupManifest of viewManifest.groups ?? []) {
addUniversalFlatEntityToUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow(
{
metadataName: 'viewGroup',
universalFlatEntity: fromViewGroupManifestToUniversalFlatViewGroup({
viewGroupManifest,
viewUniversalIdentifier: viewManifest.universalIdentifier,
applicationUniversalIdentifier,
now,
}),
universalFlatEntityAndRelatedMapsToMutate: allUniversalFlatEntityMaps,
},
);
}
}
for (const navigationMenuItemManifest of manifest.navigationMenuItems ?? []) {
addUniversalFlatEntityToUniversalFlatEntityAndRelatedEntityMapsThroughMutationOrThrow(
{
metadataName: 'navigationMenuItem',
universalFlatEntity:
fromNavigationMenuItemManifestToUniversalFlatNavigationMenuItem({
navigationMenuItemManifest,
applicationUniversalIdentifier,
now,
}),
universalFlatEntityAndRelatedMapsToMutate: allUniversalFlatEntityMaps,
},
);
}
return allUniversalFlatEntityMaps;
};
@@ -0,0 +1,32 @@
import { type NavigationMenuItemManifest } from 'twenty-shared/application';
import { type UniversalFlatNavigationMenuItem } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-navigation-menu-item.type';
export const fromNavigationMenuItemManifestToUniversalFlatNavigationMenuItem =
({
navigationMenuItemManifest,
applicationUniversalIdentifier,
now,
}: {
navigationMenuItemManifest: NavigationMenuItemManifest;
applicationUniversalIdentifier: string;
now: string;
}): UniversalFlatNavigationMenuItem => {
return {
universalIdentifier: navigationMenuItemManifest.universalIdentifier,
applicationUniversalIdentifier,
name: navigationMenuItemManifest.name ?? null,
position: navigationMenuItemManifest.position,
viewUniversalIdentifier:
navigationMenuItemManifest.viewUniversalIdentifier ?? null,
link: navigationMenuItemManifest.link ?? null,
folderUniversalIdentifier:
navigationMenuItemManifest.folderUniversalIdentifier ?? null,
targetObjectMetadataUniversalIdentifier:
navigationMenuItemManifest.targetObjectUniversalIdentifier ?? null,
targetRecordId: null,
userWorkspaceId: null,
createdAt: now,
updatedAt: now,
};
};
@@ -0,0 +1,28 @@
import { type ViewFieldGroupManifest } from 'twenty-shared/application';
import { type UniversalFlatViewFieldGroup } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-view-field-group.type';
export const fromViewFieldGroupManifestToUniversalFlatViewFieldGroup = ({
viewFieldGroupManifest,
viewUniversalIdentifier,
applicationUniversalIdentifier,
now,
}: {
viewFieldGroupManifest: ViewFieldGroupManifest;
viewUniversalIdentifier: string;
applicationUniversalIdentifier: string;
now: string;
}): UniversalFlatViewFieldGroup => {
return {
universalIdentifier: viewFieldGroupManifest.universalIdentifier,
applicationUniversalIdentifier,
viewUniversalIdentifier,
name: viewFieldGroupManifest.name ?? '',
position: viewFieldGroupManifest.position,
isVisible: viewFieldGroupManifest.isVisible ?? true,
viewFieldUniversalIdentifiers: [],
createdAt: now,
updatedAt: now,
deletedAt: null,
};
};
@@ -0,0 +1,32 @@
import { type ViewFieldManifest } from 'twenty-shared/application';
import { type UniversalFlatViewField } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-view-field.type';
export const fromViewFieldManifestToUniversalFlatViewField = ({
viewFieldManifest,
viewUniversalIdentifier,
applicationUniversalIdentifier,
now,
}: {
viewFieldManifest: ViewFieldManifest;
viewUniversalIdentifier: string;
applicationUniversalIdentifier: string;
now: string;
}): UniversalFlatViewField => {
return {
universalIdentifier: viewFieldManifest.universalIdentifier,
applicationUniversalIdentifier,
fieldMetadataUniversalIdentifier:
viewFieldManifest.fieldMetadataUniversalIdentifier,
viewUniversalIdentifier,
viewFieldGroupUniversalIdentifier:
viewFieldManifest.viewFieldGroupUniversalIdentifier ?? null,
isVisible: viewFieldManifest.isVisible ?? true,
size: viewFieldManifest.size ?? 0,
position: viewFieldManifest.position,
aggregateOperation: viewFieldManifest.aggregateOperation ?? null,
createdAt: now,
updatedAt: now,
deletedAt: null,
};
};
@@ -0,0 +1,31 @@
import { type ViewFilterGroupManifest } from 'twenty-shared/application';
import { type UniversalFlatViewFilterGroup } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-view-filter-group.type';
export const fromViewFilterGroupManifestToUniversalFlatViewFilterGroup = ({
viewFilterGroupManifest,
viewUniversalIdentifier,
applicationUniversalIdentifier,
now,
}: {
viewFilterGroupManifest: ViewFilterGroupManifest;
viewUniversalIdentifier: string;
applicationUniversalIdentifier: string;
now: string;
}): UniversalFlatViewFilterGroup => {
return {
universalIdentifier: viewFilterGroupManifest.universalIdentifier,
applicationUniversalIdentifier,
viewUniversalIdentifier,
parentViewFilterGroupUniversalIdentifier:
viewFilterGroupManifest.parentViewFilterGroupUniversalIdentifier ?? null,
logicalOperator: viewFilterGroupManifest.logicalOperator,
positionInViewFilterGroup:
viewFilterGroupManifest.positionInViewFilterGroup ?? null,
childViewFilterGroupUniversalIdentifiers: [],
viewFilterUniversalIdentifiers: [],
createdAt: now,
updatedAt: now,
deletedAt: null,
};
};
@@ -0,0 +1,33 @@
import { type ViewFilterManifest } from 'twenty-shared/application';
import { type UniversalFlatViewFilter } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-view-filter.type';
export const fromViewFilterManifestToUniversalFlatViewFilter = ({
viewFilterManifest,
viewUniversalIdentifier,
applicationUniversalIdentifier,
now,
}: {
viewFilterManifest: ViewFilterManifest;
viewUniversalIdentifier: string;
applicationUniversalIdentifier: string;
now: string;
}): UniversalFlatViewFilter => {
return {
universalIdentifier: viewFilterManifest.universalIdentifier,
applicationUniversalIdentifier,
fieldMetadataUniversalIdentifier:
viewFilterManifest.fieldMetadataUniversalIdentifier,
viewUniversalIdentifier,
viewFilterGroupUniversalIdentifier:
viewFilterManifest.viewFilterGroupUniversalIdentifier ?? null,
operand: viewFilterManifest.operand,
value: viewFilterManifest.value,
subFieldName: viewFilterManifest.subFieldName ?? null,
positionInViewFilterGroup:
viewFilterManifest.positionInViewFilterGroup ?? null,
createdAt: now,
updatedAt: now,
deletedAt: null,
};
};
@@ -0,0 +1,27 @@
import { type ViewGroupManifest } from 'twenty-shared/application';
import { type UniversalFlatViewGroup } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-view-group.type';
export const fromViewGroupManifestToUniversalFlatViewGroup = ({
viewGroupManifest,
viewUniversalIdentifier,
applicationUniversalIdentifier,
now,
}: {
viewGroupManifest: ViewGroupManifest;
viewUniversalIdentifier: string;
applicationUniversalIdentifier: string;
now: string;
}): UniversalFlatViewGroup => {
return {
universalIdentifier: viewGroupManifest.universalIdentifier,
applicationUniversalIdentifier,
viewUniversalIdentifier,
fieldValue: viewGroupManifest.fieldValue,
isVisible: viewGroupManifest.isVisible ?? true,
position: viewGroupManifest.position,
createdAt: now,
updatedAt: now,
deletedAt: null,
};
};
@@ -0,0 +1,49 @@
import { type ViewManifest } from 'twenty-shared/application';
import {
ViewOpenRecordIn,
ViewType,
ViewVisibility,
} from 'twenty-shared/types';
import { type UniversalFlatView } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-view.type';
export const fromViewManifestToUniversalFlatView = ({
viewManifest,
applicationUniversalIdentifier,
now,
}: {
viewManifest: ViewManifest;
applicationUniversalIdentifier: string;
now: string;
}): UniversalFlatView => {
return {
universalIdentifier: viewManifest.universalIdentifier,
applicationUniversalIdentifier,
name: viewManifest.name,
objectMetadataUniversalIdentifier: viewManifest.objectUniversalIdentifier,
type: viewManifest.type ?? ViewType.TABLE,
icon: viewManifest.icon ?? 'IconList',
position: viewManifest.position ?? 0,
isCompact: viewManifest.isCompact ?? false,
isCustom: true,
visibility: viewManifest.visibility ?? ViewVisibility.WORKSPACE,
openRecordIn: viewManifest.openRecordIn ?? ViewOpenRecordIn.SIDE_PANEL,
key: null,
kanbanAggregateOperation: null,
kanbanAggregateOperationFieldMetadataUniversalIdentifier: null,
calendarLayout: null,
calendarFieldMetadataUniversalIdentifier: null,
mainGroupByFieldMetadataUniversalIdentifier: null,
shouldHideEmptyGroups: false,
anyFieldFilterValue: null,
createdByUserWorkspaceId: null,
viewFieldUniversalIdentifiers: [],
viewFilterUniversalIdentifiers: [],
viewFilterGroupUniversalIdentifiers: [],
viewGroupUniversalIdentifiers: [],
viewFieldGroupUniversalIdentifiers: [],
createdAt: now,
updatedAt: now,
deletedAt: null,
};
};
@@ -1,11 +1,11 @@
import { trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties } from 'twenty-shared/utils';
import { v4 } from 'uuid';
import { ViewFilterGroupLogicalOperator } from 'twenty-shared/types';
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
import { resolveEntityRelationUniversalIdentifiers } from 'src/engine/metadata-modules/flat-entity/utils/resolve-entity-relation-universal-identifiers.util';
import { type CreateViewFilterGroupInput } from 'src/engine/metadata-modules/view-filter-group/dtos/inputs/create-view-filter-group.input';
import { ViewFilterGroupLogicalOperator } from 'src/engine/metadata-modules/view-filter-group/enums/view-filter-group-logical-operator';
import { type UniversalFlatViewFilterGroup } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-view-filter-group.type';
export const fromCreateViewFilterGroupInputToFlatViewFilterGroupToCreate = ({
@@ -3,15 +3,17 @@ import {
trimAndRemoveDuplicatedWhitespacesFromObjectStringProperties,
} from 'twenty-shared/utils';
import { v4 } from 'uuid';
import {
ViewOpenRecordIn,
ViewType,
ViewVisibility,
} from 'twenty-shared/types';
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
import { resolveEntityRelationUniversalIdentifiers } from 'src/engine/metadata-modules/flat-entity/utils/resolve-entity-relation-universal-identifiers.util';
import { computeFlatViewGroupsOnViewCreate } from 'src/engine/metadata-modules/flat-view-group/utils/compute-flat-view-groups-on-view-create.util';
import { type CreateViewInput } from 'src/engine/metadata-modules/view/dtos/inputs/create-view.input';
import { ViewOpenRecordIn } from 'src/engine/metadata-modules/view/enums/view-open-record-in';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import { ViewVisibility } from 'src/engine/metadata-modules/view/enums/view-visibility.enum';
import { type UniversalFlatViewGroup } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-view-group.type';
import { type UniversalFlatView } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-view.type';
@@ -5,6 +5,11 @@ import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm';
import { fromArrayToUniqueKeyRecord, isDefined } from 'twenty-shared/utils';
import { FindManyOptions, FindOneOptions, Repository } from 'typeorm';
import { v4 as uuidv4, v4 } from 'uuid';
import {
ViewOpenRecordIn,
ViewType,
ViewVisibility,
} from 'twenty-shared/types';
import { ApplicationService } from 'src/engine/core-modules/application/services/application.service';
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
@@ -37,9 +42,6 @@ import {
import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type';
import { PageLayoutType } from 'src/engine/metadata-modules/page-layout/enums/page-layout-type.enum';
import { ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
import { ViewOpenRecordIn } from 'src/engine/metadata-modules/view/enums/view-open-record-in';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import { ViewVisibility } from 'src/engine/metadata-modules/view/enums/view-visibility.enum';
import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager';
import { buildSystemAuthContext } from 'src/engine/twenty-orm/utils/build-system-auth-context.util';
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
@@ -17,9 +17,8 @@ import {
} from 'class-validator';
import { GraphQLJSON } from 'graphql-type-json';
import { CalendarStartDay } from 'twenty-shared/constants';
import { SerializedRelation } from 'twenty-shared/types';
import { AggregateOperations, SerializedRelation } from 'twenty-shared/types';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { RatioAggregateConfigDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/ratio-aggregate-config.dto';
import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type';
@@ -17,9 +17,8 @@ import {
} from 'class-validator';
import { GraphQLJSON } from 'graphql-type-json';
import { CalendarStartDay } from 'twenty-shared/constants';
import { SerializedRelation } from 'twenty-shared/types';
import { AggregateOperations, SerializedRelation } from 'twenty-shared/types';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { AxisNameDisplay } from 'src/engine/metadata-modules/page-layout-widget/enums/axis-name-display.enum';
import { BarChartGroupMode } from 'src/engine/metadata-modules/page-layout-widget/enums/bar-chart-group-mode.enum';
@@ -15,9 +15,8 @@ import {
} from 'class-validator';
import { GraphQLJSON } from 'graphql-type-json';
import { CalendarStartDay } from 'twenty-shared/constants';
import { SerializedRelation } from 'twenty-shared/types';
import { AggregateOperations, SerializedRelation } from 'twenty-shared/types';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type';
import { ChartFilter } from 'src/engine/metadata-modules/page-layout-widget/types/chart-filter.type';
@@ -17,9 +17,8 @@ import {
} from 'class-validator';
import { GraphQLJSON } from 'graphql-type-json';
import { CalendarStartDay } from 'twenty-shared/constants';
import { SerializedRelation } from 'twenty-shared/types';
import { AggregateOperations, SerializedRelation } from 'twenty-shared/types';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { AxisNameDisplay } from 'src/engine/metadata-modules/page-layout-widget/enums/axis-name-display.enum';
import { ObjectRecordGroupByDateGranularity } from 'src/engine/metadata-modules/page-layout-widget/enums/date-granularity.enum';
@@ -16,9 +16,8 @@ import {
} from 'class-validator';
import { GraphQLJSON } from 'graphql-type-json';
import { CalendarStartDay } from 'twenty-shared/constants';
import { SerializedRelation } from 'twenty-shared/types';
import { AggregateOperations, SerializedRelation } from 'twenty-shared/types';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { ObjectRecordGroupByDateGranularity } from 'src/engine/metadata-modules/page-layout-widget/enums/date-granularity.enum';
import { GraphOrderBy } from 'src/engine/metadata-modules/page-layout-widget/enums/graph-order-by.enum';
@@ -7,8 +7,8 @@ import {
IsOptional,
IsUUID,
} from 'class-validator';
import { AggregateOperations } from 'twenty-shared/types';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
@InputType()
@@ -10,8 +10,8 @@ import {
IsUUID,
ValidateNested,
} from 'class-validator';
import { AggregateOperations } from 'twenty-shared/types';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
@InputType()
@@ -1,8 +1,8 @@
import { Field, ObjectType, registerEnumType } from '@nestjs/graphql';
import { IDField } from '@ptc-org/nestjs-query-graphql';
import { AggregateOperations } from 'twenty-shared/types';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
registerEnumType(AggregateOperations, { name: 'AggregateOperations' });
@@ -10,8 +10,8 @@ import {
type Relation,
UpdateDateColumn,
} from 'typeorm';
import { AggregateOperations } from 'twenty-shared/types';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { ViewFieldGroupEntity } from 'src/engine/metadata-modules/view-field-group/entities/view-field-group.entity';
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
@@ -1,7 +1,8 @@
import { Field, InputType } from '@nestjs/graphql';
import { ViewFilterGroupLogicalOperator } from 'twenty-shared/types';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { ViewFilterGroupLogicalOperator } from 'src/engine/metadata-modules/view-filter-group/enums/view-filter-group-logical-operator';
@InputType()
export class CreateViewFilterGroupInput {
@@ -1,9 +1,9 @@
import { Field, ObjectType, registerEnumType } from '@nestjs/graphql';
import { IDField } from '@ptc-org/nestjs-query-graphql';
import { ViewFilterGroupLogicalOperator } from 'twenty-shared/types';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { ViewFilterGroupLogicalOperator } from 'src/engine/metadata-modules/view-filter-group/enums/view-filter-group-logical-operator';
registerEnumType(ViewFilterGroupLogicalOperator, {
name: 'ViewFilterGroupLogicalOperator',
@@ -11,8 +11,8 @@ import {
type Relation,
UpdateDateColumn,
} from 'typeorm';
import { ViewFilterGroupLogicalOperator } from 'twenty-shared/types';
import { ViewFilterGroupLogicalOperator } from 'src/engine/metadata-modules/view-filter-group/enums/view-filter-group-logical-operator';
import { ViewFilterEntity } from 'src/engine/metadata-modules/view-filter/entities/view-filter.entity';
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface';
@@ -2,11 +2,11 @@ import { Test, type TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { type Repository } from 'typeorm';
import { ViewFilterGroupLogicalOperator } from 'twenty-shared/types';
import { ApplicationService } from 'src/engine/core-modules/application/services/application.service';
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
import { 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 { ViewFilterGroupService } from 'src/engine/metadata-modules/view-filter-group/services/view-filter-group.service';
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service';
@@ -5,8 +5,9 @@ import {
} from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';
import { ViewVisibility } from 'twenty-shared/types';
import { ViewAccessService } from 'src/engine/metadata-modules/view-permissions/services/view-access.service';
import { ViewVisibility } from 'src/engine/metadata-modules/view/enums/view-visibility.enum';
@Injectable()
export class CreateViewPermissionGuard implements CanActivate {
@@ -2,10 +2,10 @@ import { Injectable } from '@nestjs/common';
import { PermissionFlagType } from 'twenty-shared/constants';
import { isDefined } from 'twenty-shared/utils';
import { ViewVisibility } from 'twenty-shared/types';
import { PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service';
import { type ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
import { ViewVisibility } from 'src/engine/metadata-modules/view/enums/view-visibility.enum';
import {
ViewException,
ViewExceptionCode,
@@ -9,15 +9,17 @@ import {
IsString,
IsUUID,
} from 'class-validator';
import {
AggregateOperations,
ViewOpenRecordIn,
ViewType,
ViewVisibility,
} from 'twenty-shared/types';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { IsValidMetadataName } from 'src/engine/decorators/metadata/is-valid-metadata-name.decorator';
import { ViewCalendarLayout } from 'src/engine/metadata-modules/view/enums/view-calendar-layout.enum';
import { ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
import { ViewOpenRecordIn } from 'src/engine/metadata-modules/view/enums/view-open-record-in';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import { ViewVisibility } from 'src/engine/metadata-modules/view/enums/view-visibility.enum';
@InputType()
export class CreateViewInput {
@@ -8,14 +8,16 @@ import {
IsString,
IsUUID,
} from 'class-validator';
import {
AggregateOperations,
ViewOpenRecordIn,
ViewType,
ViewVisibility,
} from 'twenty-shared/types';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { IsValidMetadataName } from 'src/engine/decorators/metadata/is-valid-metadata-name.decorator';
import { ViewCalendarLayout } from 'src/engine/metadata-modules/view/enums/view-calendar-layout.enum';
import { ViewOpenRecordIn } from 'src/engine/metadata-modules/view/enums/view-open-record-in';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import { ViewVisibility } from 'src/engine/metadata-modules/view/enums/view-visibility.enum';
// TODO: this should be refactored like for view-field.input.ts
// This is a temporary fix as we were extending the CreateViewInput class which was adding default values for the non filled fields
@@ -1,8 +1,13 @@
import { Field, ObjectType, registerEnumType } from '@nestjs/graphql';
import { IDField } from '@ptc-org/nestjs-query-graphql';
import {
AggregateOperations,
ViewOpenRecordIn,
ViewType,
ViewVisibility,
} from 'twenty-shared/types';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { ViewFieldGroupDTO } from 'src/engine/metadata-modules/view-field-group/dtos/view-field-group.dto';
import { ViewFieldDTO } from 'src/engine/metadata-modules/view-field/dtos/view-field.dto';
@@ -12,9 +17,6 @@ import { ViewGroupDTO } from 'src/engine/metadata-modules/view-group/dtos/view-g
import { ViewSortDTO } from 'src/engine/metadata-modules/view-sort/dtos/view-sort.dto';
import { ViewCalendarLayout } from 'src/engine/metadata-modules/view/enums/view-calendar-layout.enum';
import { ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
import { ViewOpenRecordIn } from 'src/engine/metadata-modules/view/enums/view-open-record-in';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import { ViewVisibility } from 'src/engine/metadata-modules/view/enums/view-visibility.enum';
registerEnumType(ViewOpenRecordIn, { name: 'ViewOpenRecordIn' });
registerEnumType(ViewType, { name: 'ViewType' });
@@ -12,8 +12,13 @@ import {
type Relation,
UpdateDateColumn,
} from 'typeorm';
import {
AggregateOperations,
ViewOpenRecordIn,
ViewType,
ViewVisibility,
} from 'twenty-shared/types';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
@@ -25,9 +30,6 @@ import { ViewGroupEntity } from 'src/engine/metadata-modules/view-group/entities
import { ViewSortEntity } from 'src/engine/metadata-modules/view-sort/entities/view-sort.entity';
import { ViewCalendarLayout } from 'src/engine/metadata-modules/view/enums/view-calendar-layout.enum';
import { ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
import { ViewOpenRecordIn } from 'src/engine/metadata-modules/view/enums/view-open-record-in';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import { ViewVisibility } from 'src/engine/metadata-modules/view/enums/view-visibility.enum';
import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface';
// We could refactor this type to be dynamic to view type
@@ -10,6 +10,7 @@ import {
import { isArray } from '@sniptt/guards';
import { isDefined } from 'twenty-shared/utils';
import { ViewVisibility } from 'twenty-shared/types';
import { MetadataResolver } from 'src/engine/api/graphql/graphql-config/decorators/metadata-resolver.decorator';
import { I18nService } from 'src/engine/core-modules/i18n/i18n.service';
@@ -41,7 +42,6 @@ import { CreateViewInput } from 'src/engine/metadata-modules/view/dtos/inputs/cr
import { UpdateViewInput } from 'src/engine/metadata-modules/view/dtos/inputs/update-view.input';
import { ViewDTO } from 'src/engine/metadata-modules/view/dtos/view.dto';
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
import { ViewVisibility } from 'src/engine/metadata-modules/view/enums/view-visibility.enum';
import { ViewService } from 'src/engine/metadata-modules/view/services/view.service';
import { ViewGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/view/utils/view-graphql-api-exception.filter';
@@ -1,12 +1,15 @@
import { Test, type TestingModule } from '@nestjs/testing';
import { FieldMetadataType, ViewFilterOperand } from 'twenty-shared/types';
import {
FieldMetadataType,
ViewFilterGroupLogicalOperator,
ViewFilterOperand,
ViewType,
ViewVisibility,
} from 'twenty-shared/types';
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
import { ViewFilterGroupLogicalOperator } from 'src/engine/metadata-modules/view-filter-group/enums/view-filter-group-logical-operator';
import { ViewSortDirection } from 'src/engine/metadata-modules/view-sort/enums/view-sort-direction';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import { ViewVisibility } from 'src/engine/metadata-modules/view/enums/view-visibility.enum';
import { ViewQueryParamsService } from 'src/engine/metadata-modules/view/services/view-query-params.service';
import { ViewService } from 'src/engine/metadata-modules/view/services/view.service';
@@ -4,6 +4,8 @@ import {
OrderByDirection,
RecordFilterGroupLogicalOperator,
type RecordGqlOperationFilter,
ViewFilterGroupLogicalOperator,
ViewType,
} from 'twenty-shared/types';
import {
computeRecordGqlOperationFilter,
@@ -17,9 +19,7 @@ import { type ObjectRecordOrderBy } from 'src/engine/api/graphql/workspace-query
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { ViewFilterGroupLogicalOperator } from 'src/engine/metadata-modules/view-filter-group/enums/view-filter-group-logical-operator';
import { ViewSortDirection } from 'src/engine/metadata-modules/view-sort/enums/view-sort-direction';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import { ViewService } from 'src/engine/metadata-modules/view/services/view.service';
export type ViewQueryParams = {
@@ -4,6 +4,7 @@ import { InjectRepository } from '@nestjs/typeorm';
import { APP_LOCALES, SOURCE_LOCALE } from 'twenty-shared/translations';
import { isDefined } from 'twenty-shared/utils';
import { IsNull, Repository } from 'typeorm';
import { ViewVisibility } from 'twenty-shared/types';
import { ApplicationService } from 'src/engine/core-modules/application/services/application.service';
import { I18nService } from 'src/engine/core-modules/i18n/i18n.service';
@@ -21,7 +22,6 @@ import { DestroyViewInput } from 'src/engine/metadata-modules/view/dtos/inputs/d
import { UpdateViewInput } from 'src/engine/metadata-modules/view/dtos/inputs/update-view.input';
import { ViewDTO } from 'src/engine/metadata-modules/view/dtos/view.dto';
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
import { ViewVisibility } from 'src/engine/metadata-modules/view/enums/view-visibility.enum';
import { fromFlatViewToViewDto } from 'src/engine/metadata-modules/view/utils/from-flat-view-to-view-dto.util';
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service';
@@ -1,10 +1,12 @@
import { Test, type TestingModule } from '@nestjs/testing';
import { OrderByDirection } from 'twenty-shared/types';
import {
OrderByDirection,
ViewType,
ViewVisibility,
} from 'twenty-shared/types';
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import { ViewVisibility } from 'src/engine/metadata-modules/view/enums/view-visibility.enum';
import { ViewQueryParamsService } from 'src/engine/metadata-modules/view/services/view-query-params.service';
import { ViewService } from 'src/engine/metadata-modules/view/services/view.service';
import { ViewToolsFactory } from 'src/engine/metadata-modules/view/tools/view-tools.factory';
@@ -2,13 +2,15 @@ import { Injectable } from '@nestjs/common';
import { type ToolSet } from 'ai';
import { z } from 'zod';
import {
AggregateOperations,
ViewType,
ViewVisibility,
} from 'twenty-shared/types';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { formatValidationErrors } from 'src/engine/core-modules/tool-provider/utils/format-validation-errors.util';
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
import { buildObjectIdByNameMaps } from 'src/engine/metadata-modules/flat-object-metadata/utils/build-object-id-by-name-maps.util';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import { ViewVisibility } from 'src/engine/metadata-modules/view/enums/view-visibility.enum';
import { ViewQueryParamsService } from 'src/engine/metadata-modules/view/services/view-query-params.service';
import { ViewService } from 'src/engine/metadata-modules/view/services/view.service';
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
@@ -1,9 +1,11 @@
import { CalendarStartDay } from 'twenty-shared/constants';
import { STANDARD_OBJECTS } from 'twenty-shared/metadata';
import { PageLayoutTabLayoutMode } from 'twenty-shared/types';
import {
AggregateOperations,
PageLayoutTabLayoutMode,
} from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { AxisNameDisplay } from 'src/engine/metadata-modules/page-layout-widget/enums/axis-name-display.enum';
import { GraphOrderBy } from 'src/engine/metadata-modules/page-layout-widget/enums/graph-order-by.enum';
@@ -1,9 +1,11 @@
import { CalendarStartDay } from 'twenty-shared/constants';
import { STANDARD_OBJECTS } from 'twenty-shared/metadata';
import { PageLayoutTabLayoutMode } from 'twenty-shared/types';
import {
AggregateOperations,
PageLayoutTabLayoutMode,
} from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { AxisNameDisplay } from 'src/engine/metadata-modules/page-layout-widget/enums/axis-name-display.enum';
import { BarChartLayout } from 'src/engine/metadata-modules/page-layout-widget/enums/bar-chart-layout.enum';
@@ -1,9 +1,11 @@
import { CalendarStartDay } from 'twenty-shared/constants';
import { STANDARD_OBJECTS } from 'twenty-shared/metadata';
import { PageLayoutTabLayoutMode } from 'twenty-shared/types';
import {
AggregateOperations,
PageLayoutTabLayoutMode,
} from 'twenty-shared/types';
import { v4 } from 'uuid';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { type FlatPageLayoutWidget } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget.type';
import { AxisNameDisplay } from 'src/engine/metadata-modules/page-layout-widget/enums/axis-name-display.enum';
import { BarChartLayout } from 'src/engine/metadata-modules/page-layout-widget/enums/bar-chart-layout.enum';
@@ -1,4 +1,5 @@
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { AggregateOperations } from 'twenty-shared/types';
import { type FlatViewField } from 'src/engine/metadata-modules/flat-view-field/types/flat-view-field.type';
import {
createStandardViewFieldFlatMetadata,
@@ -1,4 +1,5 @@
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { AggregateOperations } from 'twenty-shared/types';
import { type FlatViewField } from 'src/engine/metadata-modules/flat-view-field/types/flat-view-field.type';
import {
createStandardViewFieldFlatMetadata,
@@ -1,4 +1,5 @@
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { AggregateOperations } from 'twenty-shared/types';
import { type FlatViewField } from 'src/engine/metadata-modules/flat-view-field/types/flat-view-field.type';
import {
createStandardViewFieldFlatMetadata,
@@ -1,8 +1,8 @@
import { STANDARD_OBJECTS } from 'twenty-shared/metadata';
import { isDefined } from 'twenty-shared/utils';
import { v4 } from 'uuid';
import { type AggregateOperations } from 'twenty-shared/types';
import { type AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { type FlatViewField } from 'src/engine/metadata-modules/flat-view-field/types/flat-view-field.type';
import { TWENTY_STANDARD_APPLICATION } from 'src/engine/workspace-manager/twenty-standard-application/constants/twenty-standard-applications';
import { type AllStandardObjectFieldName } from 'src/engine/workspace-manager/twenty-standard-application/types/all-standard-object-field-name.type';
@@ -1,8 +1,9 @@
import { ViewType } from 'twenty-shared/types';
import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import { type AllStandardObjectName } from 'src/engine/workspace-manager/twenty-standard-application/types/all-standard-object-name.type';
import { computeStandardAttachmentViews } from 'src/engine/workspace-manager/twenty-standard-application/utils/view/compute-standard-attachment-views.util';
import { computeStandardCalendarEventViews } from 'src/engine/workspace-manager/twenty-standard-application/utils/view/compute-standard-calendar-event-views.util';
@@ -1,6 +1,7 @@
import { ViewType } from 'twenty-shared/types';
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
import { ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import {
createStandardViewFlatMetadata,
type CreateStandardViewArgs,
@@ -1,6 +1,7 @@
import { ViewType } from 'twenty-shared/types';
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
import { ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import {
createStandardViewFlatMetadata,
type CreateStandardViewArgs,
@@ -1,6 +1,7 @@
import { ViewType } from 'twenty-shared/types';
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
import { ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import {
createStandardViewFlatMetadata,
type CreateStandardViewArgs,
@@ -1,6 +1,7 @@
import { ViewType } from 'twenty-shared/types';
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
import { ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import {
createStandardViewFlatMetadata,
type CreateStandardViewArgs,
@@ -1,6 +1,7 @@
import { ViewType } from 'twenty-shared/types';
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
import { ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import {
createStandardViewFlatMetadata,
type CreateStandardViewArgs,
@@ -1,6 +1,7 @@
import { ViewType } from 'twenty-shared/types';
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
import { ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import {
createStandardViewFlatMetadata,
type CreateStandardViewArgs,
@@ -1,6 +1,7 @@
import { ViewType } from 'twenty-shared/types';
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
import { ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import {
createStandardViewFlatMetadata,
type CreateStandardViewArgs,
@@ -1,6 +1,7 @@
import { ViewType } from 'twenty-shared/types';
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
import { ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import {
createStandardViewFlatMetadata,
type CreateStandardViewArgs,
@@ -1,7 +1,7 @@
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { AggregateOperations, ViewType } from 'twenty-shared/types';
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
import { ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import {
createStandardViewFlatMetadata,
type CreateStandardViewArgs,
@@ -1,6 +1,7 @@
import { ViewType } from 'twenty-shared/types';
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
import { ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import {
createStandardViewFlatMetadata,
type CreateStandardViewArgs,
@@ -1,6 +1,7 @@
import { ViewType } from 'twenty-shared/types';
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
import { ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import {
createStandardViewFlatMetadata,
type CreateStandardViewArgs,
@@ -1,6 +1,7 @@
import { ViewType } from 'twenty-shared/types';
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
import { ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import {
createStandardViewFlatMetadata,
type CreateStandardViewArgs,
@@ -1,6 +1,7 @@
import { ViewType } from 'twenty-shared/types';
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
import { ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import {
createStandardViewFlatMetadata,
type CreateStandardViewArgs,
@@ -1,6 +1,7 @@
import { ViewType } from 'twenty-shared/types';
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
import { ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import {
createStandardViewFlatMetadata,
type CreateStandardViewArgs,
@@ -1,6 +1,7 @@
import { ViewType } from 'twenty-shared/types';
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
import { ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import {
createStandardViewFlatMetadata,
type CreateStandardViewArgs,
@@ -1,6 +1,7 @@
import { ViewType } from 'twenty-shared/types';
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
import { ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import {
createStandardViewFlatMetadata,
type CreateStandardViewArgs,
@@ -1,6 +1,7 @@
import { ViewType } from 'twenty-shared/types';
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
import { ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import {
createStandardViewFlatMetadata,
type CreateStandardViewArgs,
@@ -1,12 +1,14 @@
import { isDefined } from 'class-validator';
import { STANDARD_OBJECTS } from 'twenty-shared/metadata';
import {
type AggregateOperations,
type ViewType,
ViewOpenRecordIn,
ViewVisibility,
} from 'twenty-shared/types';
import { type AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type';
import { type ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
import { ViewOpenRecordIn } from 'src/engine/metadata-modules/view/enums/view-open-record-in';
import { type ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import { ViewVisibility } from 'src/engine/metadata-modules/view/enums/view-visibility.enum';
import { TWENTY_STANDARD_APPLICATION } from 'src/engine/workspace-manager/twenty-standard-application/constants/twenty-standard-applications';
import { type AllStandardObjectFieldName } from 'src/engine/workspace-manager/twenty-standard-application/types/all-standard-object-field-name.type';
import { type AllStandardObjectName } from 'src/engine/workspace-manager/twenty-standard-application/types/all-standard-object-name.type';
@@ -1,10 +1,9 @@
import { msg, t } from '@lingui/core/macro';
import { type ALL_METADATA_NAME } from 'twenty-shared/metadata';
import { FieldMetadataType } from 'twenty-shared/types';
import { FieldMetadataType, ViewType } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { findFlatEntityByUniversalIdentifier } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import { type UniversalFlatView } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-view.type';
import { ViewExceptionCode } from 'src/engine/metadata-modules/view/exceptions/view.exception';
import { type FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/types/failed-flat-entity-validation.type';
@@ -1,8 +1,7 @@
import { Test, type TestingModule } from '@nestjs/testing';
import { FieldMetadataType } from 'twenty-shared/types';
import { AggregateOperations, FieldMetadataType } from 'twenty-shared/types';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { type AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
import { BarChartGroupMode } from 'src/engine/metadata-modules/page-layout-widget/enums/bar-chart-group-mode.enum';
@@ -1,8 +1,7 @@
import { Test, type TestingModule } from '@nestjs/testing';
import { FieldMetadataType } from 'twenty-shared/types';
import { AggregateOperations, FieldMetadataType } from 'twenty-shared/types';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { type AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type';
@@ -1,8 +1,7 @@
import { Test, type TestingModule } from '@nestjs/testing';
import { FieldMetadataType } from 'twenty-shared/types';
import { AggregateOperations, FieldMetadataType } from 'twenty-shared/types';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { type AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type';
@@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
import { CalendarStartDay } from 'twenty-shared/constants';
import {
AggregateOperations,
ObjectRecordGroupByDateGranularity,
OrderByWithGroupBy,
} from 'twenty-shared/types';
@@ -14,7 +15,6 @@ import {
import { ObjectRecordGroupBy } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
import { CommonGroupByQueryRunnerService } from 'src/engine/api/common/common-query-runners/common-group-by-query-runner.service';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
import { FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
@@ -1,10 +1,10 @@
import {
AggregateOperations,
FieldMetadataType,
ObjectRecordGroupByDateGranularity,
OrderByDirection,
} from 'twenty-shared/types';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { GraphOrderBy } from 'src/engine/metadata-modules/page-layout-widget/enums/graph-order-by.enum';
import { getGroupByOrderBy } from 'src/modules/dashboard/chart-data/utils/get-group-by-order-by.util';
@@ -1,7 +1,6 @@
import { FieldMetadataType } from 'twenty-shared/types';
import { AggregateOperations, FieldMetadataType } from 'twenty-shared/types';
import { capitalize } from 'twenty-shared/utils';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
type BuildAggregateFieldKeyParams = {
@@ -1,4 +1,4 @@
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { AggregateOperations } from 'twenty-shared/types';
export const getAggregateOperationLabel = (
operation: AggregateOperations,
@@ -1,4 +1,5 @@
import {
type AggregateOperations,
type AggregateOrderByWithGroupByField,
type ObjectRecordGroupByDateGranularity,
type ObjectRecordOrderByForCompositeField,
@@ -8,7 +9,6 @@ import {
} from 'twenty-shared/types';
import { assertUnreachable, isDefined } from 'twenty-shared/utils';
import { type AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { GraphOrderBy } from 'src/engine/metadata-modules/page-layout-widget/enums/graph-order-by.enum';
import { buildAggregateFieldKey } from 'src/modules/dashboard/chart-data/utils/build-aggregate-field-key.util';
@@ -1,8 +1,6 @@
import { FieldMetadataType } from 'twenty-shared/types';
import { AggregateOperations, FieldMetadataType } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
const PERCENT_AGGREGATE_OPERATIONS = new Set([
AggregateOperations.PERCENTAGE_EMPTY,
AggregateOperations.PERCENTAGE_NOT_EMPTY,
@@ -1,8 +1,10 @@
import { isNumber } from '@sniptt/guards';
import { ObjectRecordGroupByDateGranularity } from 'twenty-shared/types';
import {
AggregateOperations,
ObjectRecordGroupByDateGranularity,
} from 'twenty-shared/types';
import { z } from 'zod';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { AxisNameDisplay } from 'src/engine/metadata-modules/page-layout-widget/enums/axis-name-display.enum';
import { BarChartGroupMode } from 'src/engine/metadata-modules/page-layout-widget/enums/bar-chart-group-mode.enum';
import { BarChartLayout } from 'src/engine/metadata-modules/page-layout-widget/enums/bar-chart-layout.enum';
@@ -1,4 +1,5 @@
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { AggregateOperations } from 'twenty-shared/types';
import { type AggregateChartConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/aggregate-chart-configuration.dto';
import { type BarChartConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/bar-chart-configuration.dto';
import { type GaugeChartConfigurationDTO } from 'src/engine/metadata-modules/page-layout-widget/dtos/gauge-chart-configuration.dto';
@@ -27,6 +27,7 @@ import {
FieldMetadataType,
OrderByDirection,
RelationType,
ViewFilterGroupLogicalOperator,
ViewFilterOperand,
} from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
@@ -35,7 +36,6 @@ import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.
import { type FieldMetadataDTO } from 'src/engine/metadata-modules/field-metadata/dtos/field-metadata.dto';
import { type ObjectMetadataDTO } from 'src/engine/metadata-modules/object-metadata/dtos/object-metadata.dto';
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
import { ViewFilterGroupLogicalOperator } from 'src/engine/metadata-modules/view-filter-group/enums/view-filter-group-logical-operator';
import { WORKSPACE_MEMBER_DATA_SEED_IDS } from 'src/engine/workspace-manager/dev-seeder/data/constants/workspace-member-data-seeds.constant';
const client = request(`http://localhost:${APP_PORT}`);
@@ -4,9 +4,7 @@ import { deleteOneObjectMetadata } from 'test/integration/metadata/suites/object
import { updateOneObjectMetadata } from 'test/integration/metadata/suites/object-metadata/utils/update-one-object-metadata.util';
import { createOneCoreView } from 'test/integration/metadata/suites/view/utils/create-one-core-view.util';
import { assertViewStructure } from 'test/integration/utils/view-test.util';
import { ViewOpenRecordIn } from 'src/engine/metadata-modules/view/enums/view-open-record-in';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import { ViewOpenRecordIn, ViewType } from 'twenty-shared/types';
describe('Create core view', () => {
let testObjectMetadataId: string;
@@ -5,8 +5,7 @@ import { deleteOneObjectMetadata } from 'test/integration/metadata/suites/object
import { updateOneObjectMetadata } from 'test/integration/metadata/suites/object-metadata/utils/update-one-object-metadata.util';
import { createOneCoreView } from 'test/integration/metadata/suites/view/utils/create-one-core-view.util';
import { updateOneCoreView } from 'test/integration/metadata/suites/view/utils/update-one-core-view.util';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import { ViewType } from 'twenty-shared/types';
const TEST_NOT_EXISTING_VIEW_ID = '20202020-0000-4000-8000-000000000000';
@@ -20,10 +20,10 @@ import { updateOneObjectMetadata } from 'test/integration/metadata/suites/object
import { destroyOneCoreView } from 'test/integration/metadata/suites/view/utils/destroy-one-core-view.util';
import { assertViewFilterGroupStructure } from 'test/integration/utils/view-test.util';
import { jestExpectToBeDefined } from 'test/utils/jest-expect-to-be-defined.util.test';
import { ViewFilterGroupLogicalOperator } from 'twenty-shared/types';
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
import { type ViewFilterGroupDTO } from 'src/engine/metadata-modules/view-filter-group/dtos/view-filter-group.dto';
import { ViewFilterGroupLogicalOperator } from 'src/engine/metadata-modules/view-filter-group/enums/view-filter-group-logical-operator';
import {
generateViewFilterGroupExceptionMessage,
ViewFilterGroupExceptionMessageKey,
@@ -1,11 +1,14 @@
import {
ViewFilterGroupLogicalOperator,
ViewOpenRecordIn,
ViewType,
ViewVisibility,
} from 'twenty-shared/types';
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 ViewSortEntity } from 'src/engine/metadata-modules/view-sort/entities/view-sort.entity';
import { ViewSortDirection } from 'src/engine/metadata-modules/view-sort/enums/view-sort-direction';
import { type ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
import { ViewOpenRecordIn } from 'src/engine/metadata-modules/view/enums/view-open-record-in';
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
import { ViewVisibility } from 'src/engine/metadata-modules/view/enums/view-visibility.enum';
export const createViewData = (overrides: Partial<ViewEntity> = {}) => ({
name: 'Test View',
@@ -105,6 +105,8 @@ describe('syncApplication', () => {
logicFunctions: [],
frontComponents: [],
publicAssets: [],
views: [],
navigationMenuItems: [],
};
const { data: firstSyncData } = await syncApplication({

Some files were not shown because too many files have changed in this diff Show More