SoftwareBrothers / adminjs

AdminJS is an admin panel for apps written in node.js
https://adminjs.co
MIT License
8.25k stars 664 forks source link

Enhancement: Improve filters programming interface #251

Open wojtek-krysiak opened 4 years ago

wojtek-krysiak commented 4 years ago

Problem

Right now filters are passed to BaseResource.find as an object and are parsed inside every adapter separately.

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 would be for "or"

Acceptance criteria

In this task:

Possibilities after this change

MariaRoblesSpin commented 4 years ago

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
wojtek-krysiak commented 4 years ago

@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)

mohamed-nazmi commented 4 years ago

Regarding the feature of filtering a numeric attribute by a range of values, is it available now at v3.1?

wojtek-krysiak commented 4 years ago

nope - I will reopen this task. This is very high priority. This month it should be fixed

danchello commented 3 years ago

Any news on this?

rafa-js commented 2 years ago

Any news on this?

Asher-JH commented 2 years ago

Will this be implemented soon? Or can you share an example of writing our own list handler(including pagination?)

Damilare-alesh99 commented 1 year ago

Any update on this?

dziraf commented 1 year ago

We don't have an ETA yet, but we want to include this as a part of v7

tomups commented 1 year ago

I think this didn't make it to v7 after all?

C0RE1312 commented 7 months ago

Any news on that?

rgcunha commented 7 months ago

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)