Query Report Dynamic Filters Architecture Fix - #292
Open
Sendipad wants to merge 1 commit into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
1. Dynamic Link Resolution in ControlRegistry
The
Dynamic Linkfieldtype mapping in control_registry.js now elegantly falls back to querying its sibling filters:This ensures that if a user sets the target DocType of a Link dynamically (e.g., through a
party_typefield), theControlRegistrycorrectly resolves the current selected value.Because
ControlFactoryoperates as a computed property bounded tocontext, Vue natively re-evaluatesControlRegistry.resolvethe moment theparty_typefilter is updated.2. API Compatibility Layer in Meta Store
We've decoupled Frappe-specific
get_queryAPI parsing from the generic UI controls.A new method
execute_get_querywas added to useMetaStore.js:This entirely patches the silent error where Frappe Query Reports returned a configuration object (e.g.,
{ query: '...', filters: {...} }) instead of a flat array of rows.3. Top-Down Reactive Dependency Graph
The core issue underlying stale caches for dependent filters was the failure to notify child controls that their underlying data had changed. We resolved this by explicitly injecting the reactive
report_filter_valuesgraph into thecontext:filters: report_filter_valuesintoFlexValueControl'scontext.:filters="context?.filters || {}"and:context="context".props.filters:dependencyVersiontracking.4. Bypassing ControlFactory for Multi-Selects
In FlexValueControl.vue, the
isMultiSelectcomputed property was previously only true when there was an operator like "in" or "not in". We updated it to also natively handleMultiSelectList,MultiSelect, andMultiCheckfieldtypes.This ensures that report filters using these types are rendered directly via
<MultiSelectList>instead of being proxied through<ControlFactory>(which previously swallowed thecontextandget_dataprops).5. Resolving Sibling Filter References
We enhanced
referenceDoctypeinFlexValueControl.vueto resolve dependencies dynamically. When a field (likeparty) specifies its target DocType as the name of another filter (e.g.options: "party_type"), it now reads the actual value (e.g."Customer") fromcontext.filters:6. Breaking the Reactivity Feedback Loop
We fixed a severe flicker bug where selecting a value in a
MultiSelectListwould instantly reset the field.The issue occurred because the component watched the global
props.filtersobject. When a user selected a value, it updatedreport_filter_values, which triggered theprops.filtersdeep watcher inside the same component, causing it to wipe its own state viaclearAll().We broke this loop in both
MultiSelectList.vueandComboBoxControl.vueby making the watcher inspect the before/after values ofprops.filtersand aborting the reset if the only changed key was the component's owndf.fieldname.Summary
The combination of explicit
filtersinjection, native multi-select rendering, dynamic reference resolution, and loop-safe reactivity guarantees that dependent filters work harmoniously. Every time an upstream parent filter changes, any child Links, Dynamic Links, and MultiSelectLists will autonomously wipe their caches and re-fetch options without manual event emitters, while safely persisting user selections.