part 2 of filter/sort drill down from charts (#16013)
in this PR, we will handle simple filter translations (ie, fields that use the contains operand)
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { isCompositeFieldType } from '@/object-record/object-filter-dropdown/utils/isCompositeFieldType';
|
||||
import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { type UrlSingleFilter } from '@/views/types/UrlSingleFilter';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { isDefined, isExpectedSubFieldName } from 'twenty-shared/utils';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
export const convertUrlSingleFilterToRecordFilter = ({
|
||||
urlSingleFilter,
|
||||
objectMetadataItem,
|
||||
recordFilterGroupId,
|
||||
positionInGroup,
|
||||
}: {
|
||||
urlSingleFilter: UrlSingleFilter;
|
||||
objectMetadataItem: ObjectMetadataItem;
|
||||
recordFilterGroupId?: string;
|
||||
positionInGroup: number;
|
||||
}): RecordFilter | null => {
|
||||
const fieldMetadataItem = objectMetadataItem.fields.find(
|
||||
(field) => field.name === urlSingleFilter.field,
|
||||
);
|
||||
|
||||
if (!isDefined(fieldMetadataItem)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isNonEmptyString(urlSingleFilter.subField)) {
|
||||
if (!isCompositeFieldType(fieldMetadataItem.type)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (
|
||||
!isExpectedSubFieldName(
|
||||
fieldMetadataItem.type as Parameters<typeof isExpectedSubFieldName>[0],
|
||||
urlSingleFilter.subField as Parameters<
|
||||
typeof isExpectedSubFieldName
|
||||
>[1],
|
||||
urlSingleFilter.subField,
|
||||
)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const displayValue = urlSingleFilter.value;
|
||||
|
||||
const recordFilter: RecordFilter = {
|
||||
id: uuidv4(),
|
||||
fieldMetadataId: fieldMetadataItem.id,
|
||||
value: urlSingleFilter.value,
|
||||
displayValue,
|
||||
type: fieldMetadataItem.type as RecordFilter['type'],
|
||||
operand: urlSingleFilter.op,
|
||||
label: fieldMetadataItem.label,
|
||||
positionInRecordFilterGroup: positionInGroup,
|
||||
};
|
||||
|
||||
if (isDefined(recordFilterGroupId)) {
|
||||
recordFilter.recordFilterGroupId = recordFilterGroupId;
|
||||
}
|
||||
|
||||
if (isNonEmptyString(urlSingleFilter.subField)) {
|
||||
recordFilter.subFieldName =
|
||||
urlSingleFilter.subField as RecordFilter['subFieldName'];
|
||||
}
|
||||
|
||||
return recordFilter;
|
||||
};
|
||||
@@ -0,0 +1,85 @@
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup';
|
||||
import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { type UrlFilterDeserializationResult } from '@/views/types/UrlFilterDeserializationResult';
|
||||
import { type UrlRecursiveFilterGroup } from '@/views/types/UrlRecursiveFilterGroup';
|
||||
import { convertUrlSingleFilterToRecordFilter } from '@/views/utils/convertUrlSingleFilterToRecordFilter';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
export const deserializeUrlRecursiveFilterGroup = ({
|
||||
urlRecursiveFilterGroup,
|
||||
objectMetadataItem,
|
||||
parentGroupId,
|
||||
positionInParent,
|
||||
}: {
|
||||
urlRecursiveFilterGroup: UrlRecursiveFilterGroup;
|
||||
objectMetadataItem: ObjectMetadataItem;
|
||||
parentGroupId?: string;
|
||||
positionInParent: number;
|
||||
}): UrlFilterDeserializationResult => {
|
||||
const groupId = uuidv4();
|
||||
const recordFilters: RecordFilter[] = [];
|
||||
const recordFilterGroups: RecordFilterGroup[] = [];
|
||||
const groupFilters: RecordFilter[] = [];
|
||||
|
||||
let positionCounter = 0;
|
||||
|
||||
if (isDefined(urlRecursiveFilterGroup.filters)) {
|
||||
for (const urlSingleFilter of urlRecursiveFilterGroup.filters) {
|
||||
const recordFilter = convertUrlSingleFilterToRecordFilter({
|
||||
urlSingleFilter,
|
||||
objectMetadataItem,
|
||||
recordFilterGroupId: groupId,
|
||||
positionInGroup: positionCounter++,
|
||||
});
|
||||
|
||||
if (isDefined(recordFilter)) {
|
||||
groupFilters.push(recordFilter);
|
||||
recordFilters.push(recordFilter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const childGroupResults: RecordFilterGroup[] = [];
|
||||
if (isDefined(urlRecursiveFilterGroup.groups)) {
|
||||
for (const childUrlGroup of urlRecursiveFilterGroup.groups) {
|
||||
const childResult = deserializeUrlRecursiveFilterGroup({
|
||||
urlRecursiveFilterGroup: childUrlGroup,
|
||||
objectMetadataItem,
|
||||
parentGroupId: groupId,
|
||||
positionInParent: positionCounter++,
|
||||
});
|
||||
|
||||
if (
|
||||
childResult.recordFilters.length > 0 ||
|
||||
childResult.recordFilterGroups.length > 0
|
||||
) {
|
||||
recordFilters.push(...childResult.recordFilters);
|
||||
childGroupResults.push(...childResult.recordFilterGroups);
|
||||
recordFilterGroups.push(...childResult.recordFilterGroups);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const hasContent = groupFilters.length > 0 || childGroupResults.length > 0;
|
||||
|
||||
if (hasContent) {
|
||||
const currentGroup: RecordFilterGroup = {
|
||||
id: groupId,
|
||||
logicalOperator: urlRecursiveFilterGroup.operator,
|
||||
positionInRecordFilterGroup: positionInParent,
|
||||
};
|
||||
|
||||
if (isDefined(parentGroupId)) {
|
||||
currentGroup.parentRecordFilterGroupId = parentGroupId;
|
||||
}
|
||||
|
||||
recordFilterGroups.push(currentGroup);
|
||||
}
|
||||
|
||||
return {
|
||||
recordFilters,
|
||||
recordFilterGroups,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
export const splitFieldNameIntoBaseAndSubField = (
|
||||
fieldName: string,
|
||||
): {
|
||||
baseFieldName: string;
|
||||
subFieldName?: string;
|
||||
} => {
|
||||
const fieldParts = fieldName.split('.');
|
||||
const baseFieldName = fieldParts[0];
|
||||
const subFieldName =
|
||||
fieldParts.length > 1 ? fieldParts.slice(1).join('.') : undefined;
|
||||
|
||||
return {
|
||||
baseFieldName,
|
||||
subFieldName,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user