-
Notifications
You must be signed in to change notification settings - Fork 4.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dashboard: when updating parameters, run only relevant queries #3804
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -137,8 +137,16 @@ function DashboardCtrl( | |
this.extractGlobalParameters(); | ||
}); | ||
|
||
const collectFilters = (dashboard, forceRefresh) => { | ||
const queryResultPromises = _.compact(this.dashboard.widgets.map((widget) => { | ||
const collectFilters = (dashboard, forceRefresh, updatedParameters = []) => { | ||
const affectedWidgets = updatedParameters.length > 0 ? this.dashboard.widgets.filter( | ||
widget => Object.values(widget.getParameterMappings()).filter( | ||
({ type }) => type === 'dashboard-level', | ||
).some( | ||
({ mapTo }) => _.includes(updatedParameters.map(p => p.name), mapTo), | ||
), | ||
) : this.dashboard.widgets; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm uncertain There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Filtering by Here's a demo https://deploy-preview-3804--redash-preview.netlify.com/dashboard/param-update-tester. Change the dashboard parameter, and all widgets refresh even though the middle one shouldn't, since it only has a widget-level param. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch. I switched it to use the proper parameter mapping. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Works perfectly 👍 I know you must have worked on making the filter logic readable but I think it's still a bit complex to comprehend. Here's my suggestion: let affectedWidgets = dashboard.widgets;
if (updatedParameters.length) {
const updateParamNames = updatedParameters.map(p => p.name); // do just once
affectedWidgets = dashboard.widgets.filter(
widget => _.chain(widget.getParameterMappings()) // I like chaining :P
.filter({ type: 'dashboard-level' })
.some(({ mapTo }) => _.includes(updateParamNames, mapTo))
.value(),
);
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Chaining prevents webpack from including only the functions we use from lodash 😬 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ranbena thanks for introducing me to lodash chain sequences! I don't think it would be significant to lose tree shaking on lodash, but I'm still not entirely convinced that the change from filter({ type }) => type === 'dashboard-level') to filter({ type: 'dashboard-level' }) makes things simpler, especially given that some simpletons such as myself would possibly have to scratch their heads around I personally find expressions a primary goal for achieving simplicity. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It does makes things a lot more readable, I wonder if it's really that costly when considering Lodash 😬 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Forget it! Let's land this already! |
||
|
||
const queryResultPromises = _.compact(affectedWidgets.map((widget) => { | ||
widget.getParametersDefs(); // Force widget to read parameters values from URL | ||
return widget.load(forceRefresh); | ||
})); | ||
|
@@ -202,9 +210,9 @@ function DashboardCtrl( | |
|
||
this.loadDashboard(); | ||
|
||
this.refreshDashboard = () => { | ||
this.refreshDashboard = (parameters) => { | ||
this.refreshInProgress = true; | ||
collectFilters(this.dashboard, true).finally(() => { | ||
collectFilters(this.dashboard, true, parameters).finally(() => { | ||
this.refreshInProgress = false; | ||
}); | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now we can use
parametersWithPendingValues
here too :)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I understand. Are you referring to using
parametersWithPendingValues
in the following line? As inIf that's what you mean, I deliberately avoided that in order to future-proof someone removing the
hasPendingValue
check inapplyPendingValue
without knowing of this external concern.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't be that concerned about it (doesn't seem a likely thing or something that would cause a big issue here). But not a big deal in any case :)