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 de13b1cf44a156da691a7a834e05925b85604828 Author: Beto Dealmeida <[email protected]> AuthorDate: Thu Jul 17 15:52:51 2025 -0400 Disable instead of hide --- .../src/shared-controls/dndControls.tsx | 4 +- .../DatasourcePanelDragOption/index.tsx | 24 ++++-- .../DatasourcePanel/DatasourcePanelItem.tsx | 1 + .../explore/components/DatasourcePanel/types.ts | 2 + .../controls/SemanticLayerVerification.tsx | 89 ++++++++++++---------- 5 files changed, 70 insertions(+), 50 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 03cb0fefbd..3d9077b427 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 @@ -123,7 +123,9 @@ function enhanceControlWithSemanticLayer( // Only add semantic layer props if utilities are available if (withAsyncVerification) { - const needsVerification = needsSemanticLayerVerification(state.datasource); + const needsVerification = needsSemanticLayerVerification( + state.datasource, + ); return { ...originalProps, diff --git a/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragOption/index.tsx b/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragOption/index.tsx index 533b6c4bb1..d4054dc5aa 100644 --- a/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragOption/index.tsx +++ b/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragOption/index.tsx @@ -29,8 +29,8 @@ import { Icons } from '@superset-ui/core/components/Icons'; import { DatasourcePanelDndItem } from '../types'; -const DatasourceItemContainer = styled.div` - ${({ theme }) => css` +const DatasourceItemContainer = styled.div<{ isDisabled?: boolean }>` + ${({ theme, isDisabled }) => css` display: flex; align-items: center; justify-content: space-between; @@ -40,12 +40,16 @@ const DatasourceItemContainer = styled.div` // hack to make the drag preview image corners rounded transform: translate(0, 0); - color: ${theme.colorText}; + color: ${isDisabled ? theme.colorTextSecondary : theme.colorText}; background-color: ${theme.colorBgLayout}; border-radius: 4px; + opacity: ${isDisabled ? 0.5 : 1}; + cursor: ${isDisabled ? 'not-allowed' : 'grab'}; &:hover { - background-color: ${theme.colorPrimaryBgHover}; + background-color: ${isDisabled + ? theme.colorBgLayout + : theme.colorPrimaryBgHover}; } > div { @@ -58,6 +62,7 @@ const DatasourceItemContainer = styled.div` interface DatasourcePanelDragOptionProps extends DatasourcePanelDndItem { labelRef?: RefObject<any>; showTooltip?: boolean; + isDisabled?: boolean; } type MetricOption = Omit<Metric, 'id'> & { @@ -67,7 +72,7 @@ type MetricOption = Omit<Metric, 'id'> & { export default function DatasourcePanelDragOption( props: DatasourcePanelDragOptionProps, ) { - const { labelRef, showTooltip, type, value } = props; + const { labelRef, showTooltip, type, value, isDisabled } = props; const [{ isDragging }, drag] = useDrag({ item: { value: props.value, @@ -76,6 +81,7 @@ export default function DatasourcePanelDragOption( collect: monitor => ({ isDragging: monitor.isDragging(), }), + canDrag: !isDisabled, }); const optionProps = { @@ -85,13 +91,17 @@ export default function DatasourcePanelDragOption( }; return ( - <DatasourceItemContainer data-test="DatasourcePanelDragOption" ref={drag}> + <DatasourceItemContainer + data-test="DatasourcePanelDragOption" + ref={isDisabled ? undefined : drag} + isDisabled={isDisabled} + > {type === DndItemType.Column ? ( <StyledColumnOption column={value as ColumnMeta} {...optionProps} /> ) : ( <StyledMetricOption metric={value as MetricOption} {...optionProps} /> )} - <Icons.Drag /> + {isDisabled ? <Icons.LockOutlined /> : <Icons.Drag />} </DatasourceItemContainer> ); } diff --git a/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelItem.tsx b/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelItem.tsx index 115f5b729c..93a215910c 100644 --- a/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelItem.tsx +++ b/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelItem.tsx @@ -244,6 +244,7 @@ const DatasourcePanelItem = ({ ? DndItemType.Column : DndItemType.Metric } + isDisabled={item.item.isDisabled} /> </LabelWrapper> )} diff --git a/superset-frontend/src/explore/components/DatasourcePanel/types.ts b/superset-frontend/src/explore/components/DatasourcePanel/types.ts index 0639f3c827..73e88cf7fc 100644 --- a/superset-frontend/src/explore/components/DatasourcePanel/types.ts +++ b/superset-frontend/src/explore/components/DatasourcePanel/types.ts @@ -62,10 +62,12 @@ export type DatasourceFolder = { export type MetricItem = Metric & { type: 'metric'; + isDisabled?: boolean; }; export type ColumnItem = DatasourcePanelColumn & { type: 'column'; + isDisabled?: boolean; }; export type FolderItem = MetricItem | ColumnItem; diff --git a/superset-frontend/src/explore/components/controls/SemanticLayerVerification.tsx b/superset-frontend/src/explore/components/controls/SemanticLayerVerification.tsx index e618ee8f92..e9d0192503 100644 --- a/superset-frontend/src/explore/components/controls/SemanticLayerVerification.tsx +++ b/superset-frontend/src/explore/components/controls/SemanticLayerVerification.tsx @@ -94,7 +94,7 @@ function supportsSemanticLayerVerification(datasource: Dataset): boolean { if (!datasource || !('database' in datasource) || !datasource.database) { return false; } - + const database = datasource.database as any; return Boolean(database.engine_information?.supports_dynamic_columns); } @@ -161,40 +161,42 @@ export function createMetricsVerification(): AsyncVerify { validMetricNames.has(metric.metric_name || metric), ); - // Also filter the datasource metrics (for left panel) if this is a Dataset + // Mark datasource metrics and columns as disabled if invalid (for left panel) const dataset = datasource as Dataset; - let filteredDatasourceMetrics = dataset.metrics; - let filteredDatasourceColumns = dataset.columns; - + let updatedDatasourceMetrics = dataset.metrics; + let updatedDatasourceColumns = dataset.columns; + if (dataset.metrics) { - filteredDatasourceMetrics = dataset.metrics.filter((metric: any) => - validMetricNames.has(metric.metric_name || metric), - ); + updatedDatasourceMetrics = dataset.metrics.map((metric: any) => ({ + ...metric, + isDisabled: !validMetricNames.has(metric.metric_name || metric), + })); } - - // Also filter columns using the same validation result + + // Also update columns using the same validation result const validDimensionNames = new Set(validationResult.dimensions); if (dataset.columns) { - filteredDatasourceColumns = dataset.columns.filter((column: any) => - validDimensionNames.has(column.column_name || column), - ); + updatedDatasourceColumns = dataset.columns.map((column: any) => ({ + ...column, + isDisabled: !validDimensionNames.has(column.column_name || column), + })); } - // Create filtered datasource for left panel - const filteredDatasource = { + // Create updated datasource for left panel + const updatedDatasource = { ...dataset, - metrics: filteredDatasourceMetrics, - columns: filteredDatasourceColumns, + metrics: updatedDatasourceMetrics, + columns: updatedDatasourceColumns, }; // Update the Redux store's datasource to affect the left panel if (actions && typeof actions.syncDatasourceMetadata === 'function') { - actions.syncDatasourceMetadata(filteredDatasource); + actions.syncDatasourceMetadata(updatedDatasource); } return { savedMetrics: filteredSavedMetrics, - datasource: filteredDatasource, + datasource: updatedDatasource, }; }; } @@ -225,46 +227,49 @@ export function createColumnsVerification(): AsyncVerify { return null; } - // Filter dimension options to only include valid ones + // Mark dimension options as disabled if invalid const validDimensionNames = new Set(validationResult.dimensions); - const filteredOptions = options.filter((option: any) => - validDimensionNames.has(option.column_name || option), - ); + const updatedOptions = options.map((option: any) => ({ + ...option, + isDisabled: !validDimensionNames.has(option.column_name || option), + })); - // Also filter the datasource columns (for left panel) if this is a Dataset + // Mark datasource columns and metrics as disabled if invalid (for left panel) const dataset = datasource as Dataset; - let filteredDatasourceColumns = dataset.columns; - let filteredDatasourceMetrics = dataset.metrics; - + let updatedDatasourceColumns = dataset.columns; + let updatedDatasourceMetrics = dataset.metrics; + if (dataset.columns) { - filteredDatasourceColumns = dataset.columns.filter((column: any) => - validDimensionNames.has(column.column_name || column), - ); + updatedDatasourceColumns = dataset.columns.map((column: any) => ({ + ...column, + isDisabled: !validDimensionNames.has(column.column_name || column), + })); } - - // Also filter metrics using the same validation result + + // Also update metrics using the same validation result const validMetricNames = new Set(validationResult.metrics); if (dataset.metrics) { - filteredDatasourceMetrics = dataset.metrics.filter((metric: any) => - validMetricNames.has(metric.metric_name || metric), - ); + updatedDatasourceMetrics = dataset.metrics.map((metric: any) => ({ + ...metric, + isDisabled: !validMetricNames.has(metric.metric_name || metric), + })); } - // Create filtered datasource for left panel - const filteredDatasource = { + // Create updated datasource for left panel + const updatedDatasource = { ...dataset, - columns: filteredDatasourceColumns, - metrics: filteredDatasourceMetrics, + columns: updatedDatasourceColumns, + metrics: updatedDatasourceMetrics, }; // Update the Redux store's datasource to affect the left panel if (actions && typeof actions.syncDatasourceMetadata === 'function') { - actions.syncDatasourceMetadata(filteredDatasource); + actions.syncDatasourceMetadata(updatedDatasource); } return { - options: filteredOptions, - datasource: filteredDatasource, + options: updatedOptions, + datasource: updatedDatasource, }; }; }
