fix(content-manager): fix filters bugs with relations, enums and uids

This commit is contained in:
Fernando Chavez 2024-06-18 15:21:45 +02:00
parent cefa185d29
commit cdb95f31ee
5 changed files with 29 additions and 10 deletions

View File

@ -1,6 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import { Box, Button, Flex, Popover, Tag, useComposedRefs } from '@strapi/design-system'; import { Box, Button, Flex, Popover, Tag } from '@strapi/design-system';
import { Plus, Filter as FilterIcon, Cross } from '@strapi/icons'; import { Plus, Filter as FilterIcon, Cross } from '@strapi/icons';
import { Schema } from '@strapi/types'; import { Schema } from '@strapi/types';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
@ -12,6 +12,7 @@ import {
IS_SENSITIVE_FILTERS, IS_SENSITIVE_FILTERS,
NUMERIC_FILTERS, NUMERIC_FILTERS,
STRING_PARSE_FILTERS, STRING_PARSE_FILTERS,
FILTERS_WITH_NO_VALUE,
} from '../constants/filters'; } from '../constants/filters';
import { useControllableState } from '../hooks/useControllableState'; import { useControllableState } from '../hooks/useControllableState';
import { useQueryParams } from '../hooks/useQueryParams'; import { useQueryParams } from '../hooks/useQueryParams';
@ -119,7 +120,9 @@ const PopoverImpl = () => {
} }
const handleSubmit = (data: FilterFormData) => { const handleSubmit = (data: FilterFormData) => {
if (!data.value) { const value = FILTERS_WITH_NO_VALUE.includes(data.filter) ? 'true' : data.value;
if (!value) {
return; return;
} }
@ -130,12 +133,12 @@ const PopoverImpl = () => {
/** /**
* There will ALWAYS be an option because we use the options to create the form data. * There will ALWAYS be an option because we use the options to create the form data.
*/ */
const filterType = options.find((filter) => filter.name === data.name)!.type; const fieldOptions = options.find((filter) => filter.name === data.name)!;
/** /**
* If the filter is a relation, we need to nest the filter object, * If the filter is a relation, we need to nest the filter object,
* we always use ids to filter relations. But the nested object is * we filter based on the mainField of the relation, if there is no mainField, we use the id.
* the operator & value pair. This value _could_ look like: * At the end, we pass the operator & value. This value _could_ look like:
* ```json * ```json
* { * {
* "$eq": "1", * "$eq": "1",
@ -143,7 +146,7 @@ const PopoverImpl = () => {
* ``` * ```
*/ */
const operatorValuePairing = { const operatorValuePairing = {
[data.filter]: data.value, [data.filter]: value,
}; };
const newFilterQuery = { const newFilterQuery = {
@ -152,9 +155,9 @@ const PopoverImpl = () => {
...(query.filters?.$and ?? []), ...(query.filters?.$and ?? []),
{ {
[data.name]: [data.name]:
filterType === 'relation' fieldOptions.type === 'relation'
? { ? {
id: operatorValuePairing, [fieldOptions.mainField?.name ?? 'id']: operatorValuePairing,
} }
: operatorValuePairing, : operatorValuePairing,
}, },
@ -266,7 +269,6 @@ const getFilterList = (filter?: Filters.Filter): FilterOption[] => {
switch (type) { switch (type) {
case 'email': case 'email':
case 'text': case 'text':
case 'enumeration':
case 'string': { case 'string': {
return [ return [
...BASE_FILTERS, ...BASE_FILTERS,
@ -291,6 +293,10 @@ const getFilterList = (filter?: Filters.Filter): FilterOption[] => {
return [...BASE_FILTERS, ...NUMERIC_FILTERS]; return [...BASE_FILTERS, ...NUMERIC_FILTERS];
} }
case 'enumeration': {
return BASE_FILTERS;
}
default: default:
return [...BASE_FILTERS, ...IS_SENSITIVE_FILTERS]; return [...BASE_FILTERS, ...IS_SENSITIVE_FILTERS];
} }

View File

@ -36,6 +36,7 @@ const InputRenderer = memo(
case 'biginteger': case 'biginteger':
case 'timestamp': case 'timestamp':
case 'string': case 'string':
case 'uid':
return <StringInput ref={forwardRef} {...props} />; return <StringInput ref={forwardRef} {...props} />;
case 'boolean': case 'boolean':
return <BooleanInput ref={forwardRef} {...props} />; return <BooleanInput ref={forwardRef} {...props} />;

View File

@ -36,7 +36,6 @@ interface InputProps {
| 'media' | 'media'
| 'blocks' | 'blocks'
| 'richtext' | 'richtext'
| 'uid'
| 'dynamiczone' | 'dynamiczone'
| 'component' | 'component'
| 'relation' | 'relation'

View File

@ -158,11 +158,14 @@ const STRING_PARSE_FILTERS = [
}, },
] satisfies FilterOption[]; ] satisfies FilterOption[];
const FILTERS_WITH_NO_VALUE = ['$null', '$notNull'];
export { export {
BASE_FILTERS, BASE_FILTERS,
NUMERIC_FILTERS, NUMERIC_FILTERS,
IS_SENSITIVE_FILTERS, IS_SENSITIVE_FILTERS,
CONTAINS_FILTERS, CONTAINS_FILTERS,
STRING_PARSE_FILTERS, STRING_PARSE_FILTERS,
FILTERS_WITH_NO_VALUE,
}; };
export type { FilterOption }; export type { FilterOption };

View File

@ -163,6 +163,16 @@ const FiltersImpl = ({ disabled, schema }: FiltersProps) => {
}; };
} }
if (attribute.type === 'enumeration') {
filter = {
...filter,
options: attribute.enum.map((value) => ({
label: value,
value,
})),
};
}
return filter; return filter;
}) })
.filter(Boolean) as Filters.Filter[] .filter(Boolean) as Filters.Filter[]