This is an automated email from the ASF dual-hosted git repository.

suddjian pushed a commit to branch feature/filter-p0
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git

commit d7e926edbbb47e8274f1cb5bb87500c37ca20d5d
Author: David Aaron Suddjian <[email protected]>
AuthorDate: Thu Sep 17 08:51:28 2020 -0700

    finished filter indicators
---
 .../components/FiltersBadge/DetailsPanel.tsx       | 49 +++++++++---
 .../dashboard/components/FiltersBadge/Styles.tsx   | 21 ++++--
 .../dashboard/components/FiltersBadge/index.tsx    | 55 +++++++++-----
 .../dashboard/components/FiltersBadge/selectors.js | 88 +++++++++-------------
 superset/connectors/base/models.py                 |  2 -
 superset/views/core.py                             |  1 -
 superset/views/utils.py                            |  1 -
 superset/viz.py                                    | 15 ++--
 8 files changed, 131 insertions(+), 101 deletions(-)

diff --git 
a/superset-frontend/src/dashboard/components/FiltersBadge/DetailsPanel.tsx 
b/superset-frontend/src/dashboard/components/FiltersBadge/DetailsPanel.tsx
index 723f6c0..3a8a15d 100644
--- a/superset-frontend/src/dashboard/components/FiltersBadge/DetailsPanel.tsx
+++ b/superset-frontend/src/dashboard/components/FiltersBadge/DetailsPanel.tsx
@@ -1,33 +1,62 @@
 import React from 'react';
+import {
+  SearchOutlined,
+  MinusCircleFilled,
+  CheckCircleFilled,
+  ExclamationCircleFilled,
+} from '@ant-design/icons';
 import { Collapse } from '../../../common/components/index';
-import { SearchOutlined, MinusCircleFilled, CheckCircleFilled, 
ExclamationCircleFilled } from '@ant-design/icons';
 import S from './Styles';
+import { APPLIED, INCOMPATIBLE, UNSET } from './selectors';
 
-const Indicator = ({ indicator: { name, value = [], path }, onClick }) => (
+export type Indicator = {
+  id: string;
+  name: string;
+  value: string[];
+  status: typeof APPLIED | typeof UNSET | typeof INCOMPATIBLE;
+  path: string;
+};
+
+export interface IndicatorProps {
+  indicator: Indicator;
+  onClick: (path: string) => void;
+}
+
+const Indicator = ({
+  indicator: { name, value = [], path },
+  onClick,
+}: IndicatorProps) => (
   <S.Item onClick={() => onClick(path)}>
     <S.ItemIcon>
       <SearchOutlined />
     </S.ItemIcon>
     <S.Title bold>{name.toUpperCase()}</S.Title>
-    {value.length ? `: ${[].concat(value).join(', ')}` : ''}
+    {value.length ? `: ${value.join(', ')}` : ''}
   </S.Item>
 );
 
+export interface DetailsPanelProps {
+  appliedIndicators: Indicator[];
+  incompatibleIndicators: Indicator[];
+  unsetIndicators: Indicator[];
+  onHighlightFilterSource: (path: string) => void;
+}
+
 const DetailsPanel = ({
   appliedIndicators = [],
   incompatibleIndicators = [],
   unsetIndicators = [],
   onHighlightFilterSource,
-}) => {
-  const total = appliedIndicators.length + incompatibleIndicators.length + 
unsetIndicators.length;
+}: DetailsPanelProps) => {
+  const total =
+    appliedIndicators.length +
+    incompatibleIndicators.length +
+    unsetIndicators.length;
   return (
     <S.Panel>
       <div>{`${total} Scoped Filters`}</div>
       <S.Reset>
-        <Collapse
-          ghost
-          defaultActiveKey={['applied', 'incompatible']}
-        >
+        <Collapse ghost defaultActiveKey={['applied', 'incompatible']}>
           {appliedIndicators.length ? (
             <Collapse.Panel
               key="applied"
@@ -96,4 +125,4 @@ const DetailsPanel = ({
   );
 };
 
-export default DetailsPanel;
\ No newline at end of file
+export default DetailsPanel;
diff --git a/superset-frontend/src/dashboard/components/FiltersBadge/Styles.tsx 
b/superset-frontend/src/dashboard/components/FiltersBadge/Styles.tsx
index 7106bae..785a649 100644
--- a/superset-frontend/src/dashboard/components/FiltersBadge/Styles.tsx
+++ b/superset-frontend/src/dashboard/components/FiltersBadge/Styles.tsx
@@ -1,4 +1,4 @@
-import styled from '@superset-ui/style';
+import { styled } from '@superset-ui/core';
 
 const Pill = styled.div`
   display: inline-block;
@@ -9,21 +9,26 @@ const Pill = styled.div`
   padding: 0 8px;
   font-size: 14px;
   font-weight: normal;
-  
+
   &:hover {
     cursor: pointer;
     filter: brightness(3);
   }
-  
+
   svg {
     vertical-align: text-top;
   }
 `;
 
+interface TitleProps {
+  bold?: boolean;
+  color?: string;
+}
+
 const Title = styled.span`
-  color: ${({ color }) => color || 'auto'};
+  color: ${({ color }: TitleProps) => color || 'auto'};
   font-weight: ${({ bold }) => (bold ? '600' : 'auto')};
-  
+
   & > .anticon * {
     color: ${({ color }) => color || 'auto'};
   }
@@ -46,7 +51,7 @@ const Item = styled.button`
   white-space: nowrap;
   position: relative;
   outline: none;
-  
+
   &::-moz-focus-inner {
     border: 0;
   }
@@ -70,7 +75,7 @@ const Panel = styled.div`
   min-width: 200px;
   max-width: 400px;
   overflow-x: hidden;
-    
+
   * {
     color: #fff;
   }
@@ -86,4 +91,4 @@ const S = {
   ItemIcon,
 };
 
-export default S;
\ No newline at end of file
+export default S;
diff --git a/superset-frontend/src/dashboard/components/FiltersBadge/index.tsx 
b/superset-frontend/src/dashboard/components/FiltersBadge/index.tsx
index debf0e9..b6f31d8 100644
--- a/superset-frontend/src/dashboard/components/FiltersBadge/index.tsx
+++ b/superset-frontend/src/dashboard/components/FiltersBadge/index.tsx
@@ -1,15 +1,20 @@
 import React from 'react';
-import { connect } from 'react-redux';
+import { connect, Dispatch, MapStateToProps } from 'react-redux';
 import { bindActionCreators } from 'redux';
 import { WarningFilled } from '@ant-design/icons';
-import {Popover, Icon, Collapse} from '../../../common/components';
 import { ReactComponent as FilterIcon } from 'images/icons/filter.svg';
-import DetailsPanel from './DetailsPanel';
+import { Popover, Icon, Collapse } from '../../../common/components';
+import DetailsPanel, { Indicator } from './DetailsPanel';
 import S from './Styles';
 import { setDirectPathToChild } from '../../actions/dashboardState';
-import { selectIndicatorsForChart, INCOMPATIBLE, APPLIED, UNSET } from 
'./selectors';
+import {
+  selectIndicatorsForChart,
+  INCOMPATIBLE,
+  APPLIED,
+  UNSET,
+} from './selectors';
 
-const mapDispatchToProps = (dispatch) => {
+const mapDispatchToProps = (dispatch: Dispatch<any>) => {
   return bindActionCreators(
     {
       onHighlightFilterSource: setDirectPathToChild,
@@ -18,11 +23,20 @@ const mapDispatchToProps = (dispatch) => {
   );
 };
 
+interface IndexProps {
+  chartId: string;
+}
+
 const mapStateToProps = (
-  { datasources, dashboardFilters, charts },
-  { chartId },
+  { datasources, dashboardFilters, charts }: any,
+  { chartId }: IndexProps,
 ) => {
-  const indicators = selectIndicatorsForChart(chartId, dashboardFilters, 
datasources, charts);
+  const indicators = selectIndicatorsForChart(
+    chartId,
+    dashboardFilters,
+    datasources,
+    charts,
+  );
 
   return {
     chartId,
@@ -32,11 +46,20 @@ const mapStateToProps = (
 
 const Index = ({
   indicators,
-  onHighlightFilterSource
+  onHighlightFilterSource,
+}: {
+  indicators: Indicator[];
+  onHighlightFilterSource: (path: string) => void;
 }) => {
-  const appliedIndicators = indicators.filter((indicator) => indicator.status 
=== APPLIED);
-  const unsetIndicators = indicators.filter((indicator) => indicator.status 
=== UNSET);
-  const incompatibleIndicators = indicators.filter((indicator) => 
indicator.status === INCOMPATIBLE);
+  const appliedIndicators = indicators.filter(
+    indicator => indicator.status === APPLIED,
+  );
+  const unsetIndicators = indicators.filter(
+    indicator => indicator.status === UNSET,
+  );
+  const incompatibleIndicators = indicators.filter(
+    indicator => indicator.status === INCOMPATIBLE,
+  );
 
   if (!appliedIndicators.length && !incompatibleIndicators.length) {
     return null;
@@ -58,7 +81,8 @@ const Index = ({
         color="rgba(0, 0, 0, 0.8)"
       >
         <S.Pill>
-          <Icon component={FilterIcon} /> {appliedIndicators.length + 
incompatibleIndicators.length}
+          <Icon component={FilterIcon} />{' '}
+          {appliedIndicators.length + incompatibleIndicators.length}
           {incompatibleIndicators.length ? (
             <span>
               {' '}
@@ -71,7 +95,4 @@ const Index = ({
   );
 };
 
-export default connect(
-  mapStateToProps,
-  mapDispatchToProps,
-)(Index);
\ No newline at end of file
+export default connect(mapStateToProps, mapDispatchToProps)(Index);
diff --git 
a/superset-frontend/src/dashboard/components/FiltersBadge/selectors.js 
b/superset-frontend/src/dashboard/components/FiltersBadge/selectors.js
index 6bdd0b9..f56ad06 100644
--- a/superset-frontend/src/dashboard/components/FiltersBadge/selectors.js
+++ b/superset-frontend/src/dashboard/components/FiltersBadge/selectors.js
@@ -1,5 +1,5 @@
-import { getChartIdsInFilterScope } from '../../util/activeDashboardFilters';
 import { isNil, get } from 'lodash';
+import { getChartIdsInFilterScope } from '../../util/activeDashboardFilters';
 import { TIME_FILTER_MAP } from '../../../visualizations/FilterBox/FilterBox';
 
 export const UNSET = 'UNSET';
@@ -11,33 +11,6 @@ const TIME_GRANULARITY_FIELDS = new Set([
   TIME_FILTER_MAP.time_grain_sqla,
 ]);
 
-/*
-if (isDateFilter && TIME_GRANULARITY_FIELDS.includes(name)) {
-    const timeGranularityConfig =
-      (name === TIME_FILTER_MAP.time_grain_sqla
-        ? datasource.time_grain_sqla
-        : datasource.granularity) || [];
-    const timeGranularityDisplayMapping = timeGranularityConfig.reduce(
-      (map, [key, value]) => ({
-        ...map,
-        [key]: value,
-      }),
-      {},
-    );
-
-    indicator.values = indicator.values.map(
-      value => timeGranularityDisplayMapping[value] || value,
-    );
-  }
-
-  if (isEmpty(indicator.values)) {
-    indicators[1].push(indicator);
-  } else {
-    indicators[0].push(indicator);
-  }
-});
- */
-
 const selectIndicatorValue = (columnKey, filter, datasource) => {
   if (
     isNil(filter.columns[columnKey]) ||
@@ -68,40 +41,33 @@ const selectIndicatorValue = (columnKey, filter, 
datasource) => {
   return [].concat(filter.columns[columnKey]);
 };
 
-const selectIndicatorStatus = (columnKey, filter, chart) => {
-  if (
-    isNil(filter.columns[columnKey]) ||
-    (filter.isDateFilter && filter.columns[columnKey] === 'No filter') ||
-    (Array.isArray(filter.columns[columnKey]) &&
-      filter.columns[columnKey].length === 0)
-  ) {
-    return UNSET;
-  }
-
-  if (get(chart, 'queryResponse.rejected_filters', []).includes(columnKey)) {
-    return INCOMPATIBLE;
-  }
-
-  return APPLIED;
-};
-
 const selectIndicatorsForChartFromFilter = (
   chartId,
   filter,
   filterDataSource,
-  chart,
+  appliedColumns,
+  rejectedColumns,
 ) => {
+  // filters can be applied (if the filter is compatible with the datasource)
+  // or rejected (if the filter is incompatible)
+  // or the status can be unknown (if the filter has calculated parameters 
that we can't analyze)
+  const getStatus = column => {
+    if (appliedColumns.has(column)) return APPLIED;
+    if (rejectedColumns.has(column)) return INCOMPATIBLE;
+    return UNSET;
+  };
+
   return Object.keys(filter.columns)
-    .filter(key =>
-      getChartIdsInFilterScope({ filterScope: filter.scopes[key] }).includes(
+    .filter(column =>
+      getChartIdsInFilterScope({ filterScope: filter.scopes[column] 
}).includes(
         chartId,
       ),
     )
-    .map(key => ({
-      id: key,
-      name: filter.labels[key] || key,
-      value: selectIndicatorValue(key, filter, filterDataSource),
-      status: selectIndicatorStatus(key, filter, chart),
+    .map(column => ({
+      id: column,
+      name: filter.labels[column] || column,
+      value: selectIndicatorValue(column, filter, filterDataSource),
+      status: getStatus(column),
       path: filter.directPathToFilter,
     }));
 };
@@ -112,6 +78,19 @@ export const selectIndicatorsForChart = (
   datasources,
   charts,
 ) => {
+  const chart = charts[chartId];
+  // for now we only need to know which columns are compatible/incompatible,
+  // so grab the columns from the applied/rejected filters
+  const appliedColumns = new Set(
+    get(chart, 'queryResponse.applied_filters', []).map(
+      filter => filter.column,
+    ),
+  );
+  const rejectedColumns = new Set(
+    get(chart, 'queryResponse.rejected_filters', []).map(
+      filter => filter.column,
+    ),
+  );
   return Object.values(filters)
     .filter(filter => filter.chartId !== chartId)
     .reduce(
@@ -121,7 +100,8 @@ export const selectIndicatorsForChart = (
             chartId,
             filter,
             datasources[filter.datasourceId] || {},
-            charts[chartId],
+            appliedColumns,
+            rejectedColumns,
           ),
         ),
       [],
diff --git a/superset/connectors/base/models.py 
b/superset/connectors/base/models.py
index 724a9ce..52f6521 100644
--- a/superset/connectors/base/models.py
+++ b/superset/connectors/base/models.py
@@ -14,7 +14,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-import logging
 import json
 from enum import Enum
 from typing import Any, Dict, Hashable, List, Optional, Type, Union
@@ -30,7 +29,6 @@ from superset.models.helpers import AuditMixinNullable, 
ImportMixin, QueryResult
 from superset.models.slice import Slice
 from superset.typing import FilterValue, FilterValues, QueryObjectDict
 from superset.utils import core as utils
-logger = logging.getLogger(__name__)
 METRIC_FORM_DATA_PARAMS = [
     "metric",
     "metrics",
diff --git a/superset/views/core.py b/superset/views/core.py
index 8899efb..ef94632 100755
--- a/superset/views/core.py
+++ b/superset/views/core.py
@@ -511,7 +511,6 @@ class Superset(BaseSupersetView):  # pylint: 
disable=too-many-public-methods
 
         TODO: break into one endpoint for each return shape"""
 
-        logger.info('test123')
         response_type = utils.ChartDataResultFormat.JSON.value
         responses: List[
             Union[utils.ChartDataResultFormat, utils.ChartDataResultType]
diff --git a/superset/views/utils.py b/superset/views/utils.py
index f941834..eaecc5f 100644
--- a/superset/views/utils.py
+++ b/superset/views/utils.py
@@ -105,7 +105,6 @@ def get_viz(
     form_data: FormData, datasource_type: str, datasource_id: int, force: bool 
= False
 ) -> BaseViz:
     viz_type = form_data.get("viz_type", "table")
-    logger.info('testaa3')
     datasource = ConnectorRegistry.get_datasource(
         datasource_type, datasource_id, db.session
     )
diff --git a/superset/viz.py b/superset/viz.py
index bdf1f0b..7ac6f58 100644
--- a/superset/viz.py
+++ b/superset/viz.py
@@ -345,12 +345,6 @@ class BaseViz:
         merge_extra_filters(self.form_data)
         utils.split_adhoc_filters_into_base_filters(self.form_data)
 
-        filters = self.form_data.get("filters")
-        filter_columns = [flt.get("col") for flt in filters]
-        columns = set(self.datasource.column_names)
-        self.applied_filters = [{"column": col} for col in filter_columns if 
col in columns]
-        self.rejected_filters = [{"reason": "not_in_datasource", "column": 
col} for col in filter_columns if col not in columns]
-
     def query_obj(self) -> QueryObjectDict:
         """Building a query object"""
         form_data = self.form_data
@@ -488,8 +482,13 @@ class BaseViz:
         if "df" in payload:
             del payload["df"]
 
-        payload["applied_filters"] = self.applied_filters
-        payload["rejected_filters"] = self.rejected_filters
+        filters = self.form_data.get("filters")
+        filter_columns = [flt.get("col") for flt in filters]
+        columns = set(self.datasource.column_names)
+        payload["applied_filters"] = [{"column": col} for col in 
filter_columns if col in columns]
+        payload["rejected_filters"] = [{"reason": "not_in_datasource", 
"column": col} for col in filter_columns if col not in columns]
+        logger.info(payload["applied_filters"])
+        logger.info(payload["rejected_filters"])
 
         return payload
 

Reply via email to