Skip to content

Commit

Permalink
Refactor & make 'valueType' required in frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
ad-elias committed Sep 24, 2024
1 parent 80adc22 commit 75f9ddd
Show file tree
Hide file tree
Showing 17 changed files with 108 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { v4 } from 'uuid';

import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { DropdownMenuInput } from '@/ui/layout/dropdown/components/DropdownMenuInput';
import { ViewFilterValueType } from '@/views/types/ViewFilterValueType';

export const ObjectFilterDropdownNumberInput = () => {
const {
Expand Down Expand Up @@ -53,6 +54,7 @@ export const ObjectFilterDropdownNumberInput = () => {
id: selectedFilter?.id ? selectedFilter.id : v4(),
fieldMetadataId: filterDefinitionUsedInDropdown.fieldMetadataId,
value: newValue,
valueType: ViewFilterValueType.STATIC,
operand: selectedOperandInDropdown,
displayValue: newValue,
definition: filterDefinitionUsedInDropdown,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import { useRecoilValue } from 'recoil';
import { v4 } from 'uuid';

import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { FilterDefinition } from '@/object-record/object-filter-dropdown/types/FilterDefinition';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { isDefined } from '~/utils/isDefined';

import { getViewFilterValueType } from '@/object-record/object-filter-dropdown/utils/getViewFilterValueType';
import { ViewFilterValueType } from '@/views/types/ViewFilterValueType';
import { getOperandLabel } from '../utils/getOperandLabel';
import { getOperandsForFilterType } from '../utils/getOperandsForFilterType';

Expand Down Expand Up @@ -47,14 +48,15 @@ export const ObjectFilterDropdownOperandSelect = () => {
setSelectedOperandInDropdown(newOperand);
setIsObjectFilterDropdownOperandSelectUnfolded(false);

if (isValuelessOperand) {
if (isValuelessOperand && isDefined(filterDefinitionUsedInDropdown)) {
selectFilter?.({
id: v4(),
fieldMetadataId: filterDefinitionUsedInDropdown?.fieldMetadataId ?? '',
displayValue: '',
operand: newOperand,
value: '',
definition: filterDefinitionUsedInDropdown as FilterDefinition,
valueType: ViewFilterValueType.STATIC,
definition: filterDefinitionUsedInDropdown,
});
return;
}
Expand All @@ -69,7 +71,10 @@ export const ObjectFilterDropdownOperandSelect = () => {
displayValue: selectedFilter.displayValue,
operand: newOperand,
value: selectedFilter.value,
valueType: selectedFilter.valueType,
valueType: getViewFilterValueType(
filterDefinitionUsedInDropdown,
newOperand,
),
definition: filterDefinitionUsedInDropdown,
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectab
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
import { MenuItemMultiSelect } from '@/ui/navigation/menu-item/components/MenuItemMultiSelect';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { ViewFilterValueType } from '@/views/types/ViewFilterValueType';
import { isDefined } from '~/utils/isDefined';

export const EMPTY_FILTER_VALUE = '';
Expand Down Expand Up @@ -135,6 +136,7 @@ export const ObjectFilterDropdownOptionSelect = () => {
displayValue: filterDisplayValue,
fieldMetadataId: filterDefinitionUsedInDropdown.fieldMetadataId,
value: newFilterValue,
valueType: ViewFilterValueType.STATIC,
});
}
resetSelectedItem();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { RATING_VALUES } from '@/object-record/record-field/meta-types/constants
import { FieldRatingValue } from '@/object-record/record-field/types/FieldMetadata';
import { RatingInput } from '@/ui/field/input/components/RatingInput';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { ViewFilterValueType } from '@/views/types/ViewFilterValueType';

const convertFieldRatingValueToNumber = (
rating: Exclude<FieldRatingValue, null>,
Expand Down Expand Up @@ -61,6 +62,7 @@ export const ObjectFilterDropdownRatingInput = () => {
id: selectedFilter?.id ? selectedFilter.id : v4(),
fieldMetadataId: filterDefinitionUsedInDropdown.fieldMetadataId,
value: convertFieldRatingValueToNumber(newValue),
valueType: ViewFilterValueType.STATIC,
operand: selectedOperandInDropdown,
displayValue: convertFieldRatingValueToNumber(newValue),
definition: filterDefinitionUsedInDropdown,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useRecordsForSelect } from '@/object-record/select/hooks/useRecordsForS
import { SelectableRecord } from '@/object-record/select/types/SelectableRecord';
import { useDeleteCombinedViewFilters } from '@/views/hooks/useDeleteCombinedViewFilters';
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
import { ViewFilterValueType } from '@/views/types/ViewFilterValueType';
import { isDefined } from '~/utils/isDefined';

export const EMPTY_FILTER_VALUE = '[]';
Expand Down Expand Up @@ -129,6 +130,7 @@ export const ObjectFilterDropdownRecordSelect = ({
displayValue: filterDisplayValue,
fieldMetadataId: filterDefinitionUsedInDropdown.fieldMetadataId,
value: newFilterValue,
valueType: ViewFilterValueType.STATIC,
});
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { v4 } from 'uuid';

import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
import { ViewFilterValueType } from '@/views/types/ViewFilterValueType';

export const ObjectFilterDropdownTextSearchInput = () => {
const {
Expand Down Expand Up @@ -55,6 +56,7 @@ export const ObjectFilterDropdownTextSearchInput = () => {
id: selectedFilter?.id ? selectedFilter.id : filterId,
fieldMetadataId: filterDefinitionUsedInDropdown.fieldMetadataId,
value: event.target.value,
valueType: ViewFilterValueType.STATIC,
operand: selectedOperandInDropdown,
displayValue: event.target.value,
definition: filterDefinitionUsedInDropdown,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { FilterDefinition } from '@/object-record/object-filter-dropdown/types/F
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2';
import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { ViewFilterValueType } from '@/views/types/ViewFilterValueType';

const filterDropdownId = 'filterDropdownId';
const renderHookConfig = {
Expand All @@ -31,6 +32,7 @@ const mockFilter: Filter = {
fieldMetadataId: '',
operand: ViewFilterOperand.Is,
value: '',
valueType: ViewFilterValueType.STATIC,
};

describe('useFilterDropdown', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export type Filter = {
variant?: 'default' | 'danger';
fieldMetadataId: string;
value: string;
valueType?: ViewFilterValueType;
valueType: ViewFilterValueType;
displayValue: string;
displayAvatarUrl?: string;
operand: ViewFilterOperand;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { FilterDefinition } from '@/object-record/object-filter-dropdown/types/FilterDefinition';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { ViewFilterValueType } from '@/views/types/ViewFilterValueType';

export const getViewFilterValueType = (
filterDefinition: Pick<FilterDefinition, 'type'>,
operand: ViewFilterOperand,
) => {
switch (filterDefinition.type) {
case 'DATE':
case 'DATE_TIME':
switch (operand) {
case ViewFilterOperand.IsRelative:
return ViewFilterValueType.VARIABLE;
default:
return ViewFilterValueType.STATIC;
}
default:
return ViewFilterValueType.STATIC;
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import {
convertRatingToRatingValue,
} from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownRatingInput';
import { ViewFilterValueType } from '@/views/types/ViewFilterValueType';
import { resolveDateViewFilterValue } from '@/views/utils/view-filter-value/resolveDateViewFilterValue';
import { resolveFilterValue } from '@/views/utils/view-filter-value/resolveFilterValue';
import { endOfDay, roundToNearestMinutes, startOfDay } from 'date-fns';
import { z } from 'zod';
Expand Down Expand Up @@ -387,10 +386,14 @@ export const turnObjectDropdownFilterIntoQueryFilter = (
.object({ start: z.date(), end: z.date() })
.safeParse(resolvedFilterValue).data;

const defaultDateRange = resolveDateViewFilterValue({
const defaultDateRange = resolveFilterValue({
value: 'PAST_1_DAY',
valueType: ViewFilterValueType.VARIABLE,
}) as { start: Date; end: Date };
definition: { type: 'DATE' },
});

if (!defaultDateRange)
throw new Error('Failed to resolve default date range');

const { start, end } = dateRange ?? defaultDateRange;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Filter } from '@/object-record/object-filter-dropdown/types/Filter';
import { getOperandsForFilterType } from '@/object-record/object-filter-dropdown/utils/getOperandsForFilterType';
import { useDropdownV2 } from '@/ui/layout/dropdown/hooks/useDropdownV2';
import { useUpsertCombinedViewFilters } from '@/views/hooks/useUpsertCombinedViewFilters';
import { ViewFilterValueType } from '@/views/types/ViewFilterValueType';
import { isDefined } from '~/utils/isDefined';

type UseHandleToggleColumnFilterProps = {
Expand Down Expand Up @@ -58,6 +59,7 @@ export const useHandleToggleColumnFilter = ({
type: filterType,
},
value: '',
valueType: ViewFilterValueType.STATIC,
};

upsertCombinedViewFilter(newFilter);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Filter } from '@/object-record/object-filter-dropdown/types/Filter';
import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates';
import { useUpsertCombinedViewFilters } from '@/views/hooks/useUpsertCombinedViewFilters';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { ViewFilterValueType } from '@/views/types/ViewFilterValueType';
import { useRecoilCallback } from 'recoil';
import { isDefined } from '~/utils/isDefined';

Expand Down Expand Up @@ -61,6 +62,7 @@ export const useHandleToggleTrashColumnFilter = ({
type: filterType,
},
value: '',
valueType: ViewFilterValueType.STATIC,
};

upsertCombinedViewFilter(newFilter);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { objectMetadataItemFamilySelector } from '@/object-metadata/states/objec
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { formatFieldMetadataItemAsFilterDefinition } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
import { getObjectRecordIdentifier } from '@/object-metadata/utils/getObjectRecordIdentifier';
import { getViewFilterValueType } from '@/object-record/object-filter-dropdown/utils/getViewFilterValueType';
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { generateFindManyRecordsQuery } from '@/object-record/utils/generateFindManyRecordsQuery';
import { ViewFilter } from '@/views/types/ViewFilter';
Expand Down Expand Up @@ -157,6 +158,10 @@ export const useViewFromQueryParams = () => {
fieldMetadataId: fieldMetadataItem.id,
operand: filterOperandFromURL as ViewFilterOperand,
value: filterValueAsString,
valueType: getViewFilterValueType(
filterDefinition,
filterOperandFromURL as ViewFilterOperand,
),
displayValue:
relationRecordNames?.join(', ') ?? filterValueAsString,
definition: filterDefinition,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ export type ViewFilter = {
createdAt?: string;
updatedAt?: string;
viewId?: string;
valueType?: ViewFilterValueType;
valueType: ViewFilterValueType;
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefin
import { ViewField } from '@/views/types/ViewField';
import { ViewFilter } from '@/views/types/ViewFilter';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { ViewFilterValueType } from '@/views/types/ViewFilterValueType';
import { ViewSort } from '@/views/types/ViewSort';
import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinitionToViewField';
import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToColumnDefinitions';
Expand Down Expand Up @@ -49,6 +50,7 @@ describe('mapViewFiltersToFilters', () => {
id: 'id',
fieldMetadataId: '05731f68-6e7a-4903-8374-c0b6a9063482',
value: 'testValue',
valueType: ViewFilterValueType.STATIC,
displayValue: 'Test Display Value',
operand: ViewFilterOperand.Is,
},
Expand All @@ -58,6 +60,7 @@ describe('mapViewFiltersToFilters', () => {
id: 'id',
fieldMetadataId: '05731f68-6e7a-4903-8374-c0b6a9063482',
value: 'testValue',
valueType: ViewFilterValueType.STATIC,
displayValue: 'Test Display Value',
operand: ViewFilterOperand.Is,
definition: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ViewFilter } from '@/views/types/ViewFilter';
import { ViewFilterValueType } from '@/views/types/ViewFilterValueType';
import {
addDays,
addMonths,
Expand Down Expand Up @@ -156,13 +157,25 @@ const resolveVariableDateViewFilterValue = (value?: string | null) => {
return resolveVariableDateViewFilterValueFromRelativeDate(relativeDate);
};

export const resolveDateViewFilterValue = (
viewFilter: Pick<ViewFilter, 'value' | 'valueType'>,
) => {
export type ResolvedDateViewFilterValue<T extends ViewFilterValueType> =
T extends ViewFilterValueType.VARIABLE
? ReturnType<typeof resolveVariableDateViewFilterValue>
: Date | null;

type PartialViewFilter<T extends ViewFilterValueType> = Pick<
ViewFilter,
'value' | 'valueType'
> & { valueType: T };

export const resolveDateViewFilterValue = <T extends ViewFilterValueType>(
viewFilter: PartialViewFilter<T>,
): ResolvedDateViewFilterValue<T> => {
if (!viewFilter.value) return null;

if (viewFilter.valueType === 'VARIABLE') {
return resolveVariableDateViewFilterValue(viewFilter.value);
if (viewFilter.valueType === ViewFilterValueType.VARIABLE) {
return resolveVariableDateViewFilterValue(
viewFilter.value,
) as ResolvedDateViewFilterValue<T>;
}
return new Date(viewFilter.value);
return new Date(viewFilter.value) as ResolvedDateViewFilterValue<T>;
};
Original file line number Diff line number Diff line change
@@ -1,24 +1,42 @@
import { Filter } from '@/object-record/object-filter-dropdown/types/Filter';
import { FilterType } from '@/object-record/object-filter-dropdown/types/FilterType';
import { ViewFilterValueType } from '@/views/types/ViewFilterValueType';
import { resolveNumberViewFilterValue } from '@/views/utils/view-filter-value/resolveNumberViewFilterValue';
import { resolveDateViewFilterValue } from './resolveDateViewFilterValue';
import {
resolveDateViewFilterValue,
ResolvedDateViewFilterValue,
} from './resolveDateViewFilterValue';

type ResolvedFilterValue<T extends FilterType> = T extends 'DATE' | 'DATE_TIME'
? ReturnType<typeof resolveDateViewFilterValue>
: T extends 'NUMBER'
type ResolvedFilterValue<
F extends FilterType,
V extends ViewFilterValueType,
> = F extends 'DATE' | 'DATE_TIME'
? ResolvedDateViewFilterValue<V>
: F extends 'NUMBER'
? ReturnType<typeof resolveNumberViewFilterValue>
: string;

export const resolveFilterValue = <T extends FilterType>(
filter: Pick<Filter, 'value' | 'valueType'> & { definition: { type: T } },
type PartialFilter<F extends FilterType, V extends ViewFilterValueType> = Pick<
Filter,
'value'
> & {
definition: { type: F };
valueType: V;
};

export const resolveFilterValue = <
F extends FilterType,
V extends ViewFilterValueType,
>(
filter: PartialFilter<F, V>,
) => {
switch (filter.definition.type) {
case 'DATE':
case 'DATE_TIME':
return resolveDateViewFilterValue(filter) as ResolvedFilterValue<T>;
return resolveDateViewFilterValue(filter) as ResolvedFilterValue<F, V>;
case 'NUMBER':
return resolveNumberViewFilterValue(filter) as ResolvedFilterValue<T>;
return resolveNumberViewFilterValue(filter) as ResolvedFilterValue<F, V>;
default:
return filter.value as ResolvedFilterValue<T>;
return filter.value as ResolvedFilterValue<F, V>;
}
};

0 comments on commit 75f9ddd

Please sign in to comment.