This is an automated email from the ASF dual-hosted git repository. beto pushed a commit to branch dbt-metricflow in repository https://gitbox.apache.org/repos/asf/superset.git
commit b27d6dc9b6d5fe7f9ab99c05eb8cf8663b117800 Author: Beto Dealmeida <[email protected]> AuthorDate: Thu Jul 17 16:13:01 2025 -0400 Checkpoint --- .../src/shared-controls/dndControls.tsx | 4 +-- .../controls/SemanticLayerVerification.tsx | 32 +++++++++++++----- .../components/controls/withAsyncVerification.tsx | 39 ++++++++++++++-------- 3 files changed, 52 insertions(+), 23 deletions(-) diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/dndControls.tsx b/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/dndControls.tsx index 3d9077b427..120a8cbbd8 100644 --- a/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/dndControls.tsx +++ b/superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/dndControls.tsx @@ -100,8 +100,8 @@ function enhanceControlWithSemanticLayer( if (withAsyncVerification) { const verificationFn = verificationType === 'metrics' - ? createMetricsVerification() - : createColumnsVerification(); + ? createMetricsVerification(controlName) + : createColumnsVerification(controlName); return withAsyncVerification({ baseControl: baseControl.type, diff --git a/superset-frontend/src/explore/components/controls/SemanticLayerVerification.tsx b/superset-frontend/src/explore/components/controls/SemanticLayerVerification.tsx index e9d0192503..850be4e11a 100644 --- a/superset-frontend/src/explore/components/controls/SemanticLayerVerification.tsx +++ b/superset-frontend/src/explore/components/controls/SemanticLayerVerification.tsx @@ -132,17 +132,25 @@ async function callValidationAPI( /** * Create verification function for metrics controls */ -export function createMetricsVerification(): AsyncVerify { +export function createMetricsVerification(controlName?: string): AsyncVerify { return async (props: ControlPropsWithExtras) => { - const { datasource, form_data, savedMetrics = [], actions } = props; + const { datasource, form_data, savedMetrics = [], actions, value } = props; // Only verify for semantic layer datasources if (!supportsSemanticLayerVerification(datasource as Dataset)) { return null; } - // Extract current form fields - const queryFields = collectQueryFields(form_data || {}); + // Create updated form data with the current value + const updatedFormData = { ...form_data }; + + // Update the appropriate field based on the control name + if (value !== undefined && controlName) { + updatedFormData[controlName] = value; + } + + // Extract current form fields from updated form data + const queryFields = collectQueryFields(updatedFormData || {}); // Call validation API const validationResult = await callValidationAPI( @@ -204,17 +212,25 @@ export function createMetricsVerification(): AsyncVerify { /** * Create verification function for dimensions controls */ -export function createColumnsVerification(): AsyncVerify { +export function createColumnsVerification(controlName?: string): AsyncVerify { return async (props: ControlPropsWithExtras) => { - const { datasource, form_data, options = [], actions } = props; + const { datasource, form_data, options = [], actions, value } = props; // Only verify for semantic layer datasources if (!supportsSemanticLayerVerification(datasource as Dataset)) { return null; } - // Extract current form fields - const queryFields = collectQueryFields(form_data || {}); + // Create updated form data with the current value + const updatedFormData = { ...form_data }; + + // Update the appropriate field based on the control name + if (value !== undefined && controlName) { + updatedFormData[controlName] = value; + } + + // Extract current form fields from updated form data + const queryFields = collectQueryFields(updatedFormData || {}); // Call validation API const validationResult = await callValidationAPI( diff --git a/superset-frontend/src/explore/components/controls/withAsyncVerification.tsx b/superset-frontend/src/explore/components/controls/withAsyncVerification.tsx index 5ed60aea4d..852ac70a30 100644 --- a/superset-frontend/src/explore/components/controls/withAsyncVerification.tsx +++ b/superset-frontend/src/explore/components/controls/withAsyncVerification.tsx @@ -145,6 +145,7 @@ export default function withAsyncVerification({ const [verifiedProps, setVerifiedProps] = useState({}); const [isLoading, setIsLoading] = useState<boolean>(initialIsLoading); const { addWarningToast } = restProps.actions; + const verificationTriggeredByChange = useRef(false); // memoize `restProps`, so that verification only triggers when material // props are actually updated. @@ -153,19 +154,6 @@ export default function withAsyncVerification({ otherProps = otherPropsRef.current = restProps; } - const handleChange = useCallback( - (value: JsonValue) => { - // the default onChange handler, triggers the `setControlValue` action - if (basicOnChange) { - basicOnChange(value); - } - if (onChange) { - onChange(value, { ...otherProps, ...verifiedProps }); - } - }, - [basicOnChange, otherProps, verifiedProps], - ); - const verifyProps = useEffectEvent( (verifyFunc: AsyncVerify, props: typeof otherProps) => { if (showLoadingState) { @@ -202,8 +190,33 @@ export default function withAsyncVerification({ }, ); + const handleChange = useCallback( + (value: JsonValue) => { + // the default onChange handler, triggers the `setControlValue` action + if (basicOnChange) { + basicOnChange(value); + } + if (onChange) { + onChange(value, { ...otherProps, ...verifiedProps }); + } + + // Trigger verification with the new value if verification is enabled + if (needAsyncVerification && verify) { + verificationTriggeredByChange.current = true; + const propsWithNewValue = { ...otherProps, ...verifiedProps, value }; + verifyProps(verify, propsWithNewValue); + } + }, + [basicOnChange, otherProps, verifiedProps, needAsyncVerification, verify, verifyProps], + ); + useEffect(() => { if (needAsyncVerification && verify) { + // Skip verification if it was just triggered by onChange + if (verificationTriggeredByChange.current) { + verificationTriggeredByChange.current = false; + return; + } verifyProps(verify, otherProps); } }, [needAsyncVerification, verify, otherProps, verifyProps]);
