fix: upload field filterOptions

This commit is contained in:
Jacob Fletcher
2023-01-09 14:35:58 -05:00
parent d8c700975f
commit 9483ccb120
8 changed files with 63 additions and 19 deletions

View File

@@ -67,7 +67,8 @@ const DrawerContent: React.FC<ListDrawerProps & {
collectionSlugs, collectionSlugs,
uploads, uploads,
selectedCollection, selectedCollection,
enabledCollectionConfigs enabledCollectionConfigs,
filterOptions,
}) => { }) => {
const { t, i18n } = useTranslation(['upload', 'general']); const { t, i18n } = useTranslation(['upload', 'general']);
const { permissions } = useAuth(); const { permissions } = useAuth();
@@ -165,13 +166,21 @@ const DrawerContent: React.FC<ListDrawerProps & {
} = {}; } = {};
if (page) params.page = page; if (page) params.page = page;
if (where) params.where = where;
if (where) {
params.where = {
...where || {},
...filterOptions?.[selectedCollectionConfig.slug] ? {
...filterOptions[selectedCollectionConfig.slug],
} : {},
};
}
if (sort) params.sort = sort; if (sort) params.sort = sort;
if (limit) params.limit = limit; if (limit) params.limit = limit;
if (cacheBust) params.cacheBust = cacheBust; if (cacheBust) params.cacheBust = cacheBust;
setParams(params); setParams(params);
}, [setParams, page, sort, where, limit, cacheBust]); }, [setParams, page, sort, where, limit, cacheBust, filterOptions, selectedCollectionConfig]);
useEffect(() => { useEffect(() => {
const syncColumnsFromPrefs = async () => { const syncColumnsFromPrefs = async () => {
@@ -324,7 +333,7 @@ export const ListDrawerContent: React.FC<ListDrawerProps> = (props) => {
const [enabledCollectionConfigs] = useState(() => collections.filter((coll) => shouldIncludeCollection({ coll, uploads, collectionSlugs }))); const [enabledCollectionConfigs] = useState(() => collections.filter((coll) => shouldIncludeCollection({ coll, uploads, collectionSlugs })));
if (enabledCollectionConfigs.length === 0){ if (enabledCollectionConfigs.length === 0) {
return null; return null;
} }
@@ -333,5 +342,5 @@ export const ListDrawerContent: React.FC<ListDrawerProps> = (props) => {
{...props} {...props}
enabledCollectionConfigs={enabledCollectionConfigs} enabledCollectionConfigs={enabledCollectionConfigs}
/> />
) );
} };

View File

@@ -54,7 +54,12 @@ export const ListDrawer: React.FC<ListDrawerProps> = (props) => {
); );
}; };
export const useListDrawer: UseListDrawer = ({ collectionSlugs, uploads, selectedCollection }) => { export const useListDrawer: UseListDrawer = ({
collectionSlugs,
uploads,
selectedCollection,
filterOptions,
}) => {
const drawerDepth = useEditDepth(); const drawerDepth = useEditDepth();
const uuid = useId(); const uuid = useId();
const { modalState, toggleModal, closeModal, openModal } = useModal(); const { modalState, toggleModal, closeModal, openModal } = useModal();
@@ -90,9 +95,10 @@ export const useListDrawer: UseListDrawer = ({ collectionSlugs, uploads, selecte
closeDrawer={closeDrawer} closeDrawer={closeDrawer}
key={drawerSlug} key={drawerSlug}
selectedCollection={selectedCollection} selectedCollection={selectedCollection}
filterOptions={filterOptions}
/> />
)); ));
}, [drawerSlug, collectionSlugs, uploads, closeDrawer, selectedCollection]); }, [drawerSlug, collectionSlugs, uploads, closeDrawer, selectedCollection, filterOptions]);
const MemoizedDrawerToggler = useMemo(() => { const MemoizedDrawerToggler = useMemo(() => {
return ((props) => ( return ((props) => (

View File

@@ -1,5 +1,6 @@
import React, { HTMLAttributes } from 'react'; import React, { HTMLAttributes } from 'react';
import { SanitizedCollectionConfig } from '../../../../collections/config/types'; import { SanitizedCollectionConfig } from '../../../../collections/config/types';
import { FilterOptionsResult } from '../../forms/field-types/Relationship/types';
export type ListDrawerProps = { export type ListDrawerProps = {
onSelect?: (args: { onSelect?: (args: {
@@ -11,6 +12,7 @@ export type ListDrawerProps = {
collectionSlugs?: string[] collectionSlugs?: string[]
uploads?: boolean uploads?: boolean
selectedCollection?: string selectedCollection?: string
filterOptions?: FilterOptionsResult
} }
export type ListTogglerProps = HTMLAttributes<HTMLButtonElement> & { export type ListTogglerProps = HTMLAttributes<HTMLButtonElement> & {
@@ -24,6 +26,7 @@ export type UseListDrawer = (args: {
collectionSlugs?: string[] collectionSlugs?: string[]
selectedCollection?: string selectedCollection?: string
uploads?: boolean // finds all collections with upload: true uploads?: boolean // finds all collections with upload: true
filterOptions?: FilterOptionsResult
}) => [ }) => [
React.FC<Omit<ListDrawerProps, 'collectionSlug' | 'id'>>, // drawer React.FC<Omit<ListDrawerProps, 'collectionSlug' | 'id'>>, // drawer
React.FC<Omit<ListTogglerProps, 'collectionSlug' | 'id'>>, // toggler React.FC<Omit<ListTogglerProps, 'collectionSlug' | 'id'>>, // toggler

View File

@@ -22,7 +22,7 @@ import { useDebouncedCallback } from '../../../../hooks/useDebouncedCallback';
import wordBoundariesRegex from '../../../../../utilities/wordBoundariesRegex'; import wordBoundariesRegex from '../../../../../utilities/wordBoundariesRegex';
import { AddNewRelation } from './AddNew'; import { AddNewRelation } from './AddNew';
import { findOptionsByValue } from './findOptionsByValue'; import { findOptionsByValue } from './findOptionsByValue';
import { GetFilterOptions } from './GetFilterOptions'; import { GetFilterOptions } from '../../../utilities/GetFilterOptions';
import { SingleValue } from './select-components/SingleValue'; import { SingleValue } from './select-components/SingleValue';
import { MultiValueLabel } from './select-components/MultiValueLabel'; import { MultiValueLabel } from './select-components/MultiValueLabel';
import { DocumentDrawerProps } from '../../../elements/DocumentDrawer/types'; import { DocumentDrawerProps } from '../../../elements/DocumentDrawer/types';

View File

@@ -16,6 +16,8 @@ import { DocumentDrawerProps } from '../../../elements/DocumentDrawer/types';
import { ListDrawerProps } from '../../../elements/ListDrawer/types'; import { ListDrawerProps } from '../../../elements/ListDrawer/types';
import './index.scss'; import './index.scss';
import { GetFilterOptions } from '../../../utilities/GetFilterOptions';
import { FilterOptionsResult } from '../Relationship/types';
const baseClass = 'upload'; const baseClass = 'upload';
@@ -57,6 +59,7 @@ const UploadInput: React.FC<UploadInputProps> = (props) => {
api = '/api', api = '/api',
collection, collection,
errorMessage, errorMessage,
filterOptions,
} = props; } = props;
const { t, i18n } = useTranslation('fields'); const { t, i18n } = useTranslation('fields');
@@ -64,6 +67,7 @@ const UploadInput: React.FC<UploadInputProps> = (props) => {
const [file, setFile] = useState(undefined); const [file, setFile] = useState(undefined);
const [missingFile, setMissingFile] = useState(false); const [missingFile, setMissingFile] = useState(false);
const [collectionSlugs] = useState([collection?.slug]); const [collectionSlugs] = useState([collection?.slug]);
const [filterOptionsResult, setFilterOptionsResult] = useState<FilterOptionsResult>();
const [ const [
DocumentDrawer, DocumentDrawer,
@@ -83,6 +87,7 @@ const UploadInput: React.FC<UploadInputProps> = (props) => {
}, },
] = useListDrawer({ ] = useListDrawer({
collectionSlugs, collectionSlugs,
filterOptions: filterOptionsResult,
}); });
const classes = [ const classes = [
@@ -145,6 +150,15 @@ const UploadInput: React.FC<UploadInputProps> = (props) => {
width, width,
}} }}
> >
<GetFilterOptions
{...{
filterOptionsResult,
setFilterOptionsResult,
filterOptions,
path,
relationTo,
}}
/>
<Error <Error
showError={showError} showError={showError}
message={errorMessage} message={errorMessage}

View File

@@ -1,13 +1,13 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import equal from 'deep-equal'; import equal from 'deep-equal';
import { FilterOptions } from '../../../../../../fields/config/types'; import { FilterOptions } from '../../../../fields/config/types';
import { useAuth } from '../../../../utilities/Auth'; import { useAuth } from '../Auth';
import { useDocumentInfo } from '../../../../utilities/DocumentInfo'; import { useDocumentInfo } from '../DocumentInfo';
import { useAllFormFields } from '../../../Form/context'; import { useAllFormFields } from '../../forms/Form/context';
import { getFilterOptionsQuery } from '../../getFilterOptionsQuery'; import { getFilterOptionsQuery } from '../../forms/field-types/getFilterOptionsQuery';
import { FilterOptionsResult } from '../types'; import { FilterOptionsResult } from '../../forms/field-types/Relationship/types';
import reduceFieldsToValues from '../../../Form/reduceFieldsToValues'; import reduceFieldsToValues from '../../forms/Form/reduceFieldsToValues';
import getSiblingData from '../../../Form/getSiblingData'; import getSiblingData from '../../forms/Form/getSiblingData';
type Args = { type Args = {
filterOptions: FilterOptions filterOptions: FilterOptions

View File

@@ -15,6 +15,11 @@ const Uploads: CollectionConfig = {
type: 'upload', type: 'upload',
name: 'media', name: 'media',
relationTo: 'uploads', relationTo: 'uploads',
filterOptions: {
mimeType: {
equals: 'image/png',
},
},
}, },
], ],
}; };

View File

@@ -1,5 +1,6 @@
import type { Page } from '@playwright/test'; import type { Page } from '@playwright/test';
import { expect, test } from '@playwright/test'; import { expect, test } from '@playwright/test';
import path from 'path';
import { AdminUrlUtil } from '../helpers/adminUrlUtil'; import { AdminUrlUtil } from '../helpers/adminUrlUtil';
import { initPayloadE2E } from '../helpers/configHelpers'; import { initPayloadE2E } from '../helpers/configHelpers';
import { login, saveDocAndAssert } from '../helpers'; import { login, saveDocAndAssert } from '../helpers';
@@ -10,7 +11,6 @@ import { tabsSlug } from './collections/Tabs';
import { collapsibleFieldsSlug } from './collections/Collapsible'; import { collapsibleFieldsSlug } from './collections/Collapsible';
import wait from '../../src/utilities/wait'; import wait from '../../src/utilities/wait';
import { jsonDoc } from './collections/JSON'; import { jsonDoc } from './collections/JSON';
import path from 'path';
const { beforeAll, describe } = test; const { beforeAll, describe } = test;
@@ -513,7 +513,7 @@ describe('fields', () => {
await expect(page.locator('.Toastify')).toContainText('successfully'); await expect(page.locator('.Toastify')).toContainText('successfully');
}); });
// test that the image renders // test that the image renders
test('should render uploaded image', async () => { test('should render uploaded image', async () => {
await expect(page.locator('.file-field .file-details img')).toHaveAttribute('src', '/uploads/payload-1.jpg'); await expect(page.locator('.file-field .file-details img')).toHaveAttribute('src', '/uploads/payload-1.jpg');
}); });
@@ -538,5 +538,12 @@ describe('fields', () => {
test('should clear selected upload', async () => { test('should clear selected upload', async () => {
await page.locator('.field-type.upload .file-details__remove').click(); await page.locator('.field-type.upload .file-details__remove').click();
}); });
test('should select using the list drawer and restrict mimetype based on filterOptions', async () => {
await page.locator('.field-type.upload .upload__toggler.list-drawer__toggler').click();
const jpgImages = await page.locator('[id^=list-drawer_1_] .upload-gallery img[src$=".jpg"]');
expect(await jpgImages.count()).toEqual(0);
});
}); });
}); });