Skip to content
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

[DEV-8698] Applies Filters on MultiDash Switch #1389

Merged
merged 3 commits into from
Jul 16, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 95 additions & 2 deletions packages/dashboard/src/CdcDashboardComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -261,10 +261,11 @@ export default function CdcDashboard({ initialState, isEditor = false, isDebug =
if (config.filterBehavior !== FilterBehavior.Apply) {
reloadURLData()
}
// run addValuesToFilters to set Data Filters.

const sharedFiltersWithValues = addValuesToFilters<SharedFilter>(config.dashboard.sharedFilters, state.data)
loadAPIFilters(sharedFiltersWithValues)
}, [isEditor, isPreview])
updateDataFilters()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if you move this into the first useEffect right after loadAPIFilters it would also work. Did you try that?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is related to this issue you mentioned on 3. in dev-8409

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is related to this issue you mentioned on 3. in dev-8409

I don't believe so, 3 in 8409 is related to the value not being checked for null in packages/dashboard/src/helpers/generateValuesForFilter.ts

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if you move this into the first useEffect right after loadAPIFilters it would also work. Did you try that?

Yes, I had tried that, but the useEffect only has isEditor and isPreview as dependencies, so it doesn't fire when the dashboard multi-tab is changed. I can combine the useEffects possibly, including state.config?.activeDashboard on the first useEffect, but then API filters will reload every time the multi-tab changes.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joshlacey I combined the useeffects in the latest commit, let me know if looks better now

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should update the shared filters and then pass the result to loadAPIFilters. that's what I'm doing in the dashboard filters refactor branch

}, [isEditor, isPreview, state.config?.activeDashboard])

const updateChildConfig = (visualizationKey, newConfig) => {
const config = _.cloneDeep(state.config)
Expand All @@ -287,6 +288,98 @@ export default function CdcDashboard({ initialState, isEditor = false, isDebug =
}
}

const applyFilters = () => {
const dashboardConfig = _.cloneDeep(state.config.dashboard)
const autoLoadViz = getAutoLoadVisualization(state.config.visualizations)
const nonAutoLoadFilterIndexes = autoLoadViz?.hide || []
const allRequiredFiltersSelected = !dashboardConfig.sharedFilters.some((filter, filterIndex) => {
if (nonAutoLoadFilterIndexes.includes(filterIndex)) {
return !filter.active && !filter.queuedActive
} else {
// autoload filters don't need to be selected to apply filters
return false
}
})
if (allRequiredFiltersSelected) {
if (state.config.filterBehavior === FilterBehavior.Apply) {
const queryParams = getQueryParams()
let needsQueryUpdate = false
dashboardConfig.sharedFilters.forEach((sharedFilter, index) => {
if (sharedFilter.queuedActive) {
dashboardConfig.sharedFilters[index].active = sharedFilter.queuedActive
delete dashboardConfig.sharedFilters[index].queuedActive

if (sharedFilter.setByQueryParameter && queryParams[sharedFilter.setByQueryParameter] !== sharedFilter.active) {
queryParams[sharedFilter.setByQueryParameter] = sharedFilter.active
needsQueryUpdate = true
}
}
})

if (needsQueryUpdate) {
updateQueryString(queryParams)
}
}

dispatch({ type: 'SET_SHARED_FILTERS', payload: dashboardConfig.sharedFilters })
updateFilteredData()
loadAPIFilters(dashboardConfig.sharedFilters)
.then(newFilters => {
reloadURLData(newFilters)
})
.catch(e => {
console.error(e)
})
} else {
// TODO noftify of required fields
}
}

const updateFilteredData = (sharedFilters?) => {
const clonedState = _.cloneDeep(state)
if (sharedFilters) clonedState.config.dashboard.sharedFilters = sharedFilters
const newFilteredData = getFilteredData(clonedState)
dispatch({ type: 'SET_FILTERED_DATA', payload: newFilteredData })
}

const updateDataFilters = (sharedFilters = undefined) => {
const clonedState = _.cloneDeep(state)
if (sharedFilters) clonedState.config.dashboard.sharedFilters = sharedFilters
const newFilteredData = getFilteredData(clonedState)
dispatch({ type: 'SET_FILTERED_DATA', payload: newFilteredData })
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does the filtered data have to do with the values on the dashboard filter?

}

const handleOnChange = (index: number, value: string | string[]) => {
const config = _.cloneDeep(state.config)
let newSharedFilters = changeFilterActive(index, value, config)

if (config.filterBehavior === FilterBehavior.Apply) {
const isAutoSelectFilter = autoLoadFilterIndexes.includes(index)
const missingFilterSelections = config.dashboard.sharedFilters.some(f => !f.active)
if (isAutoSelectFilter && !missingFilterSelections) {
// a dropdown has been selected that doesn't
// require the Go Button
loadAPIFilters(newSharedFilters).then(filters => {
reloadURLData(filters)
})
} else {
if (Array.isArray(value)) throw Error(`Cannot set active values on urlfilters. expected: ${JSON.stringify(value)} to be a single value.`)
newSharedFilters[index].queuedActive = value
// setData to empty object because we no longer have a data state.
dispatch({ type: 'SET_DATA', payload: {} })
dispatch({ type: 'SET_FILTERED_DATA', payload: {} })
loadAPIFilters(newSharedFilters)
}
} else {
if (newSharedFilters[index].apiFilter) {
reloadURLData(newSharedFilters)
} else {
updateFilteredData(newSharedFilters)
dispatch({ type: 'SET_SHARED_FILTERS', payload: newSharedFilters })
}
}
}

const resizeObserver = new ResizeObserver(entries => {
for (let entry of entries) {
let newViewport = getViewport(entry.contentRect.width)
Expand Down
Loading