add author filters and handle them

This commit is contained in:
Fernando Chavez 2023-06-13 04:40:29 +02:00
parent 2319c6d15e
commit 9d684b4f18
2 changed files with 108 additions and 2 deletions

View File

@ -0,0 +1,39 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Combobox, ComboboxOption } from '@strapi/design-system';
import { getDisplayName } from '@strapi/helper-plugin';
import { useIntl } from 'react-intl';
import { useAdminUsers } from '../../../hooks/useAdminUsers';
const AdminUsersFilter = ({ value, onChange }) => {
const { formatMessage } = useIntl();
const { users, isLoading } = useAdminUsers({}, { staleTime: 2 * (1000 * 60) });
const ariaLabel = formatMessage({
id: 'content-manager.components.Filters.usersSelect.label',
defaultMessage: 'Search and select an user to filter',
});
return (
<Combobox value={value} aria-label={ariaLabel} onChange={onChange} loading={isLoading}>
{users.map((user) => {
return (
<ComboboxOption key={user.id} value={user.id.toString()}>
{getDisplayName(user, formatMessage)}
</ComboboxOption>
);
})}
</Combobox>
);
};
AdminUsersFilter.propTypes = {
onChange: PropTypes.func.isRequired,
value: PropTypes.string,
};
AdminUsersFilter.defaultProps = {
value: '',
};
export { AdminUsersFilter };

View File

@ -2,14 +2,77 @@ import React from 'react';
import PropTypes from 'prop-types';
import { useIntl } from 'react-intl';
import Filters from './Filters';
import { useQueryParams } from '@strapi/helper-plugin';
import { useAdminUsers } from '../../../hooks/useAdminUsers';
import useAllowedAttributes from './hooks/useAllowedAttributes';
import Filters from './Filters';
import { AdminUsersFilter } from './AdminUsersFilter';
const AUTHOR_ATTRIBUTES = ['createdBy', 'updatedBy'];
const AttributeFilter = ({ contentType, slug, metadatas }) => {
const { formatMessage } = useIntl();
const [{ query }] = useQueryParams();
// We get the users selected' ids
const selectedUsers =
query?.filters?.$and?.reduce((acc, filter) => {
const [key, value] = Object.entries(filter)[0];
const id = value.id?.$eq || value.id?.$ne;
if (AUTHOR_ATTRIBUTES.includes(key) && !acc.includes(id)) {
acc.push(id);
}
return acc;
}, []) ?? [];
const { users, isLoading } = useAdminUsers(
{ filter: { id: { in: selectedUsers } } },
{
enabled: selectedUsers.length > 0,
}
);
const allowedAttributes = useAllowedAttributes(contentType, slug);
const displayedFilters = allowedAttributes.map((name) => {
if (AUTHOR_ATTRIBUTES.includes(name)) {
return {
name,
metadatas: {
label: formatMessage({
id: `content-manager.components.Filters.${name}`,
defaultMessage: name,
}),
customOperators: [
{
intlLabel: { id: 'components.FilterOptions.FILTER_TYPES.$eq', defaultMessage: 'is' },
value: '$eq',
},
{
intlLabel: {
id: 'components.FilterOptions.FILTER_TYPES.$ne',
defaultMessage: 'is not',
},
value: '$ne',
},
],
customInput: AdminUsersFilter,
options: users.map((user) => ({
label: user.firstname,
customValue: user.id.toString(),
})),
},
fieldSchema: {
type: 'relation',
mainField: { name: 'id' },
trackedEvent: {
name: 'didFilterEntries',
properties: { useRelation: true },
},
},
};
}
const attribute = contentType.attributes[name];
const { type, enum: options } = attribute;
@ -28,6 +91,10 @@ const AttributeFilter = ({ contentType, slug, metadatas }) => {
};
});
if (isLoading) {
return null;
}
return <Filters displayedFilters={displayedFilters} />;
};