feat(ui): allows filtering on group and tab fields from list controls (#6647)
## Description Adds the ability to filter by fields within a `group` or **named** `tab` via the list controls. Note: added missing translations for the `within` and `intersects` operator options, these are displayed in the filters for `point` and `JSON` fields. - [X] I have read and understand the [CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md) document in this repository. ## Type of change - [X] New feature (non-breaking change which adds functionality) ## Checklist: - [X] Existing test suite passes locally with my changes
This commit is contained in:
committed by
GitHub
parent
2a2ab53189
commit
d4d410141c
@@ -251,6 +251,8 @@ export const clientTranslationKeys = createClientTranslationKeys([
|
||||
'operators:isLessThan',
|
||||
'operators:isGreaterThanOrEqualTo',
|
||||
'operators:isLessThanOrEqualTo',
|
||||
'operators:within',
|
||||
'operators:intersects',
|
||||
|
||||
'upload:crop',
|
||||
'upload:cropToolDescription',
|
||||
|
||||
@@ -302,6 +302,7 @@ export const arTranslations: DefaultTranslationsObject = {
|
||||
contains: 'يحتوي',
|
||||
equals: 'يساوي',
|
||||
exists: 'موجود',
|
||||
intersects: 'يتقاطع',
|
||||
isGreaterThan: 'أكبر من',
|
||||
isGreaterThanOrEqualTo: 'أكبر أو يساوي',
|
||||
isIn: 'موجود في',
|
||||
@@ -311,6 +312,7 @@ export const arTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'لا يساوي',
|
||||
isNotIn: 'غير موجود في',
|
||||
near: 'قريب من',
|
||||
within: 'في غضون',
|
||||
},
|
||||
upload: {
|
||||
crop: 'محصول',
|
||||
|
||||
@@ -305,6 +305,7 @@ export const azTranslations: DefaultTranslationsObject = {
|
||||
contains: 'daxilində',
|
||||
equals: 'bərabərdir',
|
||||
exists: 'mövcuddur',
|
||||
intersects: 'kəsişir',
|
||||
isGreaterThan: 'dən böyük',
|
||||
isGreaterThanOrEqualTo: 'böyük və ya bərabər',
|
||||
isIn: 'daxildir',
|
||||
@@ -314,6 +315,7 @@ export const azTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'bərabər deyil',
|
||||
isNotIn: 'daxil deyil',
|
||||
near: 'yaxın',
|
||||
within: 'daxilinde',
|
||||
},
|
||||
upload: {
|
||||
crop: 'Məhsul',
|
||||
|
||||
@@ -303,6 +303,7 @@ export const bgTranslations: DefaultTranslationsObject = {
|
||||
contains: 'съдържа',
|
||||
equals: 'е равно на',
|
||||
exists: 'съществува',
|
||||
intersects: 'пресича',
|
||||
isGreaterThan: 'е по-голямо от',
|
||||
isGreaterThanOrEqualTo: 'е по-голямо от или равно на',
|
||||
isIn: 'е в',
|
||||
@@ -312,6 +313,7 @@ export const bgTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'не е равно на',
|
||||
isNotIn: 'не е в',
|
||||
near: 'близко',
|
||||
within: 'в рамките на',
|
||||
},
|
||||
upload: {
|
||||
crop: 'Изрязване',
|
||||
|
||||
@@ -303,6 +303,7 @@ export const csTranslations: DefaultTranslationsObject = {
|
||||
contains: 'obsahuje',
|
||||
equals: 'rovná se',
|
||||
exists: 'existuje',
|
||||
intersects: 'protíná se',
|
||||
isGreaterThan: 'je větší než',
|
||||
isGreaterThanOrEqualTo: 'je větší nebo rovno',
|
||||
isIn: 'je v',
|
||||
@@ -312,6 +313,7 @@ export const csTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'není rovno',
|
||||
isNotIn: 'není v',
|
||||
near: 'blízko',
|
||||
within: 'uvnitř',
|
||||
},
|
||||
upload: {
|
||||
crop: 'Ořez',
|
||||
|
||||
@@ -309,6 +309,7 @@ export const deTranslations: DefaultTranslationsObject = {
|
||||
contains: 'enthält',
|
||||
equals: 'gleich',
|
||||
exists: 'existiert',
|
||||
intersects: 'schneidet sich',
|
||||
isGreaterThan: 'ist größer als',
|
||||
isGreaterThanOrEqualTo: 'ist größer oder gleich',
|
||||
isIn: 'ist drin',
|
||||
@@ -318,6 +319,7 @@ export const deTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'ist nicht gleich',
|
||||
isNotIn: 'ist nicht drin',
|
||||
near: 'in der Nähe',
|
||||
within: 'innerhalb',
|
||||
},
|
||||
upload: {
|
||||
crop: 'Zuschneiden',
|
||||
|
||||
@@ -306,6 +306,7 @@ export const enTranslations = {
|
||||
contains: 'contains',
|
||||
equals: 'equals',
|
||||
exists: 'exists',
|
||||
intersects: 'intersects',
|
||||
isGreaterThan: 'is greater than',
|
||||
isGreaterThanOrEqualTo: 'is greater than or equal to',
|
||||
isIn: 'is in',
|
||||
@@ -315,6 +316,7 @@ export const enTranslations = {
|
||||
isNotEqualTo: 'is not equal to',
|
||||
isNotIn: 'is not in',
|
||||
near: 'near',
|
||||
within: 'within',
|
||||
},
|
||||
upload: {
|
||||
crop: 'Crop',
|
||||
|
||||
@@ -308,6 +308,7 @@ export const esTranslations: DefaultTranslationsObject = {
|
||||
contains: 'contiene',
|
||||
equals: 'igual',
|
||||
exists: 'existe',
|
||||
intersects: 'interseca',
|
||||
isGreaterThan: 'es mayor que',
|
||||
isGreaterThanOrEqualTo: 'es mayor o igual que',
|
||||
isIn: 'está en',
|
||||
@@ -317,6 +318,7 @@ export const esTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'no es igual a',
|
||||
isNotIn: 'no está en',
|
||||
near: 'cerca',
|
||||
within: 'dentro de',
|
||||
},
|
||||
upload: {
|
||||
crop: 'Cultivo',
|
||||
|
||||
@@ -303,6 +303,7 @@ export const faTranslations: DefaultTranslationsObject = {
|
||||
contains: 'شامل',
|
||||
equals: 'برابر با',
|
||||
exists: 'وجود دارد',
|
||||
intersects: 'تلاقی',
|
||||
isGreaterThan: 'بزرگتر است از',
|
||||
isGreaterThanOrEqualTo: 'بزرگتر یا مساوی است',
|
||||
isIn: 'هست در',
|
||||
@@ -312,6 +313,7 @@ export const faTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'برابر نیست',
|
||||
isNotIn: 'در این نیست',
|
||||
near: 'نزدیک',
|
||||
within: 'در داخل',
|
||||
},
|
||||
upload: {
|
||||
crop: 'محصول',
|
||||
|
||||
@@ -312,6 +312,7 @@ export const frTranslations: DefaultTranslationsObject = {
|
||||
contains: 'contient',
|
||||
equals: 'est égal à',
|
||||
exists: 'existe',
|
||||
intersects: 'intersecte',
|
||||
isGreaterThan: 'est supérieur à',
|
||||
isGreaterThanOrEqualTo: 'est supérieur ou égal à',
|
||||
isIn: 'est dans',
|
||||
@@ -321,6 +322,7 @@ export const frTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'n’est pas égal à',
|
||||
isNotIn: 'n’est pas dans',
|
||||
near: 'proche',
|
||||
within: 'dans',
|
||||
},
|
||||
upload: {
|
||||
crop: 'Recadrer',
|
||||
|
||||
@@ -298,6 +298,7 @@ export const heTranslations: DefaultTranslationsObject = {
|
||||
contains: 'מכיל',
|
||||
equals: 'שווה ל',
|
||||
exists: 'קיים',
|
||||
intersects: 'מצטלב',
|
||||
isGreaterThan: 'גדול מ',
|
||||
isGreaterThanOrEqualTo: 'גדול או שווה ל',
|
||||
isIn: 'נמצא ב',
|
||||
@@ -307,6 +308,7 @@ export const heTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'לא שווה ל',
|
||||
isNotIn: 'לא נמצא ב',
|
||||
near: 'קרוב ל',
|
||||
within: 'בתוך',
|
||||
},
|
||||
upload: {
|
||||
crop: 'חתוך',
|
||||
|
||||
@@ -304,6 +304,7 @@ export const hrTranslations: DefaultTranslationsObject = {
|
||||
contains: 'sadrži',
|
||||
equals: 'jednako',
|
||||
exists: 'postoji',
|
||||
intersects: 'presijeca',
|
||||
isGreaterThan: 'je veće od',
|
||||
isGreaterThanOrEqualTo: 'je veće od ili jednako',
|
||||
isIn: 'je u',
|
||||
@@ -313,6 +314,7 @@ export const hrTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'nije jednako',
|
||||
isNotIn: 'nije unutra',
|
||||
near: 'blizu',
|
||||
within: 'unutar',
|
||||
},
|
||||
upload: {
|
||||
crop: 'Usjev',
|
||||
|
||||
@@ -306,6 +306,7 @@ export const huTranslations: DefaultTranslationsObject = {
|
||||
contains: 'tartalmaz',
|
||||
equals: 'egyenlő',
|
||||
exists: 'létezik',
|
||||
intersects: 'metszéspontokban',
|
||||
isGreaterThan: 'nagyobb, mint',
|
||||
isGreaterThanOrEqualTo: 'nagyobb vagy egyenlő, mint',
|
||||
isIn: 'benne van',
|
||||
@@ -315,6 +316,7 @@ export const huTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'nem egyenlő',
|
||||
isNotIn: 'nincs benne',
|
||||
near: 'közel',
|
||||
within: 'belül',
|
||||
},
|
||||
upload: {
|
||||
crop: 'Termés',
|
||||
|
||||
@@ -306,6 +306,7 @@ export const itTranslations: DefaultTranslationsObject = {
|
||||
contains: 'contiene',
|
||||
equals: 'uguale',
|
||||
exists: 'esiste',
|
||||
intersects: 'interseca',
|
||||
isGreaterThan: 'è maggiore di',
|
||||
isGreaterThanOrEqualTo: 'è maggiore o uguale a',
|
||||
isIn: 'è in',
|
||||
@@ -315,6 +316,7 @@ export const itTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'non è uguale a',
|
||||
isNotIn: 'non è in',
|
||||
near: 'vicino',
|
||||
within: "all'interno",
|
||||
},
|
||||
upload: {
|
||||
crop: 'Raccolto',
|
||||
|
||||
@@ -304,6 +304,7 @@ export const jaTranslations: DefaultTranslationsObject = {
|
||||
contains: '含む',
|
||||
equals: '等しい',
|
||||
exists: '存在す',
|
||||
intersects: '交差する',
|
||||
isGreaterThan: 'より大きい',
|
||||
isGreaterThanOrEqualTo: '以上',
|
||||
isIn: 'あります',
|
||||
@@ -313,6 +314,7 @@ export const jaTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: '等しくない',
|
||||
isNotIn: '入っていません',
|
||||
near: '近く',
|
||||
within: '内で',
|
||||
},
|
||||
upload: {
|
||||
crop: 'クロップ',
|
||||
|
||||
@@ -303,6 +303,7 @@ export const koTranslations: DefaultTranslationsObject = {
|
||||
contains: '포함',
|
||||
equals: '같음',
|
||||
exists: '존재',
|
||||
intersects: '교차합니다',
|
||||
isGreaterThan: '보다 큼',
|
||||
isGreaterThanOrEqualTo: '보다 크거나 같음',
|
||||
isIn: '포함됨',
|
||||
@@ -312,6 +313,7 @@ export const koTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: '같지 않음',
|
||||
isNotIn: '포함되지 않음',
|
||||
near: '근처',
|
||||
within: '내에서',
|
||||
},
|
||||
upload: {
|
||||
crop: '자르기',
|
||||
|
||||
@@ -307,6 +307,7 @@ export const myTranslations: DefaultTranslationsObject = {
|
||||
contains: 'ပါဝင်သည်',
|
||||
equals: 'ညီမျှ',
|
||||
exists: 'တည်ရှိသည်',
|
||||
intersects: 'ကြောက်ခြင်း',
|
||||
isGreaterThan: 'ထက်ကြီးသည်',
|
||||
isGreaterThanOrEqualTo: 'ထက်ကြီးသည် သို့မဟုတ် ညီမျှသည်',
|
||||
isIn: 'ရှိ',
|
||||
@@ -316,6 +317,7 @@ export const myTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'ညီမျှသည်',
|
||||
isNotIn: 'မဝင်ပါ',
|
||||
near: 'နီး',
|
||||
within: 'အတွင်း',
|
||||
},
|
||||
upload: {
|
||||
crop: 'သုန်း',
|
||||
|
||||
@@ -304,6 +304,7 @@ export const nbTranslations: DefaultTranslationsObject = {
|
||||
contains: 'contains',
|
||||
equals: 'lik',
|
||||
exists: 'eksisterer',
|
||||
intersects: 'krysser',
|
||||
isGreaterThan: 'er større enn',
|
||||
isGreaterThanOrEqualTo: 'er større enn eller lik',
|
||||
isIn: 'er i',
|
||||
@@ -313,6 +314,7 @@ export const nbTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'er ikke lik',
|
||||
isNotIn: 'er ikke med',
|
||||
near: 'nær',
|
||||
within: 'innen',
|
||||
},
|
||||
upload: {
|
||||
crop: 'Beskjær',
|
||||
|
||||
@@ -306,6 +306,7 @@ export const nlTranslations: DefaultTranslationsObject = {
|
||||
contains: 'bevat',
|
||||
equals: 'is gelijk aan',
|
||||
exists: 'bestaat',
|
||||
intersects: 'kruist',
|
||||
isGreaterThan: 'is groter dan',
|
||||
isGreaterThanOrEqualTo: 'is groter dan of gelijk aan',
|
||||
isIn: 'is binnen',
|
||||
@@ -315,6 +316,7 @@ export const nlTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'is niet gelijk aan',
|
||||
isNotIn: 'zit er niet in',
|
||||
near: 'nabij',
|
||||
within: 'binnen',
|
||||
},
|
||||
upload: {
|
||||
crop: 'Bijsnijden',
|
||||
|
||||
@@ -304,6 +304,7 @@ export const plTranslations: DefaultTranslationsObject = {
|
||||
contains: 'zawiera',
|
||||
equals: 'równe',
|
||||
exists: 'istnieje',
|
||||
intersects: 'przecina się',
|
||||
isGreaterThan: 'jest większy niż',
|
||||
isGreaterThanOrEqualTo: 'jest większe lub równe',
|
||||
isIn: 'jest w',
|
||||
@@ -313,6 +314,7 @@ export const plTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'nie jest równe',
|
||||
isNotIn: 'nie ma go w',
|
||||
near: 'blisko',
|
||||
within: 'w ciągu',
|
||||
},
|
||||
upload: {
|
||||
crop: 'Przytnij',
|
||||
|
||||
@@ -305,6 +305,7 @@ export const ptTranslations: DefaultTranslationsObject = {
|
||||
contains: 'contém',
|
||||
equals: 'igual',
|
||||
exists: 'existe',
|
||||
intersects: 'intersecciona',
|
||||
isGreaterThan: 'é maior que',
|
||||
isGreaterThanOrEqualTo: 'é maior ou igual a',
|
||||
isIn: 'está em',
|
||||
@@ -314,6 +315,7 @@ export const ptTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'não é igual a',
|
||||
isNotIn: 'não está em',
|
||||
near: 'perto',
|
||||
within: 'dentro',
|
||||
},
|
||||
upload: {
|
||||
crop: 'Cultura',
|
||||
|
||||
@@ -308,6 +308,7 @@ export const roTranslations: DefaultTranslationsObject = {
|
||||
contains: 'conține',
|
||||
equals: 'egal cu',
|
||||
exists: 'există',
|
||||
intersects: 'se intersectează',
|
||||
isGreaterThan: 'este mai mare decât',
|
||||
isGreaterThanOrEqualTo: 'este mai mare sau egal cu',
|
||||
isIn: 'este în',
|
||||
@@ -317,6 +318,7 @@ export const roTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'nu este egal cu',
|
||||
isNotIn: 'nu este în',
|
||||
near: 'în apropiere de',
|
||||
within: 'înăuntru',
|
||||
},
|
||||
upload: {
|
||||
crop: 'Cultură',
|
||||
|
||||
@@ -303,6 +303,7 @@ export const rsTranslations: DefaultTranslationsObject = {
|
||||
contains: 'садржи',
|
||||
equals: 'једнако',
|
||||
exists: 'постоји',
|
||||
intersects: 'preseca',
|
||||
isGreaterThan: 'је веће од',
|
||||
isGreaterThanOrEqualTo: 'је веће од или једнако',
|
||||
isIn: 'је у',
|
||||
@@ -312,6 +313,7 @@ export const rsTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'није једнако',
|
||||
isNotIn: 'није у',
|
||||
near: 'близу',
|
||||
within: 'unutar',
|
||||
},
|
||||
upload: {
|
||||
crop: 'Исеците слику',
|
||||
|
||||
@@ -303,6 +303,7 @@ export const rsLatinTranslations: DefaultTranslationsObject = {
|
||||
contains: 'sadrži',
|
||||
equals: 'jednako',
|
||||
exists: 'postoji',
|
||||
intersects: 'seče',
|
||||
isGreaterThan: 'je veće od',
|
||||
isGreaterThanOrEqualTo: 'je veće od ili jednako',
|
||||
isIn: 'je u',
|
||||
@@ -312,6 +313,7 @@ export const rsLatinTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'nije jednako',
|
||||
isNotIn: 'nije unutra',
|
||||
near: 'blizu',
|
||||
within: 'unutar',
|
||||
},
|
||||
upload: {
|
||||
crop: 'Isecite sliku',
|
||||
|
||||
@@ -307,6 +307,7 @@ export const ruTranslations: DefaultTranslationsObject = {
|
||||
contains: 'содержит',
|
||||
equals: 'равно',
|
||||
exists: 'существует',
|
||||
intersects: 'пересекает',
|
||||
isGreaterThan: 'больше чем',
|
||||
isGreaterThanOrEqualTo: 'больше или равно',
|
||||
isIn: 'находится',
|
||||
@@ -316,6 +317,7 @@ export const ruTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'не равно',
|
||||
isNotIn: 'нет в',
|
||||
near: 'рядом',
|
||||
within: 'в пределах',
|
||||
},
|
||||
upload: {
|
||||
crop: 'Обрезать',
|
||||
|
||||
@@ -305,6 +305,7 @@ export const skTranslations: DefaultTranslationsObject = {
|
||||
contains: 'obsahuje',
|
||||
equals: 'rovná sa',
|
||||
exists: 'existuje',
|
||||
intersects: 'pretína sa',
|
||||
isGreaterThan: 'je väčšie ako',
|
||||
isGreaterThanOrEqualTo: 'je väčšie alebo rovné',
|
||||
isIn: 'je v',
|
||||
@@ -314,6 +315,7 @@ export const skTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'nie je rovné',
|
||||
isNotIn: 'nie je v',
|
||||
near: 'blízko',
|
||||
within: 'vnútri',
|
||||
},
|
||||
upload: {
|
||||
crop: 'Orezať',
|
||||
|
||||
@@ -304,6 +304,7 @@ export const svTranslations: DefaultTranslationsObject = {
|
||||
contains: 'innehåller',
|
||||
equals: 'likar med',
|
||||
exists: 'finns',
|
||||
intersects: 'korsar',
|
||||
isGreaterThan: 'är större än',
|
||||
isGreaterThanOrEqualTo: 'är större än eller lika med',
|
||||
isIn: 'är med',
|
||||
@@ -313,6 +314,7 @@ export const svTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'är inte lika med',
|
||||
isNotIn: 'är inte med',
|
||||
near: 'nära',
|
||||
within: 'inom',
|
||||
},
|
||||
upload: {
|
||||
crop: 'Skörd',
|
||||
|
||||
@@ -300,6 +300,7 @@ export const thTranslations: DefaultTranslationsObject = {
|
||||
contains: 'มี',
|
||||
equals: 'เท่ากับ',
|
||||
exists: 'มีอยู่',
|
||||
intersects: 'ตัดกัน',
|
||||
isGreaterThan: 'มากกว่า',
|
||||
isGreaterThanOrEqualTo: 'มากกว่าหรือเท่ากับ',
|
||||
isIn: 'อยู่ใน',
|
||||
@@ -309,6 +310,7 @@ export const thTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'ไม่เท่ากับ',
|
||||
isNotIn: 'ไม่ได้อยู่ใน',
|
||||
near: 'ใกล้',
|
||||
within: 'ภายใน',
|
||||
},
|
||||
upload: {
|
||||
crop: 'พืชผล',
|
||||
|
||||
@@ -308,6 +308,7 @@ export const trTranslations: DefaultTranslationsObject = {
|
||||
contains: 'içerir',
|
||||
equals: 'eşittir',
|
||||
exists: 'var',
|
||||
intersects: 'kesişir',
|
||||
isGreaterThan: 'şundan büyüktür',
|
||||
isGreaterThanOrEqualTo: 'büyüktür veya eşittir',
|
||||
isIn: 'içinde',
|
||||
@@ -317,6 +318,7 @@ export const trTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'eşit değildir',
|
||||
isNotIn: 'içinde değil',
|
||||
near: 'yakın',
|
||||
within: 'içinde',
|
||||
},
|
||||
upload: {
|
||||
crop: 'Mahsulat',
|
||||
|
||||
@@ -304,6 +304,7 @@ export const ukTranslations: DefaultTranslationsObject = {
|
||||
contains: 'містить',
|
||||
equals: 'дорівнює',
|
||||
exists: 'існує',
|
||||
intersects: 'перетинається',
|
||||
isGreaterThan: 'більше ніж',
|
||||
isGreaterThanOrEqualTo: 'більше або дорівнює',
|
||||
isIn: 'є в',
|
||||
@@ -313,6 +314,7 @@ export const ukTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'не дорівнює',
|
||||
isNotIn: 'не в',
|
||||
near: 'поруч',
|
||||
within: 'в межах',
|
||||
},
|
||||
upload: {
|
||||
crop: 'Обрізати',
|
||||
|
||||
@@ -302,6 +302,7 @@ export const viTranslations: DefaultTranslationsObject = {
|
||||
contains: 'có chứa',
|
||||
equals: 'bằng',
|
||||
exists: 'tồn tại',
|
||||
intersects: 'giao nhau',
|
||||
isGreaterThan: 'lớn hơn',
|
||||
isGreaterThanOrEqualTo: 'lớn hơn hoặc bằng',
|
||||
isIn: 'có trong',
|
||||
@@ -311,6 +312,7 @@ export const viTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: 'không bằng',
|
||||
isNotIn: 'không có trong',
|
||||
near: 'gần',
|
||||
within: 'trong',
|
||||
},
|
||||
upload: {
|
||||
crop: 'Mùa vụ',
|
||||
|
||||
@@ -296,6 +296,7 @@ export const zhTranslations: DefaultTranslationsObject = {
|
||||
contains: '包含',
|
||||
equals: '等于',
|
||||
exists: '存在',
|
||||
intersects: '相交',
|
||||
isGreaterThan: '大于',
|
||||
isGreaterThanOrEqualTo: '大于等于',
|
||||
isIn: '在',
|
||||
@@ -305,6 +306,7 @@ export const zhTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: '不等于',
|
||||
isNotIn: '不在',
|
||||
near: '附近',
|
||||
within: '在...之内',
|
||||
},
|
||||
upload: {
|
||||
crop: '作物',
|
||||
|
||||
@@ -296,6 +296,7 @@ export const zhTwTranslations: DefaultTranslationsObject = {
|
||||
contains: '包含',
|
||||
equals: '等於',
|
||||
exists: '存在',
|
||||
intersects: '交叉點',
|
||||
isGreaterThan: '大於',
|
||||
isGreaterThanOrEqualTo: '大於等於',
|
||||
isIn: '在',
|
||||
@@ -305,6 +306,7 @@ export const zhTwTranslations: DefaultTranslationsObject = {
|
||||
isNotEqualTo: '不等於',
|
||||
isNotIn: '不在',
|
||||
near: '附近',
|
||||
within: '在...之內',
|
||||
},
|
||||
upload: {
|
||||
crop: '裁剪',
|
||||
|
||||
@@ -19,7 +19,7 @@ export type FieldSelectProps = {
|
||||
setSelected: (fields: FieldWithPath[]) => void
|
||||
}
|
||||
|
||||
const combineLabel = ({
|
||||
export const combineLabel = ({
|
||||
customLabel,
|
||||
field,
|
||||
prefix,
|
||||
|
||||
@@ -164,6 +164,7 @@ export const ListControls: React.FC<ListControlsProps> = (props) => {
|
||||
<WhereBuilder
|
||||
collectionPluralLabel={collectionConfig?.labels?.plural}
|
||||
collectionSlug={collectionConfig.slug}
|
||||
fieldMap={fieldMap}
|
||||
key={String(hasWhereParam.current && !searchParams?.where)}
|
||||
/>
|
||||
</AnimateHeight>
|
||||
|
||||
@@ -164,10 +164,10 @@ export const Condition: React.FC<Props> = (props) => {
|
||||
options: valueOptions,
|
||||
relationTo:
|
||||
internalField?.props?.type === 'relationship' &&
|
||||
'cellProps' in internalField.props &&
|
||||
typeof internalField.props.cellProps === 'object' &&
|
||||
'relationTo' in internalField.props.cellProps
|
||||
? internalField.props.cellProps?.relationTo
|
||||
'cellComponentProps' in internalField.props &&
|
||||
typeof internalField.props.cellComponentProps === 'object' &&
|
||||
'relationTo' in internalField.props.cellComponentProps
|
||||
? internalField.props.cellComponentProps?.relationTo
|
||||
: undefined,
|
||||
value: internalQueryValue ?? '',
|
||||
}}
|
||||
|
||||
@@ -7,10 +7,10 @@ import React, { useEffect, useState } from 'react'
|
||||
import type { WhereBuilderProps } from './types.js'
|
||||
|
||||
import { useListQuery } from '../../providers/ListQuery/index.js'
|
||||
import { useLocale } from '../../providers/Locale/index.js'
|
||||
import { useSearchParams } from '../../providers/SearchParams/index.js'
|
||||
import { useTranslation } from '../../providers/Translation/index.js'
|
||||
import { Button } from '../Button/index.js'
|
||||
import { useTableColumns } from '../TableColumns/index.js'
|
||||
import { Condition } from './Condition/index.js'
|
||||
import './index.scss'
|
||||
import { reduceFieldMap } from './reduceFieldMap.js'
|
||||
@@ -26,15 +26,15 @@ export { WhereBuilderProps }
|
||||
* It is part of the {@link ListControls} component which is used to render the controls (search, filter, where).
|
||||
*/
|
||||
export const WhereBuilder: React.FC<WhereBuilderProps> = (props) => {
|
||||
const { collectionPluralLabel } = props
|
||||
const { collectionPluralLabel, fieldMap } = props
|
||||
const { i18n, t } = useTranslation()
|
||||
const { columns } = useTableColumns()
|
||||
const { code: currentLocale } = useLocale()
|
||||
|
||||
const [reducedFields, setReducedColumns] = useState(() => reduceFieldMap(columns, i18n))
|
||||
const [reducedFields, setReducedColumns] = useState(() => reduceFieldMap(fieldMap, i18n))
|
||||
|
||||
useEffect(() => {
|
||||
setReducedColumns(reduceFieldMap(columns, i18n))
|
||||
}, [columns, i18n])
|
||||
setReducedColumns(reduceFieldMap(fieldMap, i18n, undefined, undefined, currentLocale))
|
||||
}, [fieldMap, i18n, currentLocale])
|
||||
|
||||
const { searchParams } = useSearchParams()
|
||||
const { handleWhereChange } = useListQuery()
|
||||
@@ -74,7 +74,6 @@ export const WhereBuilder: React.FC<WhereBuilderProps> = (props) => {
|
||||
if (validateWhereQuery(whereFromSearch)) {
|
||||
return whereFromSearch.or
|
||||
}
|
||||
|
||||
// Transform the where query to be in the right format. This will transform something simple like [text][equals]=example%20post to the right format
|
||||
const transformedWhere = transformWhereQuery(whereFromSearch)
|
||||
|
||||
|
||||
@@ -1,42 +1,86 @@
|
||||
'use client'
|
||||
import type { Column } from '../Table/index.js'
|
||||
import type { FieldMap } from '../../utilities/buildComponentMap.js'
|
||||
|
||||
import { createNestedClientFieldPath } from '../../forms/Form/createNestedFieldPath.js'
|
||||
import { combineLabel } from '../FieldSelect/index.js'
|
||||
import fieldTypes from './field-types.js'
|
||||
|
||||
export const reduceFieldMap = (fieldMap: Column[], i18n) =>
|
||||
fieldMap.reduce((reduced, field) => {
|
||||
export const reduceFieldMap = (
|
||||
fieldMap: FieldMap,
|
||||
i18n,
|
||||
labelPrefix?: string,
|
||||
pathPrefix?: string,
|
||||
locale?: string,
|
||||
) => {
|
||||
return fieldMap.reduce((reduced, field) => {
|
||||
if (field.disableListFilter) return reduced
|
||||
|
||||
if (field.type === 'tabs' && 'tabs' in field.fieldComponentProps) {
|
||||
const tabs = field.fieldComponentProps.tabs
|
||||
tabs.forEach((tab) => {
|
||||
if (tab.name && typeof tab.label === 'string' && tab.fieldMap) {
|
||||
reduced.push(...reduceFieldMap(tab.fieldMap, i18n, tab.label, tab.name))
|
||||
}
|
||||
})
|
||||
return reduced
|
||||
}
|
||||
|
||||
if (field.type === 'group' && 'fieldMap' in field.fieldComponentProps) {
|
||||
reduced.push(
|
||||
...reduceFieldMap(
|
||||
field.fieldComponentProps.fieldMap,
|
||||
i18n,
|
||||
field.fieldComponentProps.label as string,
|
||||
field.name,
|
||||
),
|
||||
)
|
||||
return reduced
|
||||
}
|
||||
|
||||
if (typeof fieldTypes[field.type] === 'object') {
|
||||
const operatorKeys = new Set()
|
||||
|
||||
const operators = fieldTypes[field.type].operators.reduce((acc, operator) => {
|
||||
if (!operatorKeys.has(operator.value)) {
|
||||
operatorKeys.add(operator.value)
|
||||
return [
|
||||
...acc,
|
||||
{
|
||||
acc.push({
|
||||
...operator,
|
||||
label: i18n.t(`operators:${operator.label}`),
|
||||
},
|
||||
]
|
||||
})
|
||||
}
|
||||
return acc
|
||||
}, [])
|
||||
|
||||
const localizedLabel =
|
||||
locale && typeof field.fieldComponentProps.label === 'object'
|
||||
? field.fieldComponentProps.label[locale]
|
||||
: field.fieldComponentProps.label
|
||||
|
||||
const formattedLabel = labelPrefix
|
||||
? combineLabel({
|
||||
field,
|
||||
prefix: labelPrefix,
|
||||
})
|
||||
: localizedLabel
|
||||
|
||||
const formattedValue = pathPrefix
|
||||
? createNestedClientFieldPath(pathPrefix, field)
|
||||
: field.name
|
||||
|
||||
const formattedField = {
|
||||
label: field.Label,
|
||||
value: field.name,
|
||||
label: formattedLabel,
|
||||
value: formattedValue,
|
||||
...fieldTypes[field.type],
|
||||
operators,
|
||||
props: {
|
||||
...field,
|
||||
...(field?.cellProps || {}),
|
||||
...(field?.cellComponentProps || {}),
|
||||
},
|
||||
}
|
||||
|
||||
if (field.admin?.disableListFilter) return reduced
|
||||
|
||||
return [...reduced, formattedField]
|
||||
reduced.push(formattedField)
|
||||
return reduced
|
||||
}
|
||||
|
||||
return reduced
|
||||
}, [])
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import type { Field, Operator, SanitizedCollectionConfig, Where } from 'payload'
|
||||
|
||||
import type { FieldMap } from '../../utilities/buildComponentMap.js'
|
||||
|
||||
export type WhereBuilderProps = {
|
||||
collectionPluralLabel: SanitizedCollectionConfig['labels']['plural']
|
||||
collectionSlug: SanitizedCollectionConfig['slug']
|
||||
fieldMap?: FieldMap
|
||||
}
|
||||
|
||||
export type FieldCondition = {
|
||||
|
||||
@@ -246,6 +246,14 @@ describe('admin2', () => {
|
||||
|
||||
await page.locator('.where-builder__add-first-filter').click()
|
||||
|
||||
const conditionField = page.locator('.condition__field')
|
||||
await conditionField.click()
|
||||
const dropdownFieldOption = conditionField.locator('.rs__option', {
|
||||
hasText: exactText('ID'),
|
||||
})
|
||||
await dropdownFieldOption.click()
|
||||
await expect(page.locator('.condition__field')).toContainText('ID')
|
||||
|
||||
const operatorField = page.locator('.condition__operator')
|
||||
const valueField = page.locator('.condition__value input')
|
||||
|
||||
@@ -256,7 +264,9 @@ describe('admin2', () => {
|
||||
|
||||
await valueField.fill(id)
|
||||
|
||||
await expect(page.locator(tableRowLocator)).toHaveCount(1)
|
||||
const tableRows = page.locator(tableRowLocator)
|
||||
|
||||
await expect(tableRows).toHaveCount(1)
|
||||
const firstId = await page.locator(tableRowLocator).first().locator('.cell-id').innerText()
|
||||
expect(firstId).toEqual(`ID: ${id}`)
|
||||
|
||||
@@ -288,12 +298,15 @@ describe('admin2', () => {
|
||||
await filterField.click()
|
||||
|
||||
// select new filter field of Number
|
||||
const dropdownFieldOptions = filterField.locator('.rs__option')
|
||||
await dropdownFieldOptions.locator('text=Number').click()
|
||||
const dropdownFieldOption = filterField.locator('.rs__option', {
|
||||
hasText: exactText('Status'),
|
||||
})
|
||||
await dropdownFieldOption.click()
|
||||
await expect(filterField).toContainText('Status')
|
||||
|
||||
// expect operator & value field to reset (be empty)
|
||||
await expect(operatorField.locator('.rs__placeholder')).toContainText('Select a value')
|
||||
await expect(valueField).toHaveValue('')
|
||||
await expect(page.locator('.condition__value input')).toHaveValue('')
|
||||
})
|
||||
|
||||
test('should accept where query from valid URL where parameter', async () => {
|
||||
|
||||
Reference in New Issue
Block a user