This is an automated email from the ASF dual-hosted git repository. suddjian pushed a commit to branch native-filters-fast-follow in repository https://gitbox.apache.org/repos/asf/incubator-superset.git
commit f9b59ead027f5823c5d16458a472f3775b3af828 Author: David Aaron Suddjian <[email protected]> AuthorDate: Wed Nov 25 10:35:59 2020 -0800 switch to the filter with validation errors on submit --- .../components/nativeFilters/FilterConfigModal.tsx | 93 ++++++++++++++-------- 1 file changed, 58 insertions(+), 35 deletions(-) diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterConfigModal.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterConfigModal.tsx index 8cc9f3e..0f50c84 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FilterConfigModal.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterConfigModal.tsx @@ -154,44 +154,67 @@ export function FilterConfigModal({ } const onOk = useCallback(async () => { + let values: NativeFiltersForm | null = null; try { - const values = (await form.validateFields()) as NativeFiltersForm; - const newFilterConfig: FilterConfiguration = filterIds - .filter(id => !removedFilters[id]) - .map(id => { - // create a filter config object from the form inputs - const formInputs = values.filters[id]; - // if user didn't open a filter, return the original config - if (!formInputs) return filterConfigMap[id]; - return { - id, - name: formInputs.name, - type: 'text', - // for now there will only ever be one target - targets: [ - { - datasetId: formInputs.dataset.value, - column: { - name: formInputs.column, - }, + values = (await form.validateFields()) as NativeFiltersForm; + } catch (error) { + console.warn('Filter Configuration Failed:', error); + + if (!error.errorFields || !error.errorFields.length) return; // not a validation error + + // the name is in array format since the fields are nested + type ErrorFields = { name: ['filters', string, string] }[]; + const errorFields = error.errorFields as ErrorFields; + // filter id is the second item in the field name + if (!errorFields.some(field => field.name[1] === currentFilterId)) { + // switch to the first tab that had a validation error + setCurrentFilterId(errorFields[0].name[1]); + } + } + + if (values == null) return; + + const newFilterConfig: FilterConfiguration = filterIds + .filter(id => !removedFilters[id]) + .map(id => { + // create a filter config object from the form inputs + const formInputs = values.filters[id]; + // if user didn't open a filter, return the original config + if (!formInputs) return filterConfigMap[id]; + return { + id, + name: formInputs.name, + type: 'text', + // for now there will only ever be one target + targets: [ + { + datasetId: formInputs.dataset.value, + column: { + name: formInputs.column, }, - ], - defaultValue: formInputs.defaultValue || null, - scope: { - rootPath: [DASHBOARD_ROOT_ID], - excluded: [], }, - isInstant: !!formInputs.isInstant, - allowsMultipleValues: !!formInputs.allowsMultipleValues, - isRequired: !!formInputs.isRequired, - }; - }); - await save(newFilterConfig); - resetForm(); - } catch (info) { - console.log('Filter Configuration Failed:', info); - } - }, [form, save, resetForm, filterIds, removedFilters, filterConfigMap]); + ], + defaultValue: formInputs.defaultValue || null, + scope: { + rootPath: [DASHBOARD_ROOT_ID], + excluded: [], + }, + isInstant: !!formInputs.isInstant, + allowsMultipleValues: !!formInputs.allowsMultipleValues, + isRequired: !!formInputs.isRequired, + }; + }); + await save(newFilterConfig); + resetForm(); + }, [ + form, + save, + resetForm, + filterIds, + currentFilterId, + removedFilters, + filterConfigMap, + ]); return ( <StyledModal
