[GroupBy] Allow sorting in bar chart (#15097)
Closes https://github.com/twentyhq/core-team-issues/issues/1628 From a technical perspective, we can add more ordering options, such as the ability to combine two sorts on the X axis, e.g. sort by Close date ASC and then by Sum ASC, which will sort groups that have the same close date between themselves depending on their sum ASC. @Bonapara could you provide design if you want this to be implemented (quite short on our hand i think - maybe in V2 though)? https://github.com/user-attachments/assets/6ef21fe1-9d8f-43c0-bfa2-f6fc6341cacf --------- Co-authored-by: ehconitin <nitinkoche03@gmail.com>
This commit is contained in:
+1
@@ -54,6 +54,7 @@ export const useGraphWidgetGroupByQuery = ({
|
||||
const variables = generateGroupByQueryVariablesFromBarChartConfiguration({
|
||||
objectMetadataItem,
|
||||
barChartConfiguration: configuration,
|
||||
aggregateOperation,
|
||||
});
|
||||
|
||||
const apolloCoreClient = useApolloCoreClient();
|
||||
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { type GroupByRawResult } from '@/page-layout/widgets/graph/types/GroupByRawResult';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
import {
|
||||
ExtendedAggregateOperations,
|
||||
GraphOrderBy,
|
||||
GraphType,
|
||||
type BarChartConfiguration,
|
||||
} from '~/generated/graphql';
|
||||
import { transformTwoDimensionalGroupByToBarChartData } from '../transformTwoDimensionalGroupByToBarChartData';
|
||||
|
||||
describe('transformTwoDimensionalGroupByToBarChartData', () => {
|
||||
const mockGroupByFieldX = {
|
||||
id: 'field-x',
|
||||
name: 'createdAt',
|
||||
type: FieldMetadataType.DATE,
|
||||
label: 'Created At',
|
||||
} as FieldMetadataItem;
|
||||
|
||||
const mockGroupByFieldY = {
|
||||
id: 'field-y',
|
||||
name: 'stage',
|
||||
type: FieldMetadataType.SELECT,
|
||||
label: 'Stage',
|
||||
} as FieldMetadataItem;
|
||||
|
||||
const mockAggregateField = {
|
||||
id: 'field-aggregate',
|
||||
name: 'amount',
|
||||
type: FieldMetadataType.NUMBER,
|
||||
label: 'Amount',
|
||||
} as FieldMetadataItem;
|
||||
|
||||
const mockObjectMetadataItem = {
|
||||
id: 'object-1',
|
||||
nameSingular: 'opportunity',
|
||||
namePlural: 'opportunities',
|
||||
fields: [mockGroupByFieldX, mockGroupByFieldY, mockAggregateField],
|
||||
} as ObjectMetadataItem;
|
||||
|
||||
const mockConfiguration: BarChartConfiguration = {
|
||||
__typename: 'BarChartConfiguration',
|
||||
graphType: GraphType.VERTICAL_BAR,
|
||||
aggregateFieldMetadataId: 'field-aggregate',
|
||||
aggregateOperation: ExtendedAggregateOperations.SUM,
|
||||
primaryAxisGroupByFieldMetadataId: 'field-x',
|
||||
secondaryAxisGroupByFieldMetadataId: 'field-y',
|
||||
secondaryAxisOrderBy: GraphOrderBy.FIELD_DESC,
|
||||
};
|
||||
|
||||
it('should order keys correctly despite unordered raw results', () => {
|
||||
// This test demonstrates the key ordering issue described in the user query
|
||||
// Raw results where "CUSTOMER" appears before "NEW" in the data stream despite orderBy,
|
||||
// bc there is no "NEW" group before october 21st and the results are primarily ordered by date ASC
|
||||
// but we want them ordered alphabetically-reversed
|
||||
const rawResults: GroupByRawResult[] = [
|
||||
{
|
||||
groupByDimensionValues: ['2025-10-16T00:00:00.000Z', 'SCREENING'],
|
||||
sumAmount: 75000000000,
|
||||
},
|
||||
{
|
||||
groupByDimensionValues: ['2025-10-16T00:00:00.000Z', 'PROPOSAL'],
|
||||
sumAmount: 380000000000,
|
||||
},
|
||||
{
|
||||
groupByDimensionValues: ['2025-10-17T00:00:00.000Z', 'CUSTOMER'],
|
||||
sumAmount: 720000000000,
|
||||
},
|
||||
{
|
||||
groupByDimensionValues: ['2025-10-21T00:00:00.000Z', 'PROPOSAL'],
|
||||
sumAmount: 580000000000,
|
||||
},
|
||||
{
|
||||
groupByDimensionValues: ['2025-10-21T00:00:00.000Z', 'NEW'],
|
||||
sumAmount: 125000000000,
|
||||
},
|
||||
];
|
||||
|
||||
const result = transformTwoDimensionalGroupByToBarChartData({
|
||||
rawResults,
|
||||
groupByFieldX: mockGroupByFieldX,
|
||||
groupByFieldY: mockGroupByFieldY,
|
||||
aggregateField: mockAggregateField,
|
||||
configuration: mockConfiguration,
|
||||
aggregateOperation: 'sumAmount',
|
||||
objectMetadataItem: mockObjectMetadataItem,
|
||||
});
|
||||
|
||||
expect(result.keys).toEqual(['SCREENING', 'PROPOSAL', 'NEW', 'CUSTOMER']);
|
||||
expect(result.series).toEqual([
|
||||
{ key: 'SCREENING', label: 'SCREENING' },
|
||||
{ key: 'PROPOSAL', label: 'PROPOSAL' },
|
||||
{ key: 'NEW', label: 'NEW' },
|
||||
{ key: 'CUSTOMER', label: 'CUSTOMER' },
|
||||
]);
|
||||
|
||||
expect(result.data).toHaveLength(3);
|
||||
expect(result.data[0]).toEqual({
|
||||
createdAt: 'Oct 16, 2025',
|
||||
SCREENING: 75000000000,
|
||||
PROPOSAL: 380000000000,
|
||||
});
|
||||
expect(result.data[1]).toEqual({
|
||||
createdAt: 'Oct 17, 2025',
|
||||
CUSTOMER: 720000000000,
|
||||
});
|
||||
expect(result.data[2]).toEqual({
|
||||
createdAt: 'Oct 21, 2025',
|
||||
PROPOSAL: 580000000000,
|
||||
NEW: 125000000000,
|
||||
});
|
||||
});
|
||||
});
|
||||
+42
-38
@@ -1,29 +1,23 @@
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { assertUnreachable, isDefined } from 'twenty-shared/utils';
|
||||
import { type BarChartConfiguration, GraphOrderBy } from '~/generated/graphql';
|
||||
import { getGroupByOrderBy } from '@/page-layout/widgets/graph/utils/getGroupByOrderBy';
|
||||
import {
|
||||
type AggregateOrderByWithGroupByField,
|
||||
type ObjectRecordOrderByForCompositeField,
|
||||
type ObjectRecordOrderByForScalarField,
|
||||
type ObjectRecordOrderByWithGroupByDateField,
|
||||
} from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { type BarChartConfiguration } from '~/generated/graphql';
|
||||
import { buildGroupByFieldObject } from './buildGroupByFieldObject';
|
||||
|
||||
const _mapOrderByToDirection = (orderByEnum: GraphOrderBy) => {
|
||||
switch (orderByEnum) {
|
||||
case GraphOrderBy.FIELD_ASC:
|
||||
return 'AscNullsLast';
|
||||
case GraphOrderBy.FIELD_DESC:
|
||||
return 'DescNullsLast';
|
||||
case GraphOrderBy.VALUE_ASC:
|
||||
return 'AscNullsLast';
|
||||
case GraphOrderBy.VALUE_DESC:
|
||||
return 'DescNullsLast';
|
||||
default:
|
||||
assertUnreachable(orderByEnum);
|
||||
}
|
||||
};
|
||||
|
||||
export const generateGroupByQueryVariablesFromBarChartConfiguration = ({
|
||||
objectMetadataItem,
|
||||
barChartConfiguration,
|
||||
aggregateOperation,
|
||||
}: {
|
||||
objectMetadataItem: ObjectMetadataItem;
|
||||
barChartConfiguration: BarChartConfiguration;
|
||||
aggregateOperation?: string;
|
||||
}) => {
|
||||
const groupByFieldXId =
|
||||
barChartConfiguration.primaryAxisGroupByFieldMetadataId;
|
||||
@@ -71,31 +65,41 @@ export const generateGroupByQueryVariablesFromBarChartConfiguration = ({
|
||||
);
|
||||
}
|
||||
|
||||
const orderBy: Array<Record<string, string>> = [];
|
||||
const orderBy: Array<
|
||||
| AggregateOrderByWithGroupByField
|
||||
| ObjectRecordOrderByForScalarField
|
||||
| ObjectRecordOrderByWithGroupByDateField
|
||||
| ObjectRecordOrderByForCompositeField
|
||||
> = [];
|
||||
|
||||
// TODO: Add orderBy back in when the backend is ready
|
||||
// if (isDefined(barChartConfiguration.primaryAxisOrderBy)) {
|
||||
// orderBy.push({
|
||||
// [groupByFieldX.name]: mapOrderByToDirection(
|
||||
// barChartConfiguration.primaryAxisOrderBy!,
|
||||
// ),
|
||||
// });
|
||||
// }
|
||||
|
||||
// if (
|
||||
// isDefined(groupByFieldY) &&
|
||||
// isDefined(barChartConfiguration.secondaryAxisOrderBy)
|
||||
// ) {
|
||||
// orderBy.push({
|
||||
// [groupByFieldY.name]: mapOrderByToDirection(
|
||||
// barChartConfiguration.secondaryAxisOrderBy!,
|
||||
// ),
|
||||
// });
|
||||
// }
|
||||
if (isDefined(barChartConfiguration.primaryAxisOrderBy)) {
|
||||
orderBy.push(
|
||||
getGroupByOrderBy({
|
||||
graphOrderBy: barChartConfiguration.primaryAxisOrderBy,
|
||||
groupByField: groupByFieldX,
|
||||
groupBySubFieldName:
|
||||
barChartConfiguration.primaryAxisGroupBySubFieldName,
|
||||
aggregateOperation,
|
||||
}),
|
||||
);
|
||||
}
|
||||
if (
|
||||
isDefined(groupByFieldY) &&
|
||||
isDefined(barChartConfiguration.secondaryAxisOrderBy)
|
||||
) {
|
||||
orderBy.push(
|
||||
getGroupByOrderBy({
|
||||
graphOrderBy: barChartConfiguration.secondaryAxisOrderBy,
|
||||
groupByField: groupByFieldY,
|
||||
groupBySubFieldName:
|
||||
barChartConfiguration.secondaryAxisGroupBySubFieldName,
|
||||
aggregateOperation,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
groupBy,
|
||||
// TODO: Add filters
|
||||
...(orderBy.length > 0 && { orderBy }),
|
||||
};
|
||||
};
|
||||
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { isCompositeFieldType } from '@/object-record/object-filter-dropdown/utils/isCompositeFieldType';
|
||||
import { GRAPH_DEFAULT_DATE_GRANULARITY } from '@/page-layout/widgets/graph/constants/GraphDefaultDateGranularity.constant';
|
||||
import {
|
||||
OrderByDirection,
|
||||
type AggregateOrderByWithGroupByField,
|
||||
type ObjectRecordOrderByForCompositeField,
|
||||
type ObjectRecordOrderByForScalarField,
|
||||
type ObjectRecordOrderByWithGroupByDateField,
|
||||
} from 'twenty-shared/types';
|
||||
import {
|
||||
assertUnreachable,
|
||||
isDefined,
|
||||
isFieldMetadataDateKind,
|
||||
} from 'twenty-shared/utils';
|
||||
import { GraphOrderBy } from '~/generated/graphql';
|
||||
|
||||
const mapOrderByToDirection = (orderByEnum: GraphOrderBy): OrderByDirection => {
|
||||
switch (orderByEnum) {
|
||||
case GraphOrderBy.FIELD_ASC:
|
||||
return OrderByDirection.AscNullsLast;
|
||||
case GraphOrderBy.FIELD_DESC:
|
||||
return OrderByDirection.DescNullsLast;
|
||||
case GraphOrderBy.VALUE_ASC:
|
||||
return OrderByDirection.AscNullsLast;
|
||||
case GraphOrderBy.VALUE_DESC:
|
||||
return OrderByDirection.DescNullsLast;
|
||||
default:
|
||||
assertUnreachable(orderByEnum);
|
||||
}
|
||||
};
|
||||
|
||||
export const getGroupByOrderBy = ({
|
||||
graphOrderBy,
|
||||
groupByField,
|
||||
groupBySubFieldName,
|
||||
aggregateOperation,
|
||||
}: {
|
||||
graphOrderBy: GraphOrderBy;
|
||||
groupByField: FieldMetadataItem;
|
||||
groupBySubFieldName?: string | null;
|
||||
aggregateOperation?: string;
|
||||
}):
|
||||
| AggregateOrderByWithGroupByField
|
||||
| ObjectRecordOrderByForScalarField
|
||||
| ObjectRecordOrderByWithGroupByDateField
|
||||
| ObjectRecordOrderByForCompositeField => {
|
||||
switch (graphOrderBy) {
|
||||
case GraphOrderBy.FIELD_ASC:
|
||||
case GraphOrderBy.FIELD_DESC: {
|
||||
if (isCompositeFieldType(groupByField.type)) {
|
||||
if (!isDefined(groupBySubFieldName)) {
|
||||
throw new Error(
|
||||
`Group by subFieldName is required for composite fields (field: ${groupByField.name})`,
|
||||
);
|
||||
}
|
||||
return {
|
||||
[groupByField.name]: {
|
||||
[groupBySubFieldName]: mapOrderByToDirection(graphOrderBy),
|
||||
},
|
||||
};
|
||||
} else if (isFieldMetadataDateKind(groupByField.type)) {
|
||||
return {
|
||||
[groupByField.name]: {
|
||||
orderBy: mapOrderByToDirection(graphOrderBy),
|
||||
granularity: GRAPH_DEFAULT_DATE_GRANULARITY,
|
||||
},
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
[groupByField.name]: mapOrderByToDirection(graphOrderBy),
|
||||
};
|
||||
}
|
||||
}
|
||||
case GraphOrderBy.VALUE_ASC:
|
||||
case GraphOrderBy.VALUE_DESC: {
|
||||
if (!isDefined(aggregateOperation)) {
|
||||
throw new Error(
|
||||
`Aggregate operation not found (field: ${groupByField.name})`,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
aggregate: {
|
||||
[aggregateOperation]: mapOrderByToDirection(graphOrderBy),
|
||||
},
|
||||
};
|
||||
}
|
||||
default:
|
||||
assertUnreachable(graphOrderBy);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
import { GraphOrderBy } from '~/generated/graphql';
|
||||
|
||||
export const getSortedKeys = ({
|
||||
orderByY,
|
||||
yValues,
|
||||
}: {
|
||||
orderByY?: GraphOrderBy | null;
|
||||
yValues: string[];
|
||||
}) => {
|
||||
switch (orderByY) {
|
||||
case GraphOrderBy.FIELD_ASC:
|
||||
return Array.from(yValues).sort((a, b) => a.localeCompare(b));
|
||||
case GraphOrderBy.FIELD_DESC:
|
||||
return Array.from(yValues).sort((a, b) => b.localeCompare(a));
|
||||
default:
|
||||
return Array.from(yValues);
|
||||
}
|
||||
};
|
||||
+7
-1
@@ -8,6 +8,7 @@ import { type GroupByRawResult } from '@/page-layout/widgets/graph/types/GroupBy
|
||||
import { computeAggregateValueFromGroupByResult } from '@/page-layout/widgets/graph/utils/computeAggregateValueFromGroupByResult';
|
||||
import { formatDimensionValue } from '@/page-layout/widgets/graph/utils/formatDimensionValue';
|
||||
import { getFieldKey } from '@/page-layout/widgets/graph/utils/getFieldKey';
|
||||
import { getSortedKeys } from '@/page-layout/widgets/graph/utils/getSortedKeys';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { type BarChartConfiguration } from '~/generated/graphql';
|
||||
|
||||
@@ -101,7 +102,12 @@ export const transformTwoDimensionalGroupByToBarChartData = ({
|
||||
dataItem[yValue] = aggregateValue;
|
||||
});
|
||||
|
||||
const keys = Array.from(yValues);
|
||||
// Sorting needed because yValues may be unordered despite BE orderBy, if there are empty groups
|
||||
const keys = getSortedKeys({
|
||||
orderByY: configuration.secondaryAxisOrderBy,
|
||||
yValues: Array.from(yValues),
|
||||
});
|
||||
|
||||
const series: BarChartSeries[] = keys.map((key) => ({
|
||||
key,
|
||||
label: key,
|
||||
|
||||
+1
-1
@@ -1,9 +1,9 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { WorkspaceAuthContext } from 'src/engine/api/common/interfaces/workspace-auth-context.interface';
|
||||
import { ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
import { CommonSelectedFieldsHandler } from 'src/engine/api/common/common-args-handlers/common-query-selected-fields/common-selected-fields.handler';
|
||||
import { CommonResultGettersService } from 'src/engine/api/common/common-result-getters/common-result-getters.service';
|
||||
|
||||
+1
-2
@@ -2,14 +2,13 @@ import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { isDefined } from 'class-validator';
|
||||
import { QUERY_MAX_RECORDS } from 'twenty-shared/constants';
|
||||
import { ObjectRecord, OrderByDirection } from 'twenty-shared/types';
|
||||
import { FindOptionsRelations, ObjectLiteral } from 'typeorm';
|
||||
|
||||
import { WorkspaceAuthContext } from 'src/engine/api/common/interfaces/workspace-auth-context.interface';
|
||||
import {
|
||||
ObjectRecord,
|
||||
ObjectRecordFilter,
|
||||
ObjectRecordOrderBy,
|
||||
OrderByDirection,
|
||||
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
import { CommonBaseQueryRunnerService } from 'src/engine/api/common/common-query-runners/common-base-query-runner.service';
|
||||
|
||||
+2
-4
@@ -1,14 +1,12 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { QUERY_MAX_RECORDS } from 'twenty-shared/constants';
|
||||
import { ObjectRecord } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { FindOptionsRelations, ObjectLiteral } from 'typeorm';
|
||||
|
||||
import { WorkspaceAuthContext } from 'src/engine/api/common/interfaces/workspace-auth-context.interface';
|
||||
import {
|
||||
ObjectRecord,
|
||||
ObjectRecordFilter,
|
||||
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { ObjectRecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
import { CommonBaseQueryRunnerService } from 'src/engine/api/common/common-query-runners/common-base-query-runner.service';
|
||||
import {
|
||||
|
||||
+5
-2
@@ -1,9 +1,12 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
|
||||
import { FieldMetadataType, RelationType } from 'twenty-shared/types';
|
||||
import {
|
||||
FieldMetadataType,
|
||||
ObjectRecord,
|
||||
RelationType,
|
||||
} from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type QueryResultFieldValue } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/interfaces/query-result-field-value';
|
||||
import { type QueryResultGetterHandlerInterface } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/interfaces/query-result-getter-handler.interface';
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import {
|
||||
type ObjectRecord,
|
||||
type ObjectRecordOrderBy,
|
||||
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import { type ObjectRecordOrderBy } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
import { type CommonPageInfo } from 'src/engine/api/common/types/common-page-info.type';
|
||||
import {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
export const mockPersonRecords: Partial<ObjectRecord>[] = [
|
||||
{
|
||||
|
||||
+7
-9
@@ -1,19 +1,17 @@
|
||||
import { isObject } from 'class-validator';
|
||||
import {
|
||||
type AggregateOrderByWithGroupByField,
|
||||
FieldMetadataType,
|
||||
ObjectRecordGroupByDateGranularity,
|
||||
} from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import {
|
||||
OrderByDirection,
|
||||
type AggregateOrderByWithGroupByField,
|
||||
type ObjectRecordOrderBy,
|
||||
type ObjectRecordOrderByForCompositeField,
|
||||
type ObjectRecordOrderByForScalarField,
|
||||
type ObjectRecordOrderByWithGroupByDateField,
|
||||
OrderByDirection,
|
||||
type OrderByWithGroupBy,
|
||||
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
} from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type ObjectRecordOrderBy } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
import {
|
||||
GraphqlQueryRunnerException,
|
||||
@@ -28,8 +26,8 @@ import {
|
||||
import { getGroupByExpression } from 'src/engine/api/graphql/graphql-query-runner/group-by/resolvers/utils/get-group-by-expression.util';
|
||||
import { ProcessAggregateHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/process-aggregate.helper';
|
||||
import {
|
||||
getAvailableAggregationsFromObjectFields,
|
||||
type AggregationField,
|
||||
getAvailableAggregationsFromObjectFields,
|
||||
} from 'src/engine/api/graphql/workspace-schema-builder/utils/get-available-aggregations-from-object-fields.util';
|
||||
import { UserInputError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||
import { type FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { OrderByDirection } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { OrderByDirection } from 'twenty-shared/types';
|
||||
|
||||
import {
|
||||
GraphqlQueryRunnerException,
|
||||
|
||||
+1
-2
@@ -1,7 +1,6 @@
|
||||
import { OrderByDirection } from 'twenty-shared/types';
|
||||
import { capitalize } from 'twenty-shared/utils';
|
||||
|
||||
import { OrderByDirection } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
import { type OrderByCondition } from 'src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-order/graphql-query-order.parser';
|
||||
import { convertOrderByToFindOptionsOrder } from 'src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query-order/utils/convert-order-by-to-find-options-order';
|
||||
import { compositeTypeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types';
|
||||
|
||||
+1
-1
@@ -1,9 +1,9 @@
|
||||
import { type OrderByWithGroupBy } from 'twenty-shared/types';
|
||||
import { type FindOptionsWhere, type ObjectLiteral } from 'typeorm';
|
||||
|
||||
import {
|
||||
type ObjectRecordFilter,
|
||||
type ObjectRecordOrderBy,
|
||||
type OrderByWithGroupBy,
|
||||
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
import {
|
||||
|
||||
+2
-4
@@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
|
||||
|
||||
import {
|
||||
CompositeFieldSubFieldName,
|
||||
ObjectRecord,
|
||||
PartialFieldMetadataItemOption,
|
||||
RecordFilterGroupLogicalOperator,
|
||||
} from 'twenty-shared/types';
|
||||
@@ -18,10 +19,7 @@ import {
|
||||
GraphqlQueryBaseResolverService,
|
||||
GraphqlQueryResolverExecutionArgs,
|
||||
} from 'src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service';
|
||||
import {
|
||||
ObjectRecord,
|
||||
ObjectRecordFilter,
|
||||
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { ObjectRecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { IEdge } from 'src/engine/api/graphql/workspace-query-runner/interfaces/edge.interface';
|
||||
import { IGroupByConnection } from 'src/engine/api/graphql/workspace-query-runner/interfaces/group-by-connection.interface';
|
||||
import { type WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
|
||||
|
||||
+4
-2
@@ -1,7 +1,9 @@
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { ObjectRecordGroupByDateGranularity } from 'twenty-shared/types';
|
||||
import {
|
||||
ObjectRecordGroupByDateGranularity,
|
||||
type ObjectRecord,
|
||||
} from 'twenty-shared/types';
|
||||
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type IEdge } from 'src/engine/api/graphql/workspace-query-runner/interfaces/edge.interface';
|
||||
import { type IGroupByConnection } from 'src/engine/api/graphql/workspace-query-runner/interfaces/group-by-connection.interface';
|
||||
|
||||
|
||||
+2
-5
@@ -1,10 +1,7 @@
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { FieldMetadataType, type ObjectRecord } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import {
|
||||
type ObjectRecord,
|
||||
type ObjectRecordOrderBy,
|
||||
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type ObjectRecordOrderBy } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type IConnection } from 'src/engine/api/graphql/workspace-query-runner/interfaces/connection.interface';
|
||||
|
||||
import { CONNECTION_MAX_DEPTH } from 'src/engine/api/graphql/graphql-query-runner/constants/connection-max-depth.constant';
|
||||
|
||||
+1
-2
@@ -1,9 +1,8 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { FieldMetadataType, type ObjectRecord } from 'twenty-shared/types';
|
||||
import { type FindOptionsRelations, type ObjectLiteral } from 'typeorm';
|
||||
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
|
||||
|
||||
import {
|
||||
|
||||
+1
-2
@@ -1,9 +1,8 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
import { type FindOptionsRelations, type ObjectLiteral } from 'typeorm';
|
||||
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
import { ProcessNestedRelationsV2Helper } from 'src/engine/api/graphql/graphql-query-runner/helpers/process-nested-relations-v2.helper';
|
||||
import { type AggregationField } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-available-aggregations-from-object-fields.util';
|
||||
import { type AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
|
||||
|
||||
+1
-1
@@ -1,6 +1,7 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
|
||||
import graphqlFields from 'graphql-fields';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
import {
|
||||
assertIsDefinedOrThrow,
|
||||
capitalize,
|
||||
@@ -8,7 +9,6 @@ import {
|
||||
} from 'twenty-shared/utils';
|
||||
import { type ObjectLiteral } from 'typeorm';
|
||||
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type IConnection } from 'src/engine/api/graphql/workspace-query-runner/interfaces/connection.interface';
|
||||
import { type IEdge } from 'src/engine/api/graphql/workspace-query-runner/interfaces/edge.interface';
|
||||
import { type WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
|
||||
|
||||
+1
-1
@@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { QUERY_MAX_RECORDS } from 'twenty-shared/constants';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
import { capitalize, isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
In,
|
||||
@@ -14,7 +15,6 @@ import {
|
||||
GraphqlQueryBaseResolverService,
|
||||
type GraphqlQueryResolverExecutionArgs,
|
||||
} from 'src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service';
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
|
||||
import { type CreateManyResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
|
||||
+2
-1
@@ -1,10 +1,11 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import {
|
||||
GraphqlQueryBaseResolverService,
|
||||
type GraphqlQueryResolverExecutionArgs,
|
||||
} from 'src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service';
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
|
||||
import { type CreateOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
|
||||
+1
-1
@@ -1,12 +1,12 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { QUERY_MAX_RECORDS } from 'twenty-shared/constants';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import {
|
||||
GraphqlQueryBaseResolverService,
|
||||
type GraphqlQueryResolverExecutionArgs,
|
||||
} from 'src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service';
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
|
||||
import { type DeleteManyResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
|
||||
+1
-1
@@ -1,12 +1,12 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { QUERY_MAX_RECORDS } from 'twenty-shared/constants';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import {
|
||||
GraphqlQueryBaseResolverService,
|
||||
type GraphqlQueryResolverExecutionArgs,
|
||||
} from 'src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service';
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
|
||||
import { type DeleteOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
|
||||
+1
-1
@@ -1,12 +1,12 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { QUERY_MAX_RECORDS } from 'twenty-shared/constants';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import {
|
||||
GraphqlQueryBaseResolverService,
|
||||
type GraphqlQueryResolverExecutionArgs,
|
||||
} from 'src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service';
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
|
||||
import { type DestroyManyResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
|
||||
+1
-1
@@ -1,12 +1,12 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { QUERY_MAX_RECORDS } from 'twenty-shared/constants';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import {
|
||||
GraphqlQueryBaseResolverService,
|
||||
type GraphqlQueryResolverExecutionArgs,
|
||||
} from 'src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service';
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
|
||||
import { type DestroyOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
|
||||
+1
-4
@@ -1,16 +1,13 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import isEmpty from 'lodash.isempty';
|
||||
import { OrderByDirection, type ObjectRecord } from 'twenty-shared/types';
|
||||
import { In } from 'typeorm';
|
||||
|
||||
import {
|
||||
GraphqlQueryBaseResolverService,
|
||||
type GraphqlQueryResolverExecutionArgs,
|
||||
} from 'src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service';
|
||||
import {
|
||||
type ObjectRecord,
|
||||
OrderByDirection,
|
||||
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type IConnection } from 'src/engine/api/graphql/workspace-query-runner/interfaces/connection.interface';
|
||||
import { type WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
|
||||
import { type FindDuplicatesResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
+1
-2
@@ -1,6 +1,7 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { QUERY_MAX_RECORDS } from 'twenty-shared/constants';
|
||||
import { ObjectRecord, OrderByDirection } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import {
|
||||
@@ -8,10 +9,8 @@ import {
|
||||
type GraphqlQueryResolverExecutionArgs,
|
||||
} from 'src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service';
|
||||
import {
|
||||
type ObjectRecord,
|
||||
type ObjectRecordFilter,
|
||||
type ObjectRecordOrderBy,
|
||||
OrderByDirection,
|
||||
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type IConnection } from 'src/engine/api/graphql/workspace-query-runner/interfaces/connection.interface';
|
||||
import { type WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
|
||||
|
||||
+2
-4
@@ -2,15 +2,13 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { QUERY_MAX_RECORDS } from 'twenty-shared/constants';
|
||||
import { ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import {
|
||||
GraphqlQueryBaseResolverService,
|
||||
type GraphqlQueryResolverExecutionArgs,
|
||||
} from 'src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service';
|
||||
import {
|
||||
type ObjectRecord,
|
||||
type ObjectRecordFilter,
|
||||
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type ObjectRecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
|
||||
import { type FindOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
|
||||
+1
-2
@@ -4,7 +4,7 @@ import {
|
||||
MUTATION_MAX_MERGE_RECORDS,
|
||||
QUERY_MAX_RECORDS,
|
||||
} from 'twenty-shared/constants';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { FieldMetadataType, type ObjectRecord } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { In } from 'typeorm';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
@@ -13,7 +13,6 @@ import {
|
||||
GraphqlQueryBaseResolverService,
|
||||
type GraphqlQueryResolverExecutionArgs,
|
||||
} from 'src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service';
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
|
||||
import { type MergeManyResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
import { type FieldMetadataRelationSettings } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-settings.interface';
|
||||
|
||||
+1
-1
@@ -1,12 +1,12 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { QUERY_MAX_RECORDS } from 'twenty-shared/constants';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import {
|
||||
GraphqlQueryBaseResolverService,
|
||||
type GraphqlQueryResolverExecutionArgs,
|
||||
} from 'src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service';
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
|
||||
import { type RestoreManyResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
|
||||
+1
-1
@@ -1,12 +1,12 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { QUERY_MAX_RECORDS } from 'twenty-shared/constants';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import {
|
||||
GraphqlQueryBaseResolverService,
|
||||
type GraphqlQueryResolverExecutionArgs,
|
||||
} from 'src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service';
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
|
||||
import { type RestoreOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
|
||||
+1
-1
@@ -1,12 +1,12 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { QUERY_MAX_RECORDS } from 'twenty-shared/constants';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import {
|
||||
GraphqlQueryBaseResolverService,
|
||||
type GraphqlQueryResolverExecutionArgs,
|
||||
} from 'src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service';
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
|
||||
import { type UpdateManyResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
|
||||
+1
-1
@@ -1,12 +1,12 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { QUERY_MAX_RECORDS } from 'twenty-shared/constants';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import {
|
||||
GraphqlQueryBaseResolverService,
|
||||
type GraphqlQueryResolverExecutionArgs,
|
||||
} from 'src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service';
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
|
||||
import { type UpdateOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
|
||||
+3
-4
@@ -1,7 +1,6 @@
|
||||
import {
|
||||
type ObjectRecord,
|
||||
type ObjectRecordOrderBy,
|
||||
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import { type ObjectRecordOrderBy } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type FindManyResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||
|
||||
import {
|
||||
|
||||
+6
-46
@@ -1,14 +1,9 @@
|
||||
import { type ObjectRecordGroupByDateGranularity } from 'twenty-shared/types';
|
||||
|
||||
//TODO : Refacto-common - Should be moved to common api layer
|
||||
export interface ObjectRecord {
|
||||
id: string;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
[key: string]: any;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
deletedAt: string | null;
|
||||
}
|
||||
import {
|
||||
type ObjectRecord,
|
||||
type ObjectRecordGroupByDateGranularity,
|
||||
type ObjectRecordOrderByForCompositeField,
|
||||
type ObjectRecordOrderByForScalarField,
|
||||
} from 'twenty-shared/types';
|
||||
|
||||
export type ObjectRecordFilter = Partial<{
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@@ -35,45 +30,10 @@ export type ObjectRecordGroupByForDateField = Partial<{
|
||||
};
|
||||
}>;
|
||||
|
||||
export enum OrderByDirection {
|
||||
AscNullsFirst = 'AscNullsFirst',
|
||||
AscNullsLast = 'AscNullsLast',
|
||||
DescNullsFirst = 'DescNullsFirst',
|
||||
DescNullsLast = 'DescNullsLast',
|
||||
}
|
||||
|
||||
export type ObjectRecordOrderBy = Array<
|
||||
ObjectRecordOrderByForScalarField | ObjectRecordOrderByForCompositeField
|
||||
>;
|
||||
|
||||
export type AggregateOrderByWithGroupByField = {
|
||||
aggregate: {
|
||||
[x: string]: OrderByDirection;
|
||||
};
|
||||
};
|
||||
|
||||
export type ObjectRecordOrderByWithGroupByDateField = {
|
||||
[Property in keyof ObjectRecord]?: {
|
||||
orderBy: OrderByDirection;
|
||||
granularity: ObjectRecordGroupByDateGranularity;
|
||||
};
|
||||
};
|
||||
|
||||
export type OrderByWithGroupBy = Array<
|
||||
| ObjectRecordOrderByForScalarField
|
||||
| ObjectRecordOrderByForCompositeField
|
||||
| ObjectRecordOrderByWithGroupByDateField
|
||||
| AggregateOrderByWithGroupByField
|
||||
>;
|
||||
|
||||
export type ObjectRecordOrderByForScalarField = {
|
||||
[Property in keyof ObjectRecord]?: OrderByDirection;
|
||||
};
|
||||
|
||||
export type ObjectRecordOrderByForCompositeField = {
|
||||
[Property in keyof ObjectRecord]?: Record<string, OrderByDirection>;
|
||||
};
|
||||
|
||||
export type ObjectRecordCursorLeafScalarValue = string | number | boolean;
|
||||
export type ObjectRecordCursorLeafCompositeValue = Record<
|
||||
string,
|
||||
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import { type QueryResultFieldValue } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/interfaces/query-result-field-value';
|
||||
import { type IConnection } from 'src/engine/api/graphql/workspace-query-runner/interfaces/connection.interface';
|
||||
import { type IEdge } from 'src/engine/api/graphql/workspace-query-runner/interfaces/edge.interface';
|
||||
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import { type QueryResultFieldValue } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/interfaces/query-result-field-value';
|
||||
|
||||
export const isQueryResultFieldValueANestedRecordArray = (
|
||||
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import { type QueryResultFieldValue } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/interfaces/query-result-field-value';
|
||||
|
||||
export const isQueryResultFieldValueARecordArray = (
|
||||
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import { type QueryResultFieldValue } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/interfaces/query-result-field-value';
|
||||
|
||||
export const isQueryResultFieldValueARecord = (
|
||||
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import { type IConnection } from 'src/engine/api/graphql/workspace-query-runner/interfaces/connection.interface';
|
||||
|
||||
export type QueryResultFieldValue =
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
export interface QueryResultGetterHandlerInterface {
|
||||
handle(
|
||||
|
||||
+1
-2
@@ -1,9 +1,8 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { FieldMetadataType, type ObjectRecord } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type QueryResultFieldValue } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/interfaces/query-result-field-value';
|
||||
import { type QueryResultGetterHandlerInterface } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/interfaces/query-result-getter-handler.interface';
|
||||
import { type IConnection } from 'src/engine/api/graphql/workspace-query-runner/interfaces/connection.interface';
|
||||
|
||||
+2
-5
@@ -1,12 +1,9 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { FieldMetadataType, ObjectRecord } from 'twenty-shared/types';
|
||||
import { assertIsDefinedOrThrow, isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import {
|
||||
type ObjectRecord,
|
||||
type ObjectRecordFilter,
|
||||
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type ObjectRecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
|
||||
import {
|
||||
type CreateManyResolverArgs,
|
||||
|
||||
+1
-1
@@ -3,9 +3,9 @@ import { DiscoveryService, ModuleRef, createContextId } from '@nestjs/core';
|
||||
import { Injector } from '@nestjs/core/injector/injector';
|
||||
import { type Module } from '@nestjs/core/injector/module';
|
||||
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
import { assertIsDefinedOrThrow } from 'twenty-shared/utils';
|
||||
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type QueryResultFieldValue } from 'src/engine/api/graphql/workspace-query-runner/factories/query-result-getters/interfaces/query-result-field-value';
|
||||
import {
|
||||
type WorkspacePostQueryHookInstance,
|
||||
|
||||
+4
-2
@@ -1,11 +1,13 @@
|
||||
import { type GraphQLFieldResolver } from 'graphql';
|
||||
|
||||
import {
|
||||
type ObjectRecord,
|
||||
type OrderByWithGroupBy,
|
||||
} from 'twenty-shared/types';
|
||||
|
||||
import {
|
||||
type ObjectRecordFilter,
|
||||
type ObjectRecordGroupBy,
|
||||
type ObjectRecordOrderBy,
|
||||
type OrderByWithGroupBy,
|
||||
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
import { type workspaceResolverBuilderMethodNames } from 'src/engine/api/graphql/workspace-resolver-builder/factories/factories';
|
||||
|
||||
+1
-1
@@ -2,9 +2,9 @@ import { BadRequestException, Injectable } from '@nestjs/common';
|
||||
|
||||
import { type Request } from 'express';
|
||||
import isEmpty from 'lodash.isempty';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
import { In } from 'typeorm';
|
||||
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import {
|
||||
type FormatResult,
|
||||
RestApiBaseHandler,
|
||||
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import {
|
||||
PageInfo,
|
||||
RestApiBaseHandler,
|
||||
|
||||
+1
-1
@@ -1,8 +1,8 @@
|
||||
import { BadRequestException, Injectable } from '@nestjs/common';
|
||||
|
||||
import { ObjectRecord } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { RestApiBaseHandler } from 'src/engine/api/rest/core/interfaces/rest-api-base.handler';
|
||||
|
||||
import { CommonFindOneQueryRunnerService } from 'src/engine/api/common/common-query-runners/common-find-one-query-runner.service';
|
||||
|
||||
@@ -4,16 +4,14 @@ import chunk from 'lodash.chunk';
|
||||
import isEmpty from 'lodash.isempty';
|
||||
import {
|
||||
FieldMetadataType,
|
||||
ObjectRecord,
|
||||
type RestrictedFieldsPermissions,
|
||||
} from 'twenty-shared/types';
|
||||
import { capitalize, isDefined } from 'twenty-shared/utils';
|
||||
import { In, type ObjectLiteral } from 'typeorm';
|
||||
|
||||
import { WorkspaceAuthContext } from 'src/engine/api/common/interfaces/workspace-auth-context.interface';
|
||||
import {
|
||||
type ObjectRecord,
|
||||
type ObjectRecordFilter,
|
||||
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type ObjectRecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
import { GraphqlQueryParser } from 'src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query.parser';
|
||||
import { encodeCursor } from 'src/engine/api/graphql/graphql-query-runner/utils/cursors.util';
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { Test, type TestingModule } from '@nestjs/testing';
|
||||
|
||||
import { OrderByDirection } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { OrderByDirection } from 'twenty-shared/types';
|
||||
|
||||
import {
|
||||
objectMetadataMapItemMock,
|
||||
|
||||
+2
-4
@@ -1,11 +1,9 @@
|
||||
import { BadRequestException, Injectable } from '@nestjs/common';
|
||||
|
||||
import { type Request } from 'express';
|
||||
import { OrderByDirection } from 'twenty-shared/types';
|
||||
|
||||
import {
|
||||
type ObjectRecordOrderBy,
|
||||
OrderByDirection,
|
||||
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { ObjectRecordOrderBy } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
import { checkFields } from 'src/engine/api/rest/core/query-builder/utils/check-fields.utils';
|
||||
import { type ObjectMetadataItemWithFieldMaps } from 'src/engine/metadata-modules/types/object-metadata-item-with-field-maps';
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { OrderByDirection } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { OrderByDirection } from 'twenty-shared/types';
|
||||
|
||||
import { parseOrderByRestRequest } from 'src/engine/api/rest/input-request-parsers/order-by-parser-utils/parse-order-by-rest-request.util';
|
||||
|
||||
|
||||
+3
-4
@@ -1,7 +1,6 @@
|
||||
import {
|
||||
type ObjectRecordOrderBy,
|
||||
OrderByDirection,
|
||||
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { OrderByDirection } from 'twenty-shared/types';
|
||||
|
||||
import { type ObjectRecordOrderBy } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
export const addDefaultOrderById = (orderBy: ObjectRecordOrderBy) => {
|
||||
const hasIdOrder = orderBy.some((o) => Object.keys(o).includes('id'));
|
||||
|
||||
+3
-4
@@ -2,10 +2,9 @@
|
||||
|
||||
import { BadRequestException } from '@nestjs/common';
|
||||
|
||||
import {
|
||||
type ObjectRecordOrderBy,
|
||||
OrderByDirection,
|
||||
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { OrderByDirection } from 'twenty-shared/types';
|
||||
|
||||
import { type ObjectRecordOrderBy } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
import { DEFAULT_ORDER_DIRECTION } from 'src/engine/api/rest/input-factories/order-by-input.factory';
|
||||
import { addDefaultOrderById } from 'src/engine/api/rest/input-request-parsers/order-by-parser-utils/add-default-order-by-id.util';
|
||||
|
||||
+2
-5
@@ -1,10 +1,7 @@
|
||||
import { type EachTestingContext } from 'twenty-shared/testing';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { FieldMetadataType, OrderByDirection } from 'twenty-shared/types';
|
||||
|
||||
import {
|
||||
type ObjectRecordOrderBy,
|
||||
OrderByDirection,
|
||||
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type ObjectRecordOrderBy } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
import { buildCursorCompositeFieldWhereCondition } from 'src/engine/api/utils/build-cursor-composite-field-where-condition.utils';
|
||||
|
||||
|
||||
+1
-3
@@ -1,6 +1,4 @@
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
import { OrderByDirection } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { FieldMetadataType, OrderByDirection } from 'twenty-shared/types';
|
||||
|
||||
import { GraphqlQueryRunnerException } from 'src/engine/api/graphql/graphql-query-runner/errors/graphql-query-runner.exception';
|
||||
import { computeCursorArgFilter } from 'src/engine/api/utils/compute-cursor-arg-filter.utils';
|
||||
|
||||
+1
-2
@@ -1,8 +1,7 @@
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { FieldMetadataType, type ObjectRecord } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import {
|
||||
type ObjectRecord,
|
||||
type ObjectRecordCursorLeafCompositeValue,
|
||||
type ObjectRecordFilter,
|
||||
type ObjectRecordOrderBy,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import {
|
||||
type ObjectRecord,
|
||||
type ObjectRecordCursorLeafCompositeValue,
|
||||
type ObjectRecordCursorLeafScalarValue,
|
||||
type ObjectRecordOrderBy,
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import isEmpty from 'lodash.isempty';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import {
|
||||
type ObjectRecord,
|
||||
type ObjectRecordFilter,
|
||||
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type ObjectRecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
import { settings } from 'src/engine/constants/settings';
|
||||
import { type ObjectMetadataItemWithFieldMaps } from 'src/engine/metadata-modules/types/object-metadata-item-with-field-maps';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { OrderByDirection } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { OrderByDirection } from 'twenty-shared/types';
|
||||
|
||||
export const isAscendingOrder = (direction: OrderByDirection): boolean =>
|
||||
direction === OrderByDirection.AscNullsFirst ||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import {
|
||||
type ObjectRecord,
|
||||
type ObjectRecordOrderBy,
|
||||
type ObjectRecordOrderByForCompositeField,
|
||||
type ObjectRecordOrderByForScalarField,
|
||||
OrderByDirection,
|
||||
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
} from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type ObjectRecordOrderBy } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
import {
|
||||
GraphqlQueryRunnerException,
|
||||
|
||||
+1
-2
@@ -1,6 +1,5 @@
|
||||
import deepEqual from 'deep-equal';
|
||||
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import { type BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity';
|
||||
|
||||
|
||||
+1
-3
@@ -1,7 +1,5 @@
|
||||
import deepEqual from 'deep-equal';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { FieldMetadataType, type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import { type ObjectMetadataItemWithFieldMaps } from 'src/engine/metadata-modules/types/object-metadata-item-with-field-maps';
|
||||
|
||||
|
||||
+1
-2
@@ -2,8 +2,7 @@ import {
|
||||
QUERY_DEFAULT_LIMIT_RECORDS,
|
||||
QUERY_MAX_RECORDS,
|
||||
} from 'twenty-shared/constants';
|
||||
|
||||
import { OrderByDirection } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { OrderByDirection } from 'twenty-shared/types';
|
||||
|
||||
import {
|
||||
computeDepthParameters,
|
||||
|
||||
@@ -3,8 +3,7 @@ import {
|
||||
QUERY_DEFAULT_LIMIT_RECORDS,
|
||||
QUERY_MAX_RECORDS,
|
||||
} from 'twenty-shared/constants';
|
||||
|
||||
import { OrderByDirection } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { OrderByDirection } from 'twenty-shared/types';
|
||||
|
||||
export const computeLimitParameters = (
|
||||
fromMetadata = false,
|
||||
|
||||
+1
-1
@@ -1,12 +1,12 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
|
||||
import { QUERY_MAX_RECORDS } from 'twenty-shared/constants';
|
||||
import { OrderByDirection } from 'twenty-shared/types';
|
||||
import { type ObjectLiteral } from 'typeorm';
|
||||
|
||||
import {
|
||||
type ObjectRecordFilter,
|
||||
type ObjectRecordOrderBy,
|
||||
OrderByDirection,
|
||||
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
import { GraphqlQueryParser } from 'src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query.parser';
|
||||
|
||||
+1
-2
@@ -1,10 +1,9 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { isNumber } from '@sniptt/guards';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
|
||||
export type RecordPositionServiceCreateArgs = {
|
||||
|
||||
@@ -2,14 +2,11 @@ import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import chunk from 'lodash.chunk';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import { FieldMetadataType, ObjectRecord } from 'twenty-shared/types';
|
||||
import { getLogoUrlFromDomainName } from 'twenty-shared/utils';
|
||||
import { Brackets, type ObjectLiteral } from 'typeorm';
|
||||
|
||||
import {
|
||||
type ObjectRecord,
|
||||
type ObjectRecordFilter,
|
||||
} from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type ObjectRecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
import { GraphqlQueryParser } from 'src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query.parser';
|
||||
import {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import { type ObjectMetadataItemWithFieldMaps } from 'src/engine/metadata-modules/types/object-metadata-item-with-field-maps';
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { Field, ObjectType, registerEnumType } from '@nestjs/graphql';
|
||||
|
||||
import GraphQLJSON from 'graphql-type-json';
|
||||
|
||||
import { ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action';
|
||||
|
||||
|
||||
+1
-2
@@ -1,10 +1,9 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { isDefined } from 'class-validator';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
import { In, MoreThan } from 'typeorm';
|
||||
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
import { objectRecordDiffMerge } from 'src/engine/core-modules/event-emitter/utils/object-record-diff-merge';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
import { type TimelineActivityPayload } from 'src/modules/timeline/types/timeline-activity-payload';
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { In } from 'typeorm';
|
||||
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
import { type ObjectRecordBaseEvent } from 'src/engine/core-modules/event-emitter/types/object-record.base.event';
|
||||
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
import { WorkspaceEventBatch } from 'src/engine/workspace-event-emitter/types/workspace-event-batch.type';
|
||||
import { parseEventNameOrThrow } from 'src/engine/workspace-event-emitter/utils/parse-event-name';
|
||||
import { TimelineActivityRepository } from 'src/modules/timeline/repositories/timeline-activity.repository';
|
||||
import { TimelineActivityWorkspaceEntity } from 'src/modules/timeline/standard-objects/timeline-activity.workspace-entity';
|
||||
import { type TimelineActivityPayload } from 'src/modules/timeline/types/timeline-activity-payload';
|
||||
import { WorkspaceEventBatch } from 'src/engine/workspace-event-emitter/types/workspace-event-batch.type';
|
||||
|
||||
type ActivityType = 'note' | 'task';
|
||||
|
||||
|
||||
+1
-2
@@ -1,10 +1,9 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { In, Raw } from 'typeorm';
|
||||
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
import { OnDatabaseBatchEvent } from 'src/engine/api/graphql/graphql-query-runner/decorators/on-database-batch-event.decorator';
|
||||
import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action';
|
||||
import { type ObjectRecordCreateEvent } from 'src/engine/core-modules/event-emitter/types/object-record-create.event';
|
||||
|
||||
+1
-2
@@ -13,8 +13,7 @@ import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graph
|
||||
import { performCreateManyOperation } from 'test/integration/graphql/utils/perform-create-many-operation.utils';
|
||||
import { updateManyOperationFactory } from 'test/integration/graphql/utils/update-many-operation-factory.util';
|
||||
import { updateOneOperationFactory } from 'test/integration/graphql/utils/update-one-operation-factory.util';
|
||||
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||
|
||||
|
||||
@@ -3,10 +3,9 @@ import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graph
|
||||
import { type CommonResponseBody } from 'test/integration/metadata/types/common-response-body.type';
|
||||
import { type PerformMetadataQueryParams } from 'test/integration/metadata/types/perform-metadata-query.type';
|
||||
import { warnIfNoErrorButExpectedToFail } from 'test/integration/metadata/utils/warn-if-no-error-but-expected-to-fail.util';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
import { capitalize } from 'twenty-shared/utils';
|
||||
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
type CreateOneOperationArgs<T> = PerformMetadataQueryParams<T> & {
|
||||
objectMetadataSingularName: string;
|
||||
};
|
||||
|
||||
@@ -2,8 +2,7 @@ import { findOneOperationFactory } from 'test/integration/graphql/utils/find-one
|
||||
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
||||
import { type CommonResponseBody } from 'test/integration/metadata/types/common-response-body.type';
|
||||
import { warnIfNoErrorButExpectedToFail } from 'test/integration/metadata/utils/warn-if-no-error-but-expected-to-fail.util';
|
||||
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
|
||||
type FindOneOperationArgs = Parameters<typeof findOneOperationFactory>[0] & {
|
||||
expectToFail?: boolean;
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
||||
import { updateOneOperationFactory } from 'test/integration/graphql/utils/update-one-operation-factory.util';
|
||||
import { type CommonResponseBody } from 'test/integration/metadata/types/common-response-body.type';
|
||||
import { type PerformMetadataQueryParams } from 'test/integration/metadata/types/perform-metadata-query.type';
|
||||
import { warnIfNoErrorButExpectedToFail } from 'test/integration/metadata/utils/warn-if-no-error-but-expected-to-fail.util';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
import { capitalize } from 'twenty-shared/utils';
|
||||
import { updateOneOperationFactory } from 'test/integration/graphql/utils/update-one-operation-factory.util';
|
||||
|
||||
import { type ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
||||
|
||||
type UpdateOneOperationArgs<T> = PerformMetadataQueryParams<T> & {
|
||||
objectMetadataSingularName: string;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
export interface ObjectRecord {
|
||||
id: string;
|
||||
|
||||
[key: string]: any;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
deletedAt: string | null;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import { type ObjectRecord } from '@/types/ObjectRecord';
|
||||
import { type ObjectRecordGroupByDateGranularity } from '@/types/ObjectRecordGroupByDateGranularity';
|
||||
|
||||
export enum OrderByDirection {
|
||||
AscNullsFirst = 'AscNullsFirst',
|
||||
AscNullsLast = 'AscNullsLast',
|
||||
DescNullsFirst = 'DescNullsFirst',
|
||||
DescNullsLast = 'DescNullsLast',
|
||||
}
|
||||
|
||||
export type AggregateOrderByWithGroupByField = {
|
||||
aggregate: {
|
||||
[x: string]: OrderByDirection;
|
||||
};
|
||||
};
|
||||
|
||||
export type ObjectRecordOrderByWithGroupByDateField = {
|
||||
[Property in keyof ObjectRecord]?: {
|
||||
orderBy: OrderByDirection;
|
||||
granularity: ObjectRecordGroupByDateGranularity;
|
||||
};
|
||||
};
|
||||
|
||||
export type OrderByWithGroupBy = Array<
|
||||
| ObjectRecordOrderByForScalarField
|
||||
| ObjectRecordOrderByForCompositeField
|
||||
| ObjectRecordOrderByWithGroupByDateField
|
||||
| AggregateOrderByWithGroupByField
|
||||
>;
|
||||
|
||||
export type ObjectRecordOrderByForScalarField = {
|
||||
[Property in keyof ObjectRecord]?: OrderByDirection;
|
||||
};
|
||||
|
||||
export type ObjectRecordOrderByForCompositeField = {
|
||||
[Property in keyof ObjectRecord]?: Record<string, OrderByDirection>;
|
||||
};
|
||||
@@ -34,6 +34,15 @@ export type { Nullable } from './Nullable';
|
||||
export type { NullablePartial } from './NullablePartial';
|
||||
export type { ObjectPermissions } from './ObjectPermissions';
|
||||
export type { ObjectPermissionsDeprecated } from './ObjectPermissionsDeprecated';
|
||||
export type { ObjectRecord } from './ObjectRecord';
|
||||
export type {
|
||||
AggregateOrderByWithGroupByField,
|
||||
ObjectRecordOrderByWithGroupByDateField,
|
||||
OrderByWithGroupBy,
|
||||
ObjectRecordOrderByForScalarField,
|
||||
ObjectRecordOrderByForCompositeField,
|
||||
} from './ObjectRecordGroupBy';
|
||||
export { OrderByDirection } from './ObjectRecordGroupBy';
|
||||
export { ObjectRecordGroupByDateGranularity } from './ObjectRecordGroupByDateGranularity';
|
||||
export type { ObjectsPermissions } from './ObjectsPermissions';
|
||||
export type { ObjectsPermissionsByRoleId } from './ObjectsPermissionsByRoleId';
|
||||
|
||||
Reference in New Issue
Block a user