Skip to content

Commit bad3638

Browse files
feat: allow async relationship filter options (#2951)
* chore: improving relationship filter options; Updating prop filterOptions from field type "relationship" to allow async functions; * chore: add failing test case * fix: translation followingFieldsInvalid_many not getting triggered * docs: improve documentation --------- Co-authored-by: Alessio Gravili <alessio@gravili.de>
1 parent 20a6ce8 commit bad3638

File tree

33 files changed

+103
-73
lines changed

33 files changed

+103
-73
lines changed

docs/fields/relationship.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ Set to `false` if you'd like to disable the ability to create new documents from
7474

7575
Options can be dynamically limited by supplying a [query constraint](/docs/queries/overview), which will be used both for validating input and filtering available relationships in the UI.
7676

77-
The `filterOptions` property can either be a `Where` query directly, or a function that returns one. When using a function, it will be called with an argument object with the following properties:
77+
The `filterOptions` property can either be a `Where` query directly, or a function (synchronous or asynchronous) that returns one. When using a function, it will be called with an argument object containing the following properties:
7878

7979
| Property | Description |
8080
| ------------- | ------------------------------------------------------------------------------------ |
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { Where } from '../../../../types';
22
import { FilterOptions, FilterOptionsProps } from '../../../../fields/config/types';
33

4-
export const getFilterOptionsQuery = (filterOptions: FilterOptions, options: Omit<FilterOptionsProps, 'relationTo'> & { relationTo: string | string[] }): {[collection: string]: Where } => {
4+
export const getFilterOptionsQuery = async (filterOptions: FilterOptions, options: Omit<FilterOptionsProps, 'relationTo'> & { relationTo: string | string[] }): Promise<{[collection: string]: Where }> => {
55
const { relationTo } = options;
66
const relations = Array.isArray(relationTo) ? relationTo : [relationTo];
77
const query = {};
88
if (typeof filterOptions !== 'undefined') {
9-
relations.forEach((relation) => {
10-
query[relation] = typeof filterOptions === 'function' ? filterOptions({ ...options, relationTo: relation }) : filterOptions;
11-
});
9+
await Promise.all(relations.map(async (relation) => {
10+
query[relation] = typeof filterOptions === 'function' ? await filterOptions({ ...options, relationTo: relation }) : filterOptions;
11+
}));
1212
}
1313
return query;
1414
};

src/admin/components/utilities/GetFilterOptions/index.tsx

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,20 @@ export const GetFilterOptions = ({
3232
const data = reduceFieldsToValues(fields, true);
3333
const siblingData = getSiblingData(fields, path);
3434

35-
const newFilterOptionsResult = getFilterOptionsQuery(filterOptions, {
36-
id,
37-
data,
38-
relationTo,
39-
siblingData,
40-
user,
41-
});
35+
const getFilterOptions = async () => {
36+
const newFilterOptionsResult = await getFilterOptionsQuery(filterOptions, {
37+
id,
38+
data,
39+
relationTo,
40+
siblingData,
41+
user,
42+
});
4243

43-
if (!equal(newFilterOptionsResult, filterOptionsResult)) {
44-
setFilterOptionsResult(newFilterOptionsResult);
45-
}
44+
if (!equal(newFilterOptionsResult, filterOptionsResult)) {
45+
setFilterOptionsResult(newFilterOptionsResult);
46+
}
47+
};
48+
getFilterOptions();
4649
}, [
4750
fields,
4851
filterOptions,

src/fields/config/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export type FilterOptionsProps<T = any> = {
5656
relationTo: string,
5757
}
5858

59-
export type FilterOptions<T = any> = Where | ((options: FilterOptionsProps<T>) => Where);
59+
export type FilterOptions<T = any> = Where | ((options: FilterOptionsProps<T>) => (Where | Promise<Where>));
6060

6161
type Admin = {
6262
position?: 'sidebar';

src/fields/validations.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ const validateFilterOptions: Validate = async (value, { t, filterOptions, id, us
211211
const values = Array.isArray(value) ? value : [value];
212212

213213
await Promise.all(collections.map(async (collection) => {
214-
const optionFilter = typeof filterOptions === 'function' ? filterOptions({
214+
const optionFilter = typeof filterOptions === 'function' ? await filterOptions({
215215
id,
216216
data,
217217
siblingData,

src/translations/ar.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
"deletingFile": "حدث خطأ أثناء حذف الملف.",
6464
"deletingTitle": "حدث خطأ أثناء حذف {{title}}. يرجى التحقق من الاتصال الخاص بك والمحاولة مرة أخرى.",
6565
"emailOrPasswordIncorrect": "البريد الإلكتروني أو كلمة المرور المقدمة غير صحيحة.",
66-
"followingFieldsInvalid_many": "الحقول التالية غير صالحة:",
66+
"followingFieldsInvalid_other": "الحقول التالية غير صالحة:",
6767
"followingFieldsInvalid_one": "الحقل التالي غير صالح:",
6868
"incorrectCollection": "مجموعة غير صحيحة",
6969
"invalidFileType": "نوع ملف غير صالح",
@@ -346,4 +346,4 @@
346346
"viewingVersions": "عرض النسخ لـ {{entityLabel}} {{documentTitle}}",
347347
"viewingVersionsGlobal": "عرض النسخ للـ {{entityLabel}} العام"
348348
}
349-
}
349+
}

src/translations/bg.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
"deletingFile": "Имаше грешка при изтриването на файла.",
6464
"deletingTitle": "Имаше проблем при изтриването на {{title}}. Моля провери връзката си и опитай отново.",
6565
"emailOrPasswordIncorrect": "Имейлът или паролата не са правилни.",
66-
"followingFieldsInvalid_many": "Следните полета са некоректни:",
66+
"followingFieldsInvalid_other": "Следните полета са некоректни:",
6767
"followingFieldsInvalid_one": "Следното поле е некоректно:",
6868
"incorrectCollection": "Некоректно събиране",
6969
"invalidFileType": "Невалиден тип на файл",
@@ -346,4 +346,4 @@
346346
"viewingVersions": "Гледане на версии за {{entityLabel}} {{documentTitle}}",
347347
"viewingVersionsGlobal": "Гледане на версии за глобалния документ {{entityLabel}}"
348348
}
349-
}
349+
}

src/translations/cs.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
"deletingFile": "Při mazání souboru došlo k chybě.",
6464
"deletingTitle": "Při mazání {{title}} došlo k chybě. Zkontrolujte své připojení a zkuste to znovu.",
6565
"emailOrPasswordIncorrect": "Zadaný email nebo heslo není správné.",
66-
"followingFieldsInvalid_many": "Následující pole jsou neplatná:",
66+
"followingFieldsInvalid_other": "Následující pole jsou neplatná:",
6767
"followingFieldsInvalid_one": "Následující pole je neplatné:",
6868
"incorrectCollection": "Nesprávná kolekce",
6969
"invalidFileType": "Neplatný typ souboru",
@@ -346,4 +346,4 @@
346346
"viewingVersions": "Zobrazuji verze pro {{entityLabel}} {{documentTitle}}",
347347
"viewingVersionsGlobal": "Zobrazuji verze pro globální {{entityLabel}}"
348348
}
349-
}
349+
}

src/translations/de.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
"deletingFile": "Beim Löschen der Datei ist ein Fehler aufgetreten.",
6464
"deletingTitle": "Es gab ein Problem während der Löschung von {{title}}. Bitte überprüfe deine Verbindung und versuche es erneut.",
6565
"emailOrPasswordIncorrect": "Die E-Mail-Adresse oder das Passwort sind nicht korrekt.",
66-
"followingFieldsInvalid_many": "Die folgenden Felder sind nicht korrekt:",
66+
"followingFieldsInvalid_other": "Die folgenden Felder sind nicht korrekt:",
6767
"followingFieldsInvalid_one": "Das folgende Feld ist nicht korrekt:",
6868
"incorrectCollection": "Falsche Sammlung",
6969
"invalidFileType": "Ungültiger Datei-Typ",
@@ -346,4 +346,4 @@
346346
"viewingVersions": "Betrachte Versionen für {{entityLabel}} {{documentTitle}}",
347347
"viewingVersionsGlobal": "`Betrachte Versionen für das Globale Dokument {{entityLabel}}"
348348
}
349-
}
349+
}

src/translations/en.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
"deletingFile": "There was an error deleting file.",
6464
"deletingTitle": "There was an error while deleting {{title}}. Please check your connection and try again.",
6565
"emailOrPasswordIncorrect": "The email or password provided is incorrect.",
66-
"followingFieldsInvalid_many": "The following fields are invalid:",
66+
"followingFieldsInvalid_other": "The following fields are invalid:",
6767
"followingFieldsInvalid_one": "The following field is invalid:",
6868
"incorrectCollection": "Incorrect Collection",
6969
"invalidFileType": "Invalid file type",
@@ -346,4 +346,4 @@
346346
"viewingVersions": "Viewing versions for the {{entityLabel}} {{documentTitle}}",
347347
"viewingVersionsGlobal": "Viewing versions for the global {{entityLabel}}"
348348
}
349-
}
349+
}

0 commit comments

Comments
 (0)