You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by el...@apache.org on 2023/07/07 22:41:41 UTC

[superset] 11/12: fix: Select all issue with "Dynamically search all filter values" in FilterBar (#23400)

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

elizabeth pushed a commit to branch 2.1
in repository https://gitbox.apache.org/repos/asf/superset.git

commit a34da923fe52077a1560b07f19dc94ead29e9827
Author: Geido <60...@users.noreply.github.com>
AuthorDate: Fri Mar 17 13:04:07 2023 +0100

    fix: Select all issue with "Dynamically search all filter values" in FilterBar (#23400)
    
    (cherry picked from commit 2fe695d3cfa54f626c37944b01b64998936ad75e)
---
 .../components/Select/SelectFilterPlugin.tsx       | 92 ++++++++++++----------
 1 file changed, 51 insertions(+), 41 deletions(-)

diff --git a/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx b/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx
index fb8e20093c..d3cb2b4dea 100644
--- a/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx
+++ b/superset-frontend/src/filters/components/Select/SelectFilterPlugin.tsx
@@ -38,6 +38,7 @@ import { Select } from 'src/components';
 import { SLOW_DEBOUNCE } from 'src/constants';
 import { propertyComparator } from 'src/components/Select/utils';
 import { FilterBarOrientation } from 'src/dashboard/types';
+import { uniqWith, isEqual } from 'lodash';
 import { PluginFilterSelectProps, SelectValue } from './types';
 import { FilterPluginStyle, StatusMessage, StyledFormItem } from '../common';
 import { getDataRecordFormatter, getSelectExtraFormData } from '../../utils';
@@ -120,6 +121,7 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
       }),
     [],
   );
+  const [initialData, setInitialData] = useState<typeof data>([]);
 
   const updateDataMask = useCallback(
     (values: SelectValue) => {
@@ -165,10 +167,6 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
     ],
   );
 
-  useEffect(() => {
-    updateDataMask(filterState.value);
-  }, [JSON.stringify(filterState.value)]);
-
   const isDisabled =
     appSection === AppSection.FILTER_CONFIG_MODAL && defaultToFirstItem;
 
@@ -224,6 +222,47 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
     [updateDataMask],
   );
 
+  const placeholderText =
+    data.length === 0
+      ? t('No data')
+      : tn('%s option', '%s options', data.length, data.length);
+
+  const formItemExtra = useMemo(() => {
+    if (filterState.validateMessage) {
+      return (
+        <StatusMessage status={filterState.validateStatus}>
+          {filterState.validateMessage}
+        </StatusMessage>
+      );
+    }
+    return undefined;
+  }, [filterState.validateMessage, filterState.validateStatus]);
+
+  const options = useMemo(() => {
+    const allOptions = [...data, ...initialData];
+    const uniqueOptions = uniqWith(allOptions, isEqual);
+    const selectOptions: { label: string; value: DataRecordValue }[] = [];
+    uniqueOptions.forEach(row => {
+      const [value] = groupby.map(col => row[col]);
+      selectOptions.push({
+        label: labelFormatter(value, datatype),
+        value,
+      });
+    });
+    return selectOptions;
+  }, [data, initialData, datatype, groupby, labelFormatter]);
+
+  const sortComparator = useCallback(
+    (a: AntdLabeledValue, b: AntdLabeledValue) => {
+      const labelComparator = propertyComparator('label');
+      if (formData.sortAscending) {
+        return labelComparator(a, b);
+      }
+      return labelComparator(b, a);
+    },
+    [formData.sortAscending],
+  );
+
   useEffect(() => {
     if (defaultToFirstItem && filterState.value === undefined) {
       // initialize to first value if set to default to first item
@@ -254,48 +293,19 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
     JSON.stringify(filterState),
   ]);
 
+  useEffect(() => {
+    updateDataMask(filterState.value);
+  }, [JSON.stringify(filterState.value)]);
+
   useEffect(() => {
     setDataMask(dataMask);
   }, [JSON.stringify(dataMask)]);
 
-  const placeholderText =
-    data.length === 0
-      ? t('No data')
-      : tn('%s option', '%s options', data.length, data.length);
-
-  const formItemExtra = useMemo(() => {
-    if (filterState.validateMessage) {
-      return (
-        <StatusMessage status={filterState.validateStatus}>
-          {filterState.validateMessage}
-        </StatusMessage>
-      );
+  useEffect(() => {
+    if (data.length && !initialData.length) {
+      setInitialData(data);
     }
-    return undefined;
-  }, [filterState.validateMessage, filterState.validateStatus]);
-
-  const options = useMemo(() => {
-    const options: { label: string; value: DataRecordValue }[] = [];
-    data.forEach(row => {
-      const [value] = groupby.map(col => row[col]);
-      options.push({
-        label: labelFormatter(value, datatype),
-        value,
-      });
-    });
-    return options;
-  }, [data, datatype, groupby, labelFormatter]);
-
-  const sortComparator = useCallback(
-    (a: AntdLabeledValue, b: AntdLabeledValue) => {
-      const labelComparator = propertyComparator('label');
-      if (formData.sortAscending) {
-        return labelComparator(a, b);
-      }
-      return labelComparator(b, a);
-    },
-    [formData.sortAscending],
-  );
+  }, [data, initialData.length]);
 
   return (
     <FilterPluginStyle height={height} width={width}>