MemberJunction / MemberJunction/MJ
Entity data grid has no filtering, so scoped views become hardcoded duplicate pages or hand-rolled grids (the filter components already exist)
- Dominant language
- TSQL
- Stars
- 29
- Forks
- 6
- Avg merge
- 2d 1h
- Merged PRs (30d)
- 323
Description
## Summary
`mj-explorer-entity-data-grid` exposes search, sort, New, refresh, export, delete and open-record — but **no filtering**. The consequence is that any "show me a scoped subset" requirement has no answer inside the platform grid, so apps either hand-roll a grid (losing everything the platform grid gives) or ship three near-duplicate pages that differ only by a hardcoded `ExtraFilter`.
**The notable part: MJ already has the filter components.** `@memberjunction/ng-ui-components` ships `mj-filter-panel`, `mj-filter-field`, `mj-filter-popover`, `mj-filter-chip` and `mj-applied-filters`, and there is a `filter-builder` package. So this is very likely *wiring existing components to the grid*, not building filtering from scratch — which should make it a considerably smaller job than the title suggests.
## What it costs today, concretely
In `bizapps-contracts`:
- The contract list, "Renewals & expiry" and "Awaiting documents" are **the same grid over the same view with different hardcoded `ExtraFilter`s and different default pills** — three pages because a user cannot filter one.
- The **customer view** (every agreement for one organisation) is only reachable as a bespoke panel contributed onto the Organization form, because there is no way to say "this grid, filtered to this customer" as a user action.
- A supersede picker needed "contracts at the same tree level that are not already superseded". Neither `mj-form-field`'s FK picker nor `mj-find-record` accepts a predicate, so the filtering had to be done in app code with a hand-built candidate list feeding an `mj-combobox`.
Each of those is a reasonable product need that the platform grid cannot express, and each produced app-level code that will drift from the platform.
## Proposal
Wire the existing filter components into `mj-explorer-entity-data-grid`:
- A toolbar affordance (alongside Search) opening `mj-filter-panel` / `mj-filter-popover`, with fields derived from the entity's `EntityField` metadata — types, and `ValueListType='List'` fields as pick-lists, which the metadata already carries.
- Applied filters surfaced as `mj-applied-filters` / `mj-filter-chip` so the active scope is visible and individually removable, rather than hidden state.
- Compose with the existing `Params.ExtraFilter` rather than replacing it, so an app-supplied scope (a related-entity grid's join filter) is preserved and the user filters *within* it. This is the important semantic: a related grid on a form must not become unscoped because a user added a filter.
- `ShowFilterButton` input, defaulting consistently with the other `Show*` toolbar inputs, so existing embeds are unchanged.
Worth considering in the same pass, since it shares the plumbing: a predicate/filter input on the FK picker (`mj-form-field`) and on `mj-find-record`. Both currently take an entity and no way to restrict candidates, which is the same gap at a different surface. (I opened and closed #3993 on the narrower "search more than one field" framing — filtering is the right shape, and that issue was withdrawn in favour of this one.)
## Not blocking us
We have workarounds for all three cases above; none is pretty and all are app code doing platform work. Raising it because it is a small, obviously-reasonable capability whose absence keeps producing hand-rolled UI — which is the thing MJ's conventions specifically tell app authors not to do.
Contributor guide
Research direction
Start at mj-explorer-entity-data-grid and inspect the existing mj-filter-panel, mj-filter-popover, mj-applied-filters, and mj-filter-chip components in @memberjunction/ng-ui-components. Trace EntityField metadata and Params.ExtraFilter, then verify that the toolbar filter affordance, removable applied filters, ShowFilterButton input, and composed app scope all behave as described.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- angular, typescript
- Domain
- frontend
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100