Follow-up high fixes on date refactor (#15553)
This PR fixes important bugs on date filter handling following-up date refactor. Fixes : https://github.com/twentyhq/core-team-issues/issues/1814
This commit is contained in:
+6
-1
@@ -8,6 +8,7 @@ import { isNonEmptyString } from '@sniptt/guards';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { useFieldMetadataItemById } from '@/object-metadata/hooks/useFieldMetadataItemById';
|
||||
import { useGetRecordFilterDisplayValue } from '@/object-record/record-filter/hooks/useGetRecordFilterDisplayValue';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
// TODO: factorize this with https://github.com/twentyhq/core-team-issues/issues/752
|
||||
@@ -38,6 +39,8 @@ export const AdvancedFilterValueInputDropdownButtonClickableSelect = ({
|
||||
currentRecordFiltersComponentState,
|
||||
);
|
||||
|
||||
const { getRecordFilterDisplayValue } = useGetRecordFilterDisplayValue();
|
||||
|
||||
const recordFilter = currentRecordFilters.find(
|
||||
(recordFilter) => recordFilter.id === recordFilterId,
|
||||
);
|
||||
@@ -56,9 +59,11 @@ export const AdvancedFilterValueInputDropdownButtonClickableSelect = ({
|
||||
? getAdvancedFilterInputPlaceholderText(fieldMetadataItem)
|
||||
: 'Enter filter';
|
||||
|
||||
const recordFilterDisplayValue = getRecordFilterDisplayValue(recordFilter);
|
||||
|
||||
const advancedFilterInputText = shouldUsePlaceholder
|
||||
? placeholderText
|
||||
: (recordFilter?.displayValue ?? '');
|
||||
: (recordFilterDisplayValue ?? '');
|
||||
|
||||
const isDateTimeType =
|
||||
recordFilter?.type === 'DATE' || recordFilter?.type === 'DATE_TIME';
|
||||
|
||||
-8
@@ -6,7 +6,6 @@ import {
|
||||
type NonSystemCalendarStartDay,
|
||||
} from '@/localization/utils/detection/detectCalendarStartDay';
|
||||
import { useApplyObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownFilterValue';
|
||||
import { useGetNowInUserTimezoneForRelativeFilter } from '@/object-record/object-filter-dropdown/hooks/useGetNowInUserTimezoneForRelativeFilter';
|
||||
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
|
||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||
import { getRelativeDateDisplayValue } from '@/object-record/object-filter-dropdown/utils/getRelativeDateDisplayValue';
|
||||
@@ -34,9 +33,6 @@ export const ObjectFilterDropdownDateInput = () => {
|
||||
selectedOperandInDropdownComponentState,
|
||||
);
|
||||
|
||||
const { getNowInUserTimezoneForRelativeFilter } =
|
||||
useGetNowInUserTimezoneForRelativeFilter();
|
||||
|
||||
const objectFilterDropdownCurrentRecordFilter = useRecoilComponentValue(
|
||||
objectFilterDropdownCurrentRecordFilterComponentState,
|
||||
);
|
||||
@@ -62,9 +58,6 @@ export const ObjectFilterDropdownDateInput = () => {
|
||||
const handleRelativeDateChange = (
|
||||
relativeDate: RelativeDateFilter | null,
|
||||
) => {
|
||||
const { dayAsStringInUserTimezone } =
|
||||
getNowInUserTimezoneForRelativeFilter();
|
||||
|
||||
const userDefinedCalendarStartDay =
|
||||
CalendarStartDay[
|
||||
currentWorkspaceMember?.calendarStartDay ?? CalendarStartDay.SYSTEM
|
||||
@@ -81,7 +74,6 @@ export const ObjectFilterDropdownDateInput = () => {
|
||||
? stringifyRelativeDateFilter({
|
||||
...relativeDate,
|
||||
timezone: timeZone,
|
||||
referenceDayAsString: dayAsStringInUserTimezone,
|
||||
firstDayOfTheWeek: resolvedCalendarStartDay,
|
||||
})
|
||||
: '';
|
||||
|
||||
+2
-14
@@ -6,9 +6,7 @@ import {
|
||||
type NonSystemCalendarStartDay,
|
||||
} from '@/localization/utils/detection/detectCalendarStartDay';
|
||||
import { useApplyObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownFilterValue';
|
||||
import { useGetNowInUserTimezoneForRelativeFilter } from '@/object-record/object-filter-dropdown/hooks/useGetNowInUserTimezoneForRelativeFilter';
|
||||
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
|
||||
import { selectedOperandInDropdownComponentState } from '@/object-record/object-filter-dropdown/states/selectedOperandInDropdownComponentState';
|
||||
import { getRelativeDateDisplayValue } from '@/object-record/object-filter-dropdown/utils/getRelativeDateDisplayValue';
|
||||
import { DateTimePicker } from '@/ui/input/components/internal/date/components/DateTimePicker';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
@@ -31,10 +29,6 @@ export const ObjectFilterDropdownDateTimeInput = () => {
|
||||
const dateLocale = useRecoilValue(dateLocaleState);
|
||||
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
|
||||
|
||||
const selectedOperandInDropdown = useRecoilComponentValue(
|
||||
selectedOperandInDropdownComponentState,
|
||||
);
|
||||
|
||||
const objectFilterDropdownCurrentRecordFilter = useRecoilComponentValue(
|
||||
objectFilterDropdownCurrentRecordFilterComponentState,
|
||||
);
|
||||
@@ -46,9 +40,6 @@ export const ObjectFilterDropdownDateTimeInput = () => {
|
||||
? resolveDateTimeFilter(objectFilterDropdownCurrentRecordFilter)
|
||||
: null;
|
||||
|
||||
const { getNowInUserTimezoneForRelativeFilter } =
|
||||
useGetNowInUserTimezoneForRelativeFilter();
|
||||
|
||||
const [internalDate, setInternalDate] = useState<Date | null>(
|
||||
initialFilterValue instanceof Date ? initialFilterValue : null,
|
||||
);
|
||||
@@ -74,9 +65,6 @@ export const ObjectFilterDropdownDateTimeInput = () => {
|
||||
const handleRelativeDateChange = (
|
||||
relativeDate: RelativeDateFilter | null,
|
||||
) => {
|
||||
const { dayAsStringInUserTimezone } =
|
||||
getNowInUserTimezoneForRelativeFilter();
|
||||
|
||||
const userDefinedCalendarStartDay =
|
||||
CalendarStartDay[
|
||||
currentWorkspaceMember?.calendarStartDay ?? CalendarStartDay.SYSTEM
|
||||
@@ -93,7 +81,6 @@ export const ObjectFilterDropdownDateTimeInput = () => {
|
||||
? stringifyRelativeDateFilter({
|
||||
...relativeDate,
|
||||
timezone: timeZone,
|
||||
referenceDayAsString: dayAsStringInUserTimezone,
|
||||
firstDayOfTheWeek: resolvedCalendarStartDay,
|
||||
})
|
||||
: '';
|
||||
@@ -106,7 +93,8 @@ export const ObjectFilterDropdownDateTimeInput = () => {
|
||||
};
|
||||
|
||||
const isRelativeOperand =
|
||||
selectedOperandInDropdown === ViewFilterOperand.IS_RELATIVE;
|
||||
objectFilterDropdownCurrentRecordFilter?.operand ===
|
||||
ViewFilterOperand.IS_RELATIVE;
|
||||
|
||||
const handleClear = () => {
|
||||
isRelativeOperand
|
||||
|
||||
-8
@@ -1,6 +1,5 @@
|
||||
import { DATE_OPERANDS_THAT_SHOULD_BE_INITIALIZED_WITH_NOW } from '@/object-record/object-filter-dropdown/constants/DateOperandsThatShouldBeInitializedWithNow';
|
||||
import { useGetInitialFilterValue } from '@/object-record/object-filter-dropdown/hooks/useGetInitialFilterValue';
|
||||
import { useGetNowInUserTimezoneForRelativeFilter } from '@/object-record/object-filter-dropdown/hooks/useGetNowInUserTimezoneForRelativeFilter';
|
||||
import { useUpsertObjectFilterDropdownCurrentFilter } from '@/object-record/object-filter-dropdown/hooks/useUpsertObjectFilterDropdownCurrentFilter';
|
||||
import { fieldMetadataItemUsedInDropdownComponentSelector } from '@/object-record/object-filter-dropdown/states/fieldMetadataItemUsedInDropdownComponentSelector';
|
||||
import { objectFilterDropdownCurrentRecordFilterComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownCurrentRecordFilterComponentState';
|
||||
@@ -49,9 +48,6 @@ export const useApplyObjectFilterDropdownOperand = () => {
|
||||
|
||||
const { userTimezone } = useUserTimezone();
|
||||
|
||||
const { getNowInUserTimezoneForRelativeFilter } =
|
||||
useGetNowInUserTimezoneForRelativeFilter();
|
||||
|
||||
const applyObjectFilterDropdownOperand = (
|
||||
newOperand: RecordFilterOperand,
|
||||
) => {
|
||||
@@ -111,15 +107,11 @@ export const useApplyObjectFilterDropdownOperand = () => {
|
||||
|
||||
recordFilterToUpsert.displayValue = displayValue;
|
||||
} else if (newOperand === RecordFilterOperand.IS_RELATIVE) {
|
||||
const { dayAsStringInUserTimezone } =
|
||||
getNowInUserTimezoneForRelativeFilter();
|
||||
|
||||
const defaultRelativeDate: RelativeDateFilter = {
|
||||
direction: 'THIS' as RelativeDateFilterDirection,
|
||||
amount: 1,
|
||||
unit: 'DAY' as RelativeDateFilterUnit,
|
||||
timezone: userTimezone,
|
||||
referenceDayAsString: dayAsStringInUserTimezone,
|
||||
};
|
||||
|
||||
recordFilterToUpsert.value =
|
||||
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
import { useUserTimezone } from '@/ui/input/components/internal/date/hooks/useUserTimezone';
|
||||
import { TZDate } from '@date-fns/tz';
|
||||
import { format } from 'date-fns';
|
||||
import { DATE_TYPE_FORMAT } from 'twenty-shared/constants';
|
||||
|
||||
export const useGetNowInUserTimezoneForRelativeFilter = () => {
|
||||
const { userTimezone } = useUserTimezone();
|
||||
|
||||
const getNowInUserTimezoneForRelativeFilter = () => {
|
||||
const now = new Date();
|
||||
|
||||
const nowInUserTimezone = new TZDate(
|
||||
now.getFullYear(),
|
||||
now.getMonth(),
|
||||
now.getDate(),
|
||||
userTimezone,
|
||||
);
|
||||
|
||||
const dayAsStringInUserTimezone = format(
|
||||
nowInUserTimezone,
|
||||
DATE_TYPE_FORMAT,
|
||||
);
|
||||
|
||||
return {
|
||||
nowInUserTimezone,
|
||||
dayAsStringInUserTimezone,
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
getNowInUserTimezoneForRelativeFilter,
|
||||
};
|
||||
};
|
||||
+45
-30
@@ -1,6 +1,5 @@
|
||||
import { type FieldMetadataItemOption } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { useGetFieldMetadataItemByIdOrThrow } from '@/object-metadata/hooks/useGetFieldMetadataItemById';
|
||||
import { useGetDateTimeFilterDisplayValue } from '@/object-record/object-filter-dropdown/hooks/useGetDateTimeFilterDisplayValue';
|
||||
import { getOperandLabelShort } from '@/object-record/object-filter-dropdown/utils/getOperandLabel';
|
||||
import { getRelativeDateDisplayValue } from '@/object-record/object-filter-dropdown/utils/getRelativeDateDisplayValue';
|
||||
import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { RecordFilterOperand } from '@/object-record/record-filter/types/RecordFilterOperand';
|
||||
@@ -10,8 +9,10 @@ import { UserContext } from '@/users/contexts/UserContext';
|
||||
import { isValid } from 'date-fns';
|
||||
import { useContext } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { type Nullable } from 'twenty-shared/types';
|
||||
import {
|
||||
getDateFromPlainDate,
|
||||
isDefined,
|
||||
isEmptinessOperand,
|
||||
parseJson,
|
||||
relativeDateFilterStringifiedSchema,
|
||||
@@ -20,25 +21,30 @@ import {
|
||||
import { dateLocaleState } from '~/localization/states/dateLocaleState';
|
||||
import { formatDateString } from '~/utils/string/formatDateString';
|
||||
|
||||
export const useGetRecordFilterLabelValue = () => {
|
||||
// TODO: finish the implementation of this hook to obtain filter display value and remove deprecated display value property
|
||||
export const useGetRecordFilterDisplayValue = () => {
|
||||
const { dateFormat, timeZone } = useContext(UserContext);
|
||||
const dateLocale = useRecoilValue(dateLocaleState);
|
||||
const { userTimezone } = useUserTimezone();
|
||||
|
||||
const { getDateTimeFilterDisplayValue } = useGetDateTimeFilterDisplayValue();
|
||||
|
||||
const getRecordFilterLabelValue = ({
|
||||
recordFilter,
|
||||
fieldMetadataOptions,
|
||||
}: {
|
||||
recordFilter: RecordFilter;
|
||||
fieldMetadataOptions?: FieldMetadataItemOption[];
|
||||
}) => {
|
||||
const operandLabelShort = getOperandLabelShort(recordFilter.operand);
|
||||
const { getFieldMetadataItemByIdOrThrow } =
|
||||
useGetFieldMetadataItemByIdOrThrow();
|
||||
|
||||
const getRecordFilterDisplayValue = (
|
||||
recordFilter?: Nullable<RecordFilter>,
|
||||
) => {
|
||||
if (!isDefined(recordFilter)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const filterType = recordFilter.type;
|
||||
|
||||
const operandIsEmptiness = isEmptinessOperand(recordFilter.operand);
|
||||
const recordFilterIsEmpty = isRecordFilterConsideredEmpty(recordFilter);
|
||||
|
||||
if (recordFilter.type === 'DATE') {
|
||||
if (filterType === 'DATE') {
|
||||
switch (recordFilter.operand) {
|
||||
case RecordFilterOperand.IS: {
|
||||
const date = getDateFromPlainDate(recordFilter.value);
|
||||
@@ -51,7 +57,7 @@ export const useGetRecordFilterLabelValue = () => {
|
||||
);
|
||||
|
||||
if (!isValid(date)) {
|
||||
return `${operandLabelShort}`;
|
||||
return '';
|
||||
}
|
||||
|
||||
const formattedDate = formatDateString({
|
||||
@@ -61,28 +67,28 @@ export const useGetRecordFilterLabelValue = () => {
|
||||
localeCatalog: dateLocale.localeCatalog,
|
||||
});
|
||||
|
||||
return `${operandLabelShort} ${formattedDate}`;
|
||||
return `${formattedDate}`;
|
||||
}
|
||||
case RecordFilterOperand.IS_RELATIVE: {
|
||||
const relativeDateFilter =
|
||||
relativeDateFilterStringifiedSchema.safeParse(recordFilter.value);
|
||||
|
||||
if (!relativeDateFilter.success) {
|
||||
return `${operandLabelShort}`;
|
||||
return ``;
|
||||
}
|
||||
|
||||
const relativeDateDisplayValue = getRelativeDateDisplayValue(
|
||||
relativeDateFilter.data,
|
||||
);
|
||||
|
||||
return `${operandLabelShort} ${relativeDateDisplayValue}`;
|
||||
return ` ${relativeDateDisplayValue}`;
|
||||
}
|
||||
case RecordFilterOperand.IS_TODAY:
|
||||
case RecordFilterOperand.IS_IN_FUTURE:
|
||||
case RecordFilterOperand.IS_IN_PAST:
|
||||
return operandLabelShort;
|
||||
return '';
|
||||
default:
|
||||
return `${operandLabelShort} ${recordFilter.displayValue}`;
|
||||
return ` ${recordFilter.displayValue}`;
|
||||
}
|
||||
} else if (recordFilter.type === 'DATE_TIME') {
|
||||
switch (recordFilter.operand) {
|
||||
@@ -93,28 +99,28 @@ export const useGetRecordFilterLabelValue = () => {
|
||||
|
||||
const { displayValue } = getDateTimeFilterDisplayValue(pointInTime);
|
||||
|
||||
return `${operandLabelShort} ${displayValue}`;
|
||||
return `${displayValue}`;
|
||||
}
|
||||
case RecordFilterOperand.IS_RELATIVE: {
|
||||
const relativeDateFilter =
|
||||
relativeDateFilterStringifiedSchema.safeParse(recordFilter.value);
|
||||
|
||||
if (!relativeDateFilter.success) {
|
||||
return `${operandLabelShort}`;
|
||||
return ``;
|
||||
}
|
||||
|
||||
const relativeDateDisplayValue = getRelativeDateDisplayValue(
|
||||
relativeDateFilter.data,
|
||||
);
|
||||
|
||||
return `${operandLabelShort} ${relativeDateDisplayValue}`;
|
||||
return `${relativeDateDisplayValue}`;
|
||||
}
|
||||
case RecordFilterOperand.IS_TODAY:
|
||||
case RecordFilterOperand.IS_IN_FUTURE:
|
||||
case RecordFilterOperand.IS_IN_PAST:
|
||||
return operandLabelShort;
|
||||
return '';
|
||||
default:
|
||||
return `${operandLabelShort} ${recordFilter.displayValue}`;
|
||||
return `${recordFilter.displayValue}`;
|
||||
}
|
||||
} else if (
|
||||
recordFilter.type === 'SELECT' ||
|
||||
@@ -126,24 +132,33 @@ export const useGetRecordFilterLabelValue = () => {
|
||||
return '';
|
||||
}
|
||||
|
||||
const optionLabels = valueArray.map(
|
||||
(value) =>
|
||||
fieldMetadataOptions?.find((option) => option.value === value)?.label,
|
||||
const { fieldMetadataItem } = getFieldMetadataItemByIdOrThrow(
|
||||
recordFilter.fieldMetadataId,
|
||||
);
|
||||
|
||||
return `${operandLabelShort} ${optionLabels.join(', ')}`;
|
||||
const fieldMetadataItemOptions = fieldMetadataItem.options;
|
||||
|
||||
const optionLabels = valueArray.map(
|
||||
(value) =>
|
||||
fieldMetadataItemOptions?.find((option) => option.value === value)
|
||||
?.label,
|
||||
);
|
||||
|
||||
return `${optionLabels.join(', ')}`;
|
||||
}
|
||||
|
||||
if (!operandIsEmptiness && !recordFilterIsEmpty) {
|
||||
return `${operandLabelShort} ${recordFilter.displayValue}`;
|
||||
return `${recordFilter.displayValue}`;
|
||||
}
|
||||
|
||||
if (operandIsEmptiness) {
|
||||
return `${operandLabelShort}`;
|
||||
return ``;
|
||||
}
|
||||
|
||||
return recordFilter.displayValue;
|
||||
};
|
||||
|
||||
return { getRecordFilterLabelValue };
|
||||
return {
|
||||
getRecordFilterDisplayValue,
|
||||
};
|
||||
};
|
||||
@@ -9,6 +9,7 @@ export type RecordFilter = {
|
||||
id: string;
|
||||
fieldMetadataId: string;
|
||||
value: string;
|
||||
/** @deprecated We shouldn't implement new features with this field and instead try to create utils to obtain the displayValue of a filter type at runtime */
|
||||
displayValue: string;
|
||||
type: FilterableAndTSVectorFieldType;
|
||||
recordFilterGroupId?: string;
|
||||
|
||||
@@ -4,7 +4,7 @@ import { isCompositeFieldType } from '@/object-record/object-filter-dropdown/uti
|
||||
import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { isValidSubFieldName } from '@/settings/data-model/utils/isValidSubFieldName';
|
||||
import { SortOrFilterChip } from '@/views/components/SortOrFilterChip';
|
||||
import { useGetRecordFilterLabelValue } from '@/views/hooks/useGetRecordFilterLabelValue';
|
||||
import { useGetRecordFilterChipLabelValue } from '@/views/hooks/useGetRecordFilterChipLabelValue';
|
||||
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
@@ -26,7 +26,7 @@ export const EditableFilterChip = ({
|
||||
recordFilter.fieldMetadataId,
|
||||
);
|
||||
|
||||
const { getRecordFilterLabelValue } = useGetRecordFilterLabelValue();
|
||||
const { getRecordFilterChipLabelValue } = useGetRecordFilterChipLabelValue();
|
||||
|
||||
const FieldMetadataItemIcon = getIcon(fieldMetadataItem.icon);
|
||||
|
||||
@@ -47,9 +47,8 @@ export const EditableFilterChip = ({
|
||||
: recordFilter.label;
|
||||
|
||||
const labelKey = `${fieldNameLabel}`;
|
||||
const labelValue = getRecordFilterLabelValue({
|
||||
const labelValue = getRecordFilterChipLabelValue({
|
||||
recordFilter,
|
||||
fieldMetadataOptions: fieldMetadataItem.options ?? [],
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
+5
-4
@@ -4,7 +4,7 @@ import { getFieldMetadataItemByIdOrThrow } from '@/object-metadata/utils/getFiel
|
||||
import { MAX_RECORDS_TO_DISPLAY } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownRecordSelect';
|
||||
import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { useRecordsForSelect } from '@/object-record/select/hooks/useRecordsForSelect';
|
||||
import { useGetRecordFilterLabelValue } from '@/views/hooks/useGetRecordFilterLabelValue';
|
||||
import { useGetRecordFilterChipLabelValue } from '@/views/hooks/useGetRecordFilterChipLabelValue';
|
||||
|
||||
import { t } from '@lingui/core/macro';
|
||||
import {
|
||||
@@ -17,12 +17,13 @@ type ObjectFilterDropdownRecordSelectProps = {
|
||||
recordFilter: RecordFilter;
|
||||
};
|
||||
|
||||
// TODO: refactor this with new useGetRecordFilterDisplayValue
|
||||
export const useComputeRecordRelationFilterLabelValue = ({
|
||||
recordFilter,
|
||||
}: ObjectFilterDropdownRecordSelectProps) => {
|
||||
const { objectMetadataItems } = useObjectMetadataItems();
|
||||
|
||||
const { getRecordFilterLabelValue } = useGetRecordFilterLabelValue();
|
||||
const { getRecordFilterChipLabelValue } = useGetRecordFilterChipLabelValue();
|
||||
|
||||
if (!isDefined(recordFilter.fieldMetadataId)) {
|
||||
throw new Error('fieldMetadataItemUsedInFilterDropdown is not defined');
|
||||
@@ -87,13 +88,13 @@ export const useComputeRecordRelationFilterLabelValue = ({
|
||||
return {
|
||||
labelValue:
|
||||
labelValueItems.length > 0
|
||||
? getRecordFilterLabelValue({
|
||||
? getRecordFilterChipLabelValue({
|
||||
recordFilter: {
|
||||
...recordFilter,
|
||||
displayValue: filterDisplayValue,
|
||||
},
|
||||
})
|
||||
: getRecordFilterLabelValue({
|
||||
: getRecordFilterChipLabelValue({
|
||||
recordFilter,
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import { getOperandLabelShort } from '@/object-record/object-filter-dropdown/utils/getOperandLabel';
|
||||
import { useGetRecordFilterDisplayValue } from '@/object-record/record-filter/hooks/useGetRecordFilterDisplayValue';
|
||||
import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { isRecordFilterConsideredEmpty } from '@/object-record/record-filter/utils/isRecordFilterConsideredEmpty';
|
||||
import { isEmptinessOperand } from 'twenty-shared/utils';
|
||||
|
||||
export const useGetRecordFilterChipLabelValue = () => {
|
||||
const { getRecordFilterDisplayValue } = useGetRecordFilterDisplayValue();
|
||||
|
||||
const getRecordFilterChipLabelValue = ({
|
||||
recordFilter,
|
||||
}: {
|
||||
recordFilter: RecordFilter;
|
||||
}) => {
|
||||
const operandLabelShort = getOperandLabelShort(recordFilter.operand);
|
||||
const operandIsEmptiness = isEmptinessOperand(recordFilter.operand);
|
||||
const recordFilterIsEmpty = isRecordFilterConsideredEmpty(recordFilter);
|
||||
|
||||
const recordFilterDisplayValue = getRecordFilterDisplayValue(recordFilter);
|
||||
|
||||
if (!operandIsEmptiness && !recordFilterIsEmpty) {
|
||||
return `${operandLabelShort} ${recordFilterDisplayValue}`;
|
||||
}
|
||||
|
||||
if (operandIsEmptiness) {
|
||||
return `${operandLabelShort}`;
|
||||
}
|
||||
|
||||
return recordFilterDisplayValue;
|
||||
};
|
||||
|
||||
return { getRecordFilterChipLabelValue };
|
||||
};
|
||||
+9
-86
@@ -160,7 +160,7 @@ describe('stringifyRelativeDateFilter', () => {
|
||||
});
|
||||
|
||||
describe('timezone handling', () => {
|
||||
it('should append timezone when provided', () => {
|
||||
it('should append timezone when provided and default first day of the week', () => {
|
||||
const filter: RelativeDateFilter = {
|
||||
direction: 'PAST',
|
||||
amount: 5,
|
||||
@@ -169,7 +169,7 @@ describe('stringifyRelativeDateFilter', () => {
|
||||
};
|
||||
|
||||
expect(stringifyRelativeDateFilter(filter)).toBe(
|
||||
'PAST_5_DAY;;America/New_York;;',
|
||||
'PAST_5_DAY;;America/New_York;;MONDAY;;',
|
||||
);
|
||||
});
|
||||
|
||||
@@ -206,74 +206,18 @@ describe('stringifyRelativeDateFilter', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('referenceDayAsString handling', () => {
|
||||
it('should append referenceDayAsString when timezone is provided', () => {
|
||||
const filter: RelativeDateFilter = {
|
||||
direction: 'PAST',
|
||||
amount: 5,
|
||||
unit: 'DAY',
|
||||
timezone: 'America/New_York',
|
||||
referenceDayAsString: '2024-01-15',
|
||||
};
|
||||
|
||||
expect(stringifyRelativeDateFilter(filter)).toBe(
|
||||
'PAST_5_DAY;;America/New_York;;2024-01-15;;MONDAY;;',
|
||||
);
|
||||
});
|
||||
|
||||
it('should not append referenceDayAsString when timezone is not provided', () => {
|
||||
const filter: RelativeDateFilter = {
|
||||
direction: 'PAST',
|
||||
amount: 5,
|
||||
unit: 'DAY',
|
||||
referenceDayAsString: '2024-01-15',
|
||||
};
|
||||
|
||||
expect(stringifyRelativeDateFilter(filter)).toBe('PAST_5_DAY');
|
||||
});
|
||||
|
||||
it('should not append referenceDayAsString when it is empty', () => {
|
||||
const filter: RelativeDateFilter = {
|
||||
direction: 'PAST',
|
||||
amount: 5,
|
||||
unit: 'DAY',
|
||||
timezone: 'America/New_York',
|
||||
referenceDayAsString: '',
|
||||
};
|
||||
|
||||
expect(stringifyRelativeDateFilter(filter)).toBe(
|
||||
'PAST_5_DAY;;America/New_York;;',
|
||||
);
|
||||
});
|
||||
|
||||
it('should not append referenceDayAsString when it is null', () => {
|
||||
const filter: RelativeDateFilter = {
|
||||
direction: 'PAST',
|
||||
amount: 5,
|
||||
unit: 'DAY',
|
||||
timezone: 'America/New_York',
|
||||
referenceDayAsString: null,
|
||||
};
|
||||
|
||||
expect(stringifyRelativeDateFilter(filter)).toBe(
|
||||
'PAST_5_DAY;;America/New_York;;',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('firstDayOfTheWeek handling', () => {
|
||||
it('should append firstDayOfTheWeek when timezone and referenceDayAsString are provided', () => {
|
||||
it('should append firstDayOfTheWeek when timezone is provided', () => {
|
||||
const filter: RelativeDateFilter = {
|
||||
direction: 'PAST',
|
||||
amount: 5,
|
||||
unit: 'DAY',
|
||||
timezone: 'America/New_York',
|
||||
referenceDayAsString: '2024-01-15',
|
||||
firstDayOfTheWeek: 'SUNDAY',
|
||||
};
|
||||
|
||||
expect(stringifyRelativeDateFilter(filter)).toBe(
|
||||
'PAST_5_DAY;;America/New_York;;2024-01-15;;SUNDAY;;',
|
||||
'PAST_5_DAY;;America/New_York;;SUNDAY;;',
|
||||
);
|
||||
});
|
||||
|
||||
@@ -285,11 +229,10 @@ describe('stringifyRelativeDateFilter', () => {
|
||||
amount: 5,
|
||||
unit: 'DAY',
|
||||
timezone: 'America/New_York',
|
||||
referenceDayAsString: '2024-01-15',
|
||||
};
|
||||
|
||||
expect(stringifyRelativeDateFilter(filter)).toBe(
|
||||
'PAST_5_DAY;;America/New_York;;2024-01-15;;MONDAY;;',
|
||||
'PAST_5_DAY;;America/New_York;;MONDAY;;',
|
||||
);
|
||||
expect(mockDetectCalendarStartDay).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
@@ -302,37 +245,20 @@ describe('stringifyRelativeDateFilter', () => {
|
||||
amount: 5,
|
||||
unit: 'DAY',
|
||||
timezone: 'America/New_York',
|
||||
referenceDayAsString: '2024-01-15',
|
||||
firstDayOfTheWeek: null,
|
||||
};
|
||||
|
||||
expect(stringifyRelativeDateFilter(filter)).toBe(
|
||||
'PAST_5_DAY;;America/New_York;;2024-01-15;;SATURDAY;;',
|
||||
'PAST_5_DAY;;America/New_York;;SATURDAY;;',
|
||||
);
|
||||
expect(mockDetectCalendarStartDay).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should not append firstDayOfTheWeek when referenceDayAsString is not provided', () => {
|
||||
const filter: RelativeDateFilter = {
|
||||
direction: 'PAST',
|
||||
amount: 5,
|
||||
unit: 'DAY',
|
||||
timezone: 'America/New_York',
|
||||
firstDayOfTheWeek: 'SUNDAY',
|
||||
};
|
||||
|
||||
expect(stringifyRelativeDateFilter(filter)).toBe(
|
||||
'PAST_5_DAY;;America/New_York;;',
|
||||
);
|
||||
expect(mockDetectCalendarStartDay).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not append firstDayOfTheWeek when timezone is not provided', () => {
|
||||
const filter: RelativeDateFilter = {
|
||||
direction: 'PAST',
|
||||
amount: 5,
|
||||
unit: 'DAY',
|
||||
referenceDayAsString: '2024-01-15',
|
||||
firstDayOfTheWeek: 'SUNDAY',
|
||||
};
|
||||
|
||||
@@ -348,11 +274,10 @@ describe('stringifyRelativeDateFilter', () => {
|
||||
amount: 5,
|
||||
unit: 'DAY',
|
||||
timezone: 'America/New_York',
|
||||
referenceDayAsString: '2024-01-15',
|
||||
};
|
||||
|
||||
expect(stringifyRelativeDateFilter(filter)).toBe(
|
||||
'PAST_5_DAY;;America/New_York;;2024-01-15;;',
|
||||
'PAST_5_DAY;;America/New_York;;',
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -364,12 +289,11 @@ describe('stringifyRelativeDateFilter', () => {
|
||||
amount: 10,
|
||||
unit: 'MONTH',
|
||||
timezone: 'Europe/London',
|
||||
referenceDayAsString: '2024-12-25',
|
||||
firstDayOfTheWeek: 'MONDAY',
|
||||
};
|
||||
|
||||
expect(stringifyRelativeDateFilter(filter)).toBe(
|
||||
'NEXT_10_MONTH;;Europe/London;;2024-12-25;;MONDAY;;',
|
||||
'NEXT_10_MONTH;;Europe/London;;MONDAY;;',
|
||||
);
|
||||
});
|
||||
|
||||
@@ -379,12 +303,11 @@ describe('stringifyRelativeDateFilter', () => {
|
||||
amount: 7,
|
||||
unit: 'WEEK',
|
||||
timezone: 'Asia/Tokyo',
|
||||
referenceDayAsString: '2024-06-01',
|
||||
firstDayOfTheWeek: 'SUNDAY',
|
||||
};
|
||||
|
||||
expect(stringifyRelativeDateFilter(filter)).toBe(
|
||||
'THIS_1_WEEK;;Asia/Tokyo;;2024-06-01;;SUNDAY;;',
|
||||
'THIS_1_WEEK;;Asia/Tokyo;;SUNDAY;;',
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
+4
-8
@@ -21,15 +21,11 @@ export const stringifyRelativeDateFilter = (
|
||||
if (isNonEmptyString(relativeDateFilter.timezone)) {
|
||||
relativeDateFilterStringified = `${relativeDateFilterStringified};;${relativeDateFilter.timezone};;`;
|
||||
|
||||
if (isNonEmptyString(relativeDateFilter.referenceDayAsString)) {
|
||||
relativeDateFilterStringified = `${relativeDateFilterStringified}${relativeDateFilter.referenceDayAsString};;`;
|
||||
const firstDayOfTheWeek =
|
||||
relativeDateFilter.firstDayOfTheWeek ?? detectCalendarStartDay();
|
||||
|
||||
const firstDayOfTheWeek =
|
||||
relativeDateFilter.firstDayOfTheWeek ?? detectCalendarStartDay();
|
||||
|
||||
if (isNonEmptyString(firstDayOfTheWeek)) {
|
||||
relativeDateFilterStringified = `${relativeDateFilterStringified}${firstDayOfTheWeek};;`;
|
||||
}
|
||||
if (isNonEmptyString(firstDayOfTheWeek)) {
|
||||
relativeDateFilterStringified = `${relativeDateFilterStringified}${firstDayOfTheWeek};;`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-5
@@ -8,10 +8,7 @@ import {
|
||||
subWeeks,
|
||||
subYears,
|
||||
} from 'date-fns';
|
||||
import {
|
||||
getPlainDateFromDate,
|
||||
type RelativeDateFilter,
|
||||
} from 'twenty-shared/utils';
|
||||
import { type RelativeDateFilter } from 'twenty-shared/utils';
|
||||
|
||||
import {
|
||||
evaluateRelativeDateFilter,
|
||||
@@ -472,7 +469,6 @@ describe('Relative Date Filter Utils', () => {
|
||||
direction: 'THIS',
|
||||
unit: 'WEEK',
|
||||
firstDayOfTheWeek: 'MONDAY',
|
||||
referenceDayAsString: getPlainDateFromDate(now),
|
||||
};
|
||||
|
||||
expect(
|
||||
|
||||
@@ -18,6 +18,14 @@ export const getStartUnitOfDateTime = (
|
||||
const firstDayOfTheWeekAsDateFNSNumber =
|
||||
getFirstDayOfTheWeekAsANumberForDateFNS(firstDayOfTheWeek);
|
||||
|
||||
console.log({
|
||||
firstDayOfTheWeek,
|
||||
firstDayOfTheWeekAsDateFNSNumber,
|
||||
startOfWekk: startOfWeek(dateTime, {
|
||||
weekStartsOn: firstDayOfTheWeekAsDateFNSNumber,
|
||||
}),
|
||||
});
|
||||
|
||||
return startOfWeek(dateTime, {
|
||||
weekStartsOn: firstDayOfTheWeekAsDateFNSNumber,
|
||||
});
|
||||
|
||||
@@ -11,7 +11,6 @@ export const relativeDateFilterSchema = z
|
||||
amount: relativeDateFilterAmountSchema.nullish(),
|
||||
unit: relativeDateFilterUnitSchema,
|
||||
timezone: z.string().nullish(),
|
||||
referenceDayAsString: z.string().nullish(),
|
||||
firstDayOfTheWeek: firstDayOfWeekSchema.nullish(),
|
||||
})
|
||||
.refine((data) => !(data.amount === undefined && data.direction !== 'THIS'), {
|
||||
|
||||
+2
-11
@@ -3,7 +3,7 @@ import { isNonEmptyArray } from '@sniptt/guards';
|
||||
import z from 'zod';
|
||||
|
||||
const REGEX_FOR_RELATIVE_DATE_FILTER_STRINGIFIED_PARSING =
|
||||
/((?:THIS)|(?:PAST)|(?:NEXT))_(\d*)_(DAY|MONTH|YEAR|WEEK)(?:(?:;;([^;;]*);;)?(?:(\d\d\d\d-\d\d-\d\d);;)?(?:(MONDAY|SUNDAY|SATURDAY);;)?)?/;
|
||||
/((?:THIS)|(?:PAST)|(?:NEXT))_(\d*)_(DAY|MONTH|YEAR|WEEK)(?:(?:;;([^;;]*);;)?(?:(MONDAY|SUNDAY|SATURDAY);;)?)?/;
|
||||
|
||||
export const relativeDateFilterStringifiedSchema = z
|
||||
.string()
|
||||
@@ -18,22 +18,13 @@ export const relativeDateFilterStringifiedSchema = z
|
||||
throw new Error(`Cannot parse stringified relative date filter`);
|
||||
}
|
||||
|
||||
const [
|
||||
_,
|
||||
direction,
|
||||
amount,
|
||||
unit,
|
||||
timezone,
|
||||
referenceDayAsString,
|
||||
firstDayOfTheWeek,
|
||||
] = result;
|
||||
const [_, direction, amount, unit, timezone, firstDayOfTheWeek] = result;
|
||||
|
||||
return relativeDateFilterSchema.parse({
|
||||
direction,
|
||||
amount,
|
||||
unit,
|
||||
timezone,
|
||||
referenceDayAsString,
|
||||
firstDayOfTheWeek,
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user