fix(filter): resolve filter-derived date defaults with Temporal (fixes create/update crash in date-filtered views) (#22124)
## Symptom
Creating or updating an Opportunity on a board view crashes with:
```
Uncaught TypeError: e.split is not a function
at splitDateString (date-fns) → parseISO → isMatchingDateFilter
→ isRecordMatchingFilter → <group-by optimistic effect> → createOneRecord
```
`e` is a non-string (a `Date` object, shown as `{}` in the debugger).
Distinct from the `null` case fixed in #22029.
## Root cause
Reproduced on a live board filtered by **Close date — Is relative —
"This quarter"** (a `DATE_TIME` field).
When you create a record in a filtered view, `useCreateNewIndexRecord`
derives default field values from the view's filters via
`buildRecordInputFromFilter` → `buildValueFromFilter`. For a date field,
`computeValueFromFilterDate` returned a JS **`Date` object** (`new
Date()` / `new Date(value)`), assigned to the new record verbatim. The
optimistic record's `closeDate` was then a `Date`, not an ISO string,
and the group-by optimistic effect matched it via `parseISO(dateObject)`
→ `dateString.split is not a function`, crashing every create/update in
the view.
## Fix
`computeValueFromFilterDate` now returns timezone-aware **ISO strings**
via Temporal, mirroring what `turnRecordFilterIntoGqlOperationFilter`
produces for the same filters — so a record created in a date-filtered
view actually satisfies its own filter:
- **`DATE_TIME`** → an instant. Date-only filter values (a `DATE_TIME`
"is" filter stores `yyyy-MM-dd`, no time) are resolved to the start of
day in the user's time zone, matching how the filter operands are built
— `Temporal.Instant.from()` alone would `RangeError` on them.
- **`DATE`** → a plain date `yyyy-MM-dd` resolved in the **user's time
zone** (`Temporal.Now.plainDateISO(timeZone)`). A bare `new
Date().toISOString()` would use the UTC date, which near midnight is the
wrong calendar day for non-UTC users, so the new record could miss its
own `IS_TODAY`/relative filter. The time zone is threaded from
`useUserTimezone` (same source the filter side uses).
- `IS_BEFORE` subtracts 1 day for `DATE` / 1 minute for `DATE_TIME` (the
`-1 minute` special-case moved out of `buildRecordInputFromFilter`,
which now just assigns the string).
No `Date` object ever reaches `parseISO`, and the value matches the
filter operand, so the optimistic card lands in the right place.
## Tests
- `buildValueFromFilter.spec.ts`: every date operator returns an ISO
**string** (round-tripped to the expected instant); a `DATE` block
asserts date-only `yyyy-MM-dd` output and that `IS_TODAY` resolves to
the correct calendar day **per time zone** at a UTC day boundary
(`2024-03-20` UTC vs `2024-03-21` Asia/Tokyo); a date-only `DATE_TIME`
`IS` value resolves to start-of-day in the user time zone (UTC vs
America/New_York) without throwing.
- `buildRecordInputFromFilter.test.ts`: filter-derived date values are
ISO strings, not `Date` objects.
## Verified locally (Chrome)
Reproduced the exact prod scenario on the **By Stage Opportunities
Kanban board** (the group-by optimistic effect) with a **Close date — Is
relative** filter:
- Created a card in a column → **no `split is not a function` crash**;
the card got a valid Close date (`now` for the relative filter, e.g. `25
Jun 2026 13:10`). Console clean.
- Also verified a **table view + Close date — Is** filter: created
record gets a valid start-of-day value (`25 Jun 2026 00:00`).
Both `IS_RELATIVE` (→ now instant) and the date-only `IS` (→
start-of-day in the user tz) paths produce string values that the
optimistic matcher handles without throwing.
This commit is contained in:
+4
@@ -14,6 +14,7 @@ import { buildRecordInputFromFilter } from '@/object-record/record-table/utils/b
|
||||
import { buildCompositeValueFromSubField } from '@/object-record/record-table/utils/buildValueFromFilter';
|
||||
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { isUndefined } from '@sniptt/guards';
|
||||
import { useUserTimezone } from '@/ui/input/components/internal/date/hooks/useUserTimezone';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { isDefined, isPlainObject } from 'twenty-shared/utils';
|
||||
|
||||
@@ -29,6 +30,8 @@ export const useBuildRecordInputFromRLSPredicates = ({
|
||||
}) => {
|
||||
const currentWorkspaceMember = useAtomStateValue(currentWorkspaceMemberState);
|
||||
|
||||
const { userTimezone } = useUserTimezone();
|
||||
|
||||
const { record: currentWorkspaceMemberRecord } = useFindOneRecord({
|
||||
objectNameSingular: CoreObjectNameSingular.WorkspaceMember,
|
||||
objectRecordId: currentWorkspaceMember?.id,
|
||||
@@ -177,6 +180,7 @@ export const useBuildRecordInputFromRLSPredicates = ({
|
||||
currentRecordFilters: staticFilters,
|
||||
objectMetadataItem,
|
||||
currentWorkspaceMember: currentWorkspaceMember ?? undefined,
|
||||
timeZone: userTimezone,
|
||||
});
|
||||
|
||||
const mergedRecordInput: Partial<ObjectRecord> = {
|
||||
|
||||
+4
@@ -5,6 +5,7 @@ import { currentRecordFiltersComponentState } from '@/object-record/record-filte
|
||||
import { buildRecordInputFromFilter } from '@/object-record/record-table/utils/buildRecordInputFromFilter';
|
||||
|
||||
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { useUserTimezone } from '@/ui/input/components/internal/date/hooks/useUserTimezone';
|
||||
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { useContext } from 'react';
|
||||
@@ -25,12 +26,15 @@ export const useBuildRecordInputFromFilters = ({
|
||||
|
||||
const { currentRecordId } = useContext(RecordFilterValueDependenciesContext);
|
||||
|
||||
const { userTimezone } = useUserTimezone();
|
||||
|
||||
const buildRecordInputFromFilters = (): Partial<ObjectRecord> => {
|
||||
return buildRecordInputFromFilter({
|
||||
currentRecordFilters,
|
||||
objectMetadataItem,
|
||||
currentWorkspaceMember: currentWorkspaceMember ?? undefined,
|
||||
currentRecordId,
|
||||
timeZone: userTimezone,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
+36
-2
@@ -62,6 +62,7 @@ describe('buildRecordInputFromFilter', () => {
|
||||
}),
|
||||
],
|
||||
objectMetadataItem: mockObjectMetadataItem,
|
||||
timeZone: 'UTC',
|
||||
});
|
||||
|
||||
expect(result).toEqual({ companyName: 'Acme' });
|
||||
@@ -80,9 +81,13 @@ describe('buildRecordInputFromFilter', () => {
|
||||
}),
|
||||
],
|
||||
objectMetadataItem: mockObjectMetadataItem,
|
||||
timeZone: 'UTC',
|
||||
});
|
||||
|
||||
expect(result.createdAt).toEqual(new Date('2025-06-15T10:29:00.000Z'));
|
||||
expect(typeof result.createdAt).toBe('string');
|
||||
expect(new Date(result.createdAt as string).getTime()).toBe(
|
||||
new Date('2025-06-15T10:29:00.000Z').getTime(),
|
||||
);
|
||||
});
|
||||
|
||||
it('should not subtract a minute for DATE_TIME with IS operand', () => {
|
||||
@@ -98,9 +103,33 @@ describe('buildRecordInputFromFilter', () => {
|
||||
}),
|
||||
],
|
||||
objectMetadataItem: mockObjectMetadataItem,
|
||||
timeZone: 'UTC',
|
||||
});
|
||||
|
||||
expect(result.createdAt).toEqual(filterDate);
|
||||
expect(typeof result.createdAt).toBe('string');
|
||||
expect(new Date(result.createdAt as string).getTime()).toBe(
|
||||
filterDate.getTime(),
|
||||
);
|
||||
});
|
||||
|
||||
it('should assign an ISO string (not a Date) for DATE_TIME with IS_RELATIVE operand', () => {
|
||||
const result = buildRecordInputFromFilter({
|
||||
currentRecordFilters: [
|
||||
createFilter({
|
||||
fieldMetadataId: FIELD_ID_DATE_TIME,
|
||||
type: 'DATE_TIME',
|
||||
operand: ViewFilterOperand.IS_RELATIVE,
|
||||
value: 'THIS_QUARTER',
|
||||
}),
|
||||
],
|
||||
objectMetadataItem: mockObjectMetadataItem,
|
||||
timeZone: 'UTC',
|
||||
});
|
||||
|
||||
expect(typeof result.createdAt).toBe('string');
|
||||
expect(() =>
|
||||
new Date(result.createdAt as string).toISOString(),
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
it('should deep-merge a single composite address sub-field starting from empty object', () => {
|
||||
@@ -115,6 +144,7 @@ describe('buildRecordInputFromFilter', () => {
|
||||
}),
|
||||
],
|
||||
objectMetadataItem: mockObjectMetadataItem,
|
||||
timeZone: 'UTC',
|
||||
});
|
||||
|
||||
expect(result.address).toEqual({ addressCity: 'Paris' });
|
||||
@@ -140,6 +170,7 @@ describe('buildRecordInputFromFilter', () => {
|
||||
}),
|
||||
],
|
||||
objectMetadataItem: mockObjectMetadataItem,
|
||||
timeZone: 'UTC',
|
||||
});
|
||||
|
||||
expect(result.address).toEqual({
|
||||
@@ -159,6 +190,7 @@ describe('buildRecordInputFromFilter', () => {
|
||||
}),
|
||||
],
|
||||
objectMetadataItem: mockObjectMetadataItem,
|
||||
timeZone: 'UTC',
|
||||
});
|
||||
|
||||
expect(result).toEqual({});
|
||||
@@ -175,6 +207,7 @@ describe('buildRecordInputFromFilter', () => {
|
||||
}),
|
||||
],
|
||||
objectMetadataItem: mockObjectMetadataItem,
|
||||
timeZone: 'UTC',
|
||||
});
|
||||
|
||||
expect(result).toEqual({});
|
||||
@@ -191,6 +224,7 @@ describe('buildRecordInputFromFilter', () => {
|
||||
}),
|
||||
],
|
||||
objectMetadataItem: mockObjectMetadataItem,
|
||||
timeZone: 'UTC',
|
||||
});
|
||||
|
||||
expect(result).toEqual({ revenue: 42 });
|
||||
|
||||
+73
-15
@@ -73,65 +73,123 @@ describe('buildValueFromFilter', () => {
|
||||
{
|
||||
operand: ViewFilterOperand.IS,
|
||||
value: '2024-03-20T12:00:00Z',
|
||||
expected: mockDate,
|
||||
expectedMs: mockDate.getTime(),
|
||||
},
|
||||
{
|
||||
operand: ViewFilterOperand.IS_AFTER,
|
||||
value: '2024-03-20T12:00:00Z',
|
||||
expected: mockDate,
|
||||
expectedMs: mockDate.getTime(),
|
||||
},
|
||||
{
|
||||
operand: ViewFilterOperand.IS_BEFORE,
|
||||
value: '2024-03-20T12:00:00Z',
|
||||
expected: mockDate,
|
||||
expectedMs: mockDate.getTime() - 60_000,
|
||||
},
|
||||
{
|
||||
operand: ViewFilterOperand.IS_IN_PAST,
|
||||
value: '2024-03-20T12:00:00Z',
|
||||
expected: mockDate,
|
||||
expectedMs: mockDate.getTime(),
|
||||
},
|
||||
{
|
||||
operand: ViewFilterOperand.IS_IN_FUTURE,
|
||||
value: '2024-03-20T12:00:00Z',
|
||||
expected: mockDate,
|
||||
expectedMs: mockDate.getTime(),
|
||||
},
|
||||
{
|
||||
operand: ViewFilterOperand.IS_TODAY,
|
||||
value: '',
|
||||
expected: mockDate,
|
||||
expectedMs: mockDate.getTime(),
|
||||
},
|
||||
{
|
||||
operand: ViewFilterOperand.IS_RELATIVE,
|
||||
value: '',
|
||||
expected: mockDate,
|
||||
expectedMs: mockDate.getTime(),
|
||||
},
|
||||
{
|
||||
operand: ViewFilterOperand.IS_EMPTY,
|
||||
value: '',
|
||||
expected: undefined,
|
||||
expectedMs: undefined,
|
||||
},
|
||||
{
|
||||
operand: ViewFilterOperand.IS_NOT_EMPTY,
|
||||
value: '2024-03-20T12:00:00Z',
|
||||
expected: mockDate,
|
||||
expectedMs: mockDate.getTime(),
|
||||
},
|
||||
];
|
||||
|
||||
it.each(testCases)(
|
||||
'should handle $operand with value "$value"',
|
||||
({ operand, value, expected }) => {
|
||||
'should return an ISO string for $operand',
|
||||
({ operand, value, expectedMs }) => {
|
||||
const filter = createTestFilter(operand, value, 'DATE_TIME');
|
||||
const result = buildValueFromFilter({ filter });
|
||||
if (expected instanceof Date) {
|
||||
expect(result).toBeInstanceOf(Date);
|
||||
expect(result).toEqual(expected);
|
||||
if (expectedMs === undefined) {
|
||||
expect(result).toBeUndefined();
|
||||
} else {
|
||||
expect(result).toBe(expected);
|
||||
expect(typeof result).toBe('string');
|
||||
expect(new Date(result as string).getTime()).toBe(expectedMs);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('DATE_TIME field type with a date-only filter value', () => {
|
||||
it('resolves a date-only IS value to the start of day in the user time zone', () => {
|
||||
const filter = createTestFilter(
|
||||
ViewFilterOperand.IS,
|
||||
'2024-03-20',
|
||||
'DATE_TIME',
|
||||
);
|
||||
|
||||
const utcResult = buildValueFromFilter({ filter, timeZone: 'UTC' });
|
||||
expect(typeof utcResult).toBe('string');
|
||||
expect(new Date(utcResult as string).getTime()).toBe(
|
||||
new Date('2024-03-20T00:00:00Z').getTime(),
|
||||
);
|
||||
|
||||
const nyResult = buildValueFromFilter({
|
||||
filter,
|
||||
timeZone: 'America/New_York',
|
||||
});
|
||||
expect(new Date(nyResult as string).getTime()).toBe(
|
||||
new Date('2024-03-20T04:00:00Z').getTime(),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('DATE field type', () => {
|
||||
it('returns a date-only string (not a Date or instant) for IS', () => {
|
||||
const filter = createTestFilter(
|
||||
ViewFilterOperand.IS,
|
||||
'2024-03-20',
|
||||
'DATE',
|
||||
);
|
||||
expect(buildValueFromFilter({ filter })).toBe('2024-03-20');
|
||||
});
|
||||
|
||||
it('returns the previous day for IS_BEFORE', () => {
|
||||
const filter = createTestFilter(
|
||||
ViewFilterOperand.IS_BEFORE,
|
||||
'2024-03-20',
|
||||
'DATE',
|
||||
);
|
||||
expect(buildValueFromFilter({ filter })).toBe('2024-03-19');
|
||||
});
|
||||
|
||||
it('resolves IS_TODAY as today in the user time zone (day boundary)', () => {
|
||||
jest.setSystemTime(new Date('2024-03-20T23:30:00Z'));
|
||||
const filter = createTestFilter(ViewFilterOperand.IS_TODAY, '', 'DATE');
|
||||
|
||||
expect(buildValueFromFilter({ filter, timeZone: 'UTC' })).toBe(
|
||||
'2024-03-20',
|
||||
);
|
||||
expect(buildValueFromFilter({ filter, timeZone: 'Asia/Tokyo' })).toBe(
|
||||
'2024-03-21',
|
||||
);
|
||||
|
||||
jest.setSystemTime(mockDate);
|
||||
});
|
||||
});
|
||||
|
||||
describe('NUMBER field type', () => {
|
||||
const testCases = [
|
||||
{
|
||||
|
||||
+5
-12
@@ -1,15 +1,9 @@
|
||||
import { subMinutes } from 'date-fns';
|
||||
|
||||
import { type CurrentWorkspaceMember } from '@/auth/states/currentWorkspaceMemberState';
|
||||
import { type EnrichedObjectMetadataItem } from '@/object-metadata/types/EnrichedObjectMetadataItem';
|
||||
import { isCompositeFieldType } from '@/object-record/object-filter-dropdown/utils/isCompositeFieldType';
|
||||
import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { buildValueFromFilter } from '@/object-record/record-table/utils/buildValueFromFilter';
|
||||
import {
|
||||
FieldMetadataType,
|
||||
ViewFilterOperand,
|
||||
type ObjectRecord,
|
||||
} from 'twenty-shared/types';
|
||||
import { type ObjectRecord } from 'twenty-shared/types';
|
||||
import { deepMerge, isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const buildRecordInputFromFilter = ({
|
||||
@@ -17,11 +11,13 @@ export const buildRecordInputFromFilter = ({
|
||||
objectMetadataItem,
|
||||
currentWorkspaceMember,
|
||||
currentRecordId,
|
||||
timeZone,
|
||||
}: {
|
||||
currentRecordFilters: RecordFilter[];
|
||||
objectMetadataItem: EnrichedObjectMetadataItem;
|
||||
currentWorkspaceMember?: CurrentWorkspaceMember;
|
||||
currentRecordId?: string;
|
||||
timeZone: string;
|
||||
}): Partial<ObjectRecord> => {
|
||||
const recordInput: Partial<ObjectRecord> = {};
|
||||
|
||||
@@ -42,6 +38,7 @@ export const buildRecordInputFromFilter = ({
|
||||
currentWorkspaceMember: currentWorkspaceMember ?? undefined,
|
||||
currentRecordId,
|
||||
label: filter.label,
|
||||
timeZone,
|
||||
});
|
||||
|
||||
if (!isDefined(value)) {
|
||||
@@ -53,6 +50,7 @@ export const buildRecordInputFromFilter = ({
|
||||
const value = buildValueFromFilter({
|
||||
filter,
|
||||
options: fieldMetadataItem.options ?? undefined,
|
||||
timeZone,
|
||||
});
|
||||
|
||||
if (!isDefined(value)) {
|
||||
@@ -64,11 +62,6 @@ export const buildRecordInputFromFilter = ({
|
||||
recordInput[fieldMetadataItem.name] ?? {},
|
||||
value,
|
||||
);
|
||||
} else if (
|
||||
fieldMetadataItem.type === FieldMetadataType.DATE_TIME &&
|
||||
filter.operand === ViewFilterOperand.IS_BEFORE
|
||||
) {
|
||||
recordInput[fieldMetadataItem.name] = subMinutes(value as Date, 1);
|
||||
} else {
|
||||
recordInput[fieldMetadataItem.name] = value;
|
||||
}
|
||||
|
||||
+36
-6
@@ -1,3 +1,5 @@
|
||||
import { Temporal } from 'temporal-polyfill';
|
||||
|
||||
import { type CurrentWorkspaceMember } from '@/auth/states/currentWorkspaceMemberState';
|
||||
import { isCompositeFieldType } from '@/object-record/object-filter-dropdown/utils/isCompositeFieldType';
|
||||
|
||||
@@ -17,6 +19,8 @@ import {
|
||||
assertUnreachable,
|
||||
FILTER_OPERANDS_MAP,
|
||||
parseJson,
|
||||
parseToInstantOrThrow,
|
||||
parseToPlainDateOrThrow,
|
||||
} from 'twenty-shared/utils';
|
||||
import { RelationType } from '~/generated-metadata/graphql';
|
||||
import { convertCurrencyAmountToCurrencyMicros } from '~/utils/convertCurrencyToCurrencyMicros';
|
||||
@@ -37,6 +41,7 @@ type ValueComputeContext = {
|
||||
currentWorkspaceMember?: CurrentWorkspaceMember;
|
||||
currentRecordId?: string;
|
||||
label?: string;
|
||||
timeZone?: string;
|
||||
};
|
||||
|
||||
type ValueHandler = (context: ValueComputeContext) => unknown;
|
||||
@@ -87,22 +92,40 @@ const computeValueFromContainsOperand = (
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: fix this with Temporal
|
||||
const filterDateTimeToInstant = (
|
||||
value: string,
|
||||
timeZone: string,
|
||||
): Temporal.Instant =>
|
||||
value.includes('T')
|
||||
? parseToInstantOrThrow(value)
|
||||
: parseToPlainDateOrThrow(value).toZonedDateTime(timeZone).toInstant();
|
||||
|
||||
const computeValueFromFilterDate = (
|
||||
operand: RecordFilterToRecordInputOperand<'DATE_TIME'>,
|
||||
value: string,
|
||||
) => {
|
||||
isDateOnly: boolean,
|
||||
timeZone = 'UTC',
|
||||
): string | undefined => {
|
||||
switch (operand) {
|
||||
case ViewFilterOperand.IS:
|
||||
case ViewFilterOperand.IS_AFTER:
|
||||
return isDateOnly
|
||||
? parseToPlainDateOrThrow(value).toString()
|
||||
: filterDateTimeToInstant(value, timeZone).toString();
|
||||
case ViewFilterOperand.IS_BEFORE:
|
||||
return new Date(value);
|
||||
return isDateOnly
|
||||
? parseToPlainDateOrThrow(value).subtract({ days: 1 }).toString()
|
||||
: filterDateTimeToInstant(value, timeZone)
|
||||
.subtract({ minutes: 1 })
|
||||
.toString();
|
||||
case ViewFilterOperand.IS_TODAY:
|
||||
case ViewFilterOperand.IS_NOT_EMPTY:
|
||||
case ViewFilterOperand.IS_IN_PAST:
|
||||
case ViewFilterOperand.IS_IN_FUTURE:
|
||||
case ViewFilterOperand.IS_RELATIVE:
|
||||
return new Date();
|
||||
return isDateOnly
|
||||
? Temporal.Now.plainDateISO(timeZone).toString()
|
||||
: Temporal.Now.instant().toString();
|
||||
case ViewFilterOperand.IS_EMPTY:
|
||||
return undefined;
|
||||
default:
|
||||
@@ -300,15 +323,19 @@ const VALUE_HANDLER_REGISTRY: Partial<Record<FieldMetadataType, ValueHandler>> =
|
||||
computeValueFromContainsOperand(operand as ContainsBasedOperand, value),
|
||||
[FieldMetadataType.RAW_JSON]: ({ operand, value }) =>
|
||||
computeValueFromContainsOperand(operand as ContainsBasedOperand, value),
|
||||
[FieldMetadataType.DATE_TIME]: ({ operand, value }) =>
|
||||
[FieldMetadataType.DATE_TIME]: ({ operand, value, timeZone }) =>
|
||||
computeValueFromFilterDate(
|
||||
operand as RecordFilterToRecordInputOperand<'DATE_TIME'>,
|
||||
value,
|
||||
false,
|
||||
timeZone,
|
||||
),
|
||||
[FieldMetadataType.DATE]: ({ operand, value }) =>
|
||||
[FieldMetadataType.DATE]: ({ operand, value, timeZone }) =>
|
||||
computeValueFromFilterDate(
|
||||
operand as RecordFilterToRecordInputOperand<'DATE_TIME'>,
|
||||
value,
|
||||
true,
|
||||
timeZone,
|
||||
),
|
||||
[FieldMetadataType.NUMBER]: ({ operand, value }) =>
|
||||
computeValueFromFilterNumber(
|
||||
@@ -514,6 +541,7 @@ export const buildValueFromFilter = ({
|
||||
currentWorkspaceMember,
|
||||
currentRecordId,
|
||||
label,
|
||||
timeZone,
|
||||
}: {
|
||||
filter: RecordFilter;
|
||||
options?: FilterOption[] | null;
|
||||
@@ -521,6 +549,7 @@ export const buildValueFromFilter = ({
|
||||
currentWorkspaceMember?: CurrentWorkspaceMember;
|
||||
currentRecordId?: string;
|
||||
label?: string;
|
||||
timeZone?: string;
|
||||
}) => {
|
||||
if (isCompositeFieldType(filter.type)) {
|
||||
return buildCompositeValueFromFilter({
|
||||
@@ -553,5 +582,6 @@ export const buildValueFromFilter = ({
|
||||
currentWorkspaceMember,
|
||||
currentRecordId,
|
||||
label,
|
||||
timeZone,
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user