adminjs
adminjs copied to clipboard
Enhancement: Improve filters programming interface
Problem
Right now filters are passed to BaseResource.find as an object and are parsed inside every adapter separately.
- Passing object is ugly because we have to create it on AdminBro core and pass to the adapter
- Current filter structure doesn't allow to filter by let say greater than in integers, or by relation.
We have to change Filter instance to a simple filter object with the strict interface.
Interface proposal (example)
type FilterQuery = {
eq?: string,
gt?: string,
lt?: string,
contain?: string, // for like
in?: Array<string>
}
type Filter = {
[path: string]: FilterQuery | Array<FilterQuery> | {and: Array<FilterQuery>}
}
Array<FilterQuery> would be for "or"
Acceptance criteria
In this task:
- unify the filters programming interface
- the best would be if it will be backwards compatible
- allow adapters to define which operations they support. Mybe some new adapter couldn't support
in? - it should be possible to filter by nested properties
Possibilities after this change
- we will be able to add
filterto ResourceOptions which will restrict the list/search actions - or to list Action interface. - we could pass filter in useRecords hook
- we could pass filter in PropertyOptions of the property responsible for handing one to many relationshipp
It is not possible to change the filter label.
module.exports.actionLabels = {
list: { label: 'Todos' },
edit: { label: 'Editar' },
show: { label: 'Detalle' },
new: { label: 'Añadir Nuevo' },
filter: { label: 'Search' },
delete: {
label: 'Borrar',
guard: '¿Seguro que quieres borrar este elemento?'
},
}
without filter everything works fine. with filter I see these errors into the browser console:
backend.js:6 The above error occurred in the <ActionButton> component:
in ActionButton (created by Context.Consumer)
in Connect(ActionButton) (created by Context.Consumer)
in withRouter(Connect(ActionButton)) (created by ActionHeader)
in div (created by Context.Consumer)
in StyledComponent (created by action-header__HeaderButtons)
in action-header__HeaderButtons (created by ActionHeader)
in section (created by Context.Consumer)
in StyledComponent (created by action-header__HeaderWrapper)
in action-header__HeaderWrapper (created by ActionHeader)
in ActionHeader (created by ResourceAction)
in section (created by Context.Consumer)
in StyledComponent (created by wrapper-box__StyledWrapperBox)
in wrapper-box__StyledWrapperBox (created by WrapperBox)
in WrapperBox (created by ResourceAction)
in div (created by ResourceAction)
in ResourceAction (created by Context.Consumer)
in Connect(ResourceAction) (created by Context.Consumer)
in Route (created by App)
in Switch (created by App)
in section (created by Context.Consumer)
in StyledComponent (created by application__Core)
in application__Core (created by App)
in section (created by Context.Consumer)
in StyledComponent (created by application__ApplicationWrapper)
in application__ApplicationWrapper (created by App)
in App
in Router (created by BrowserRouter)
in BrowserRouter
in ThemeProvider
in Provider
Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://fb.me/react-error-boundaries to learn more about error boundaries.
r @ backend.js:6
logCapturedError @ global.bundle.js:40180
logError @ global.bundle.js:40217
update.callback @ global.bundle.js:41305
callCallback @ global.bundle.js:33418
commitUpdateEffects @ global.bundle.js:33456
commitUpdateQueue @ global.bundle.js:33446
commitLifeCycles @ global.bundle.js:40494
commitLayoutEffects @ global.bundle.js:43386
callCallback @ global.bundle.js:21148
invokeGuardedCallbackDev @ global.bundle.js:21197
invokeGuardedCallback @ global.bundle.js:21252
commitRootImpl @ global.bundle.js:43124
unstable_runWithPriority @ global.bundle.js:20181
runWithPriority$2 @ global.bundle.js:31785
commitRoot @ global.bundle.js:42964
finishSyncRender @ global.bundle.js:42397
performSyncWorkOnRoot @ global.bundle.js:42375
(anonymous) @ global.bundle.js:31835
unstable_runWithPriority @ global.bundle.js:20181
runWithPriority$2 @ global.bundle.js:31785
flushSyncCallbackQueueImpl @ global.bundle.js:31830
flushSyncCallbackQueue @ global.bundle.js:31818
discreteUpdates$1 @ global.bundle.js:42482
discreteUpdates @ global.bundle.js:22173
dispatchDiscreteEvent @ global.bundle.js:25932
backend.js:6 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
in List$7 (created by Context.Consumer)
in withRouter(List$7) (created by Context.Consumer)
in Connect(withRouter(List$7)) (created by BaseActionComponent)
in ErrorBoundary (created by BaseActionComponent)
in BaseActionComponent (created by ResourceAction)
in section (created by Context.Consumer)
in StyledComponent (created by wrapper-box__StyledWrapperBox)
in wrapper-box__StyledWrapperBox (created by WrapperBox)
in WrapperBox (created by ResourceAction)
in div (created by ResourceAction)
in ResourceAction (created by Context.Consumer)
in Connect(ResourceAction) (created by Context.Consumer)
in Route (created by App)
in Switch (created by App)
in section (created by Context.Consumer)
in StyledComponent (created by application__Core)
in application__Core (created by App)
in section (created by Context.Consumer)
in StyledComponent (created by application__ApplicationWrapper)
in application__ApplicationWrapper (created by App)
in App
in Router (created by BrowserRouter)
in BrowserRouter
in ThemeProvider
in Provider
r @ backend.js:6
warningWithoutStack @ global.bundle.js:21342
warnAboutUpdateOnUnmountedFiberInDEV @ global.bundle.js:43745
scheduleUpdateOnFiber @ global.bundle.js:41749
enqueueSetState @ global.bundle.js:33583
Component.setState @ global.bundle.js:524
(anonymous) @ list.tsx:90
Promise.then (async)
_fetchData @ list.tsx:88
shouldComponentUpdate @ list.tsx:63
checkShouldComponentUpdate @ global.bundle.js:33631
updateClassInstance @ global.bundle.js:34127
updateClassComponent @ global.bundle.js:37755
beginWork$1 @ global.bundle.js:39250
beginWork$$1 @ global.bundle.js:43763
performUnitOfWork @ global.bundle.js:42737
workLoopSync @ global.bundle.js:42713
performSyncWorkOnRoot @ global.bundle.js:42338
(anonymous) @ global.bundle.js:31835
unstable_runWithPriority @ global.bundle.js:20181
runWithPriority$2 @ global.bundle.js:31785
flushSyncCallbackQueueImpl @ global.bundle.js:31830
flushSyncCallbackQueue @ global.bundle.js:31818
discreteUpdates$1 @ global.bundle.js:42482
discreteUpdates @ global.bundle.js:22173
dispatchDiscreteEvent @ global.bundle.js:25932
backend.js:6 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
in ResourceAction (created by Context.Consumer)
in Connect(ResourceAction) (created by Context.Consumer)
in Route (created by App)
in Switch (created by App)
in section (created by Context.Consumer)
in StyledComponent (created by application__Core)
in application__Core (created by App)
in section (created by Context.Consumer)
in StyledComponent (created by application__ApplicationWrapper)
in application__ApplicationWrapper (created by App)
in App
in Router (created by BrowserRouter)
in BrowserRouter
in ThemeProvider
in Provider
@MariaRoblesSpin in v2.0 we added i18n support. Check out the docs here: https://softwarebrothers.github.io/admin-bro-dev/v2/tutorial-09-i18n.html (v2 is in beta right now)
Regarding the feature of filtering a numeric attribute by a range of values, is it available now at v3.1?
nope - I will reopen this task. This is very high priority. This month it should be fixed
Any news on this?
Any news on this?
Will this be implemented soon? Or can you share an example of writing our own list handler(including pagination?)
Any update on this?
We don't have an ETA yet, but we want to include this as a part of v7
I think this didn't make it to v7 after all?
Any news on that?
I am using adminJS v7.4.1 and the nested filters don't seem to work so I suppose it was not included in V7. The QueryFilter interface is also not exposed.
Non working example with nested fields:
const createdAt = {
$gte: new Date(`${previousYear}-01-01`),
$lt: new Date(`${year}-01-01`)
}
const filter = new Filter({ createdAt }, resource)
Working example with non nested fields:
const schemaVersion = 2
const filter = new Filter({ schemaVersion }, resource)