You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by vi...@apache.org on 2021/01/29 15:01:46 UTC

[superset] 01/02: fix(explore): don't allow selecting duplicated saved metric (#12657)

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

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

commit 72b4c7ec8d8905d94cb926128b963ff1b1ecf650
Author: Kamil Gabryjelski <ka...@gmail.com>
AuthorDate: Fri Jan 22 00:51:59 2021 +0100

    fix(explore): don't allow selecting duplicated saved metric (#12657)
---
 .../controls/MetricControl/AdhocMetricEditPopover.jsx | 16 ++++++++--------
 .../controls/MetricControl/AdhocMetricOption.jsx      |  6 +++---
 .../MetricControl/AdhocMetricPopoverTrigger.tsx       |  4 ++--
 .../controls/MetricControl/MetricDefinitionValue.jsx  |  4 +++-
 .../controls/MetricControl/MetricsControl.jsx         | 19 ++++++++++++++++++-
 5 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover.jsx b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover.jsx
index 3c37eb1..93135e6 100644
--- a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover.jsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover.jsx
@@ -44,7 +44,7 @@ const propTypes = {
   getCurrentTab: PropTypes.func,
   getCurrentLabel: PropTypes.func,
   columns: PropTypes.arrayOf(columnType),
-  savedMetrics: PropTypes.arrayOf(savedMetricType),
+  savedMetricsOptions: PropTypes.arrayOf(savedMetricType),
   savedMetric: savedMetricType,
   datasourceType: PropTypes.string,
 };
@@ -73,8 +73,8 @@ export default class AdhocMetricEditPopover extends React.PureComponent {
   // "Saved" is a default tab unless there are no saved metrics for dataset
   defaultActiveTabKey =
     (this.props.savedMetric.metric_name || this.props.adhocMetric.isNew) &&
-    Array.isArray(this.props.savedMetrics) &&
-    this.props.savedMetrics.length > 0
+    Array.isArray(this.props.savedMetricsOptions) &&
+    this.props.savedMetricsOptions.length > 0
       ? SAVED_TAB_KEY
       : this.props.adhocMetric.expressionType;
 
@@ -179,7 +179,7 @@ export default class AdhocMetricEditPopover extends React.PureComponent {
   }
 
   onSavedMetricChange(savedMetricId) {
-    const savedMetric = this.props.savedMetrics.find(
+    const savedMetric = this.props.savedMetricsOptions.find(
       metric => metric.id === savedMetricId,
     );
     this.setState(prevState => ({
@@ -265,7 +265,7 @@ export default class AdhocMetricEditPopover extends React.PureComponent {
       adhocMetric: propsAdhocMetric,
       savedMetric: propsSavedMetric,
       columns,
-      savedMetrics,
+      savedMetricsOptions,
       onChange,
       onClose,
       onResize,
@@ -309,7 +309,7 @@ export default class AdhocMetricEditPopover extends React.PureComponent {
     };
 
     const savedSelectProps = {
-      placeholder: t('%s saved metric(s)', savedMetrics?.length ?? 0),
+      placeholder: t('%s saved metric(s)', savedMetricsOptions?.length ?? 0),
       value: savedMetric?.verbose_name || savedMetric?.metric_name,
       onChange: this.onSavedMetricChange,
       allowClear: true,
@@ -355,8 +355,8 @@ export default class AdhocMetricEditPopover extends React.PureComponent {
                 <strong>{t('Saved metric')}</strong>
               </FormLabel>
               <Select name="select-saved" {...savedSelectProps}>
-                {Array.isArray(savedMetrics) &&
-                  savedMetrics.map(savedMetric => (
+                {Array.isArray(savedMetricsOptions) &&
+                  savedMetricsOptions.map(savedMetric => (
                     <Select.Option
                       value={savedMetric.id}
                       filterBy={
diff --git a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricOption.jsx b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricOption.jsx
index a43d93f..ad063fb 100644
--- a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricOption.jsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricOption.jsx
@@ -31,7 +31,7 @@ const propTypes = {
   onMetricEdit: PropTypes.func.isRequired,
   onRemoveMetric: PropTypes.func,
   columns: PropTypes.arrayOf(columnType),
-  savedMetrics: PropTypes.arrayOf(savedMetricType),
+  savedMetricsOptions: PropTypes.arrayOf(savedMetricType),
   savedMetric: savedMetricType,
   datasourceType: PropTypes.string,
   onMoveLabel: PropTypes.func,
@@ -55,7 +55,7 @@ class AdhocMetricOption extends React.PureComponent {
       adhocMetric,
       onMetricEdit,
       columns,
-      savedMetrics,
+      savedMetricsOptions,
       savedMetric,
       datasourceType,
       onMoveLabel,
@@ -67,7 +67,7 @@ class AdhocMetricOption extends React.PureComponent {
         adhocMetric={adhocMetric}
         onMetricEdit={onMetricEdit}
         columns={columns}
-        savedMetrics={savedMetrics}
+        savedMetricsOptions={savedMetricsOptions}
         savedMetric={savedMetric}
         datasourceType={datasourceType}
       >
diff --git a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricPopoverTrigger.tsx b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricPopoverTrigger.tsx
index 70167e6..dd7b4bf 100644
--- a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricPopoverTrigger.tsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricPopoverTrigger.tsx
@@ -30,7 +30,7 @@ export type AdhocMetricPopoverTriggerProps = {
   adhocMetric: AdhocMetric;
   onMetricEdit(newMetric: Metric, oldMetric: Metric): void;
   columns: { column_name: string; type: string }[];
-  savedMetrics: savedMetricType[];
+  savedMetricsOptions: savedMetricType[];
   savedMetric: savedMetricType;
   datasourceType: string;
   children: ReactNode;
@@ -157,7 +157,7 @@ class AdhocMetricPopoverTrigger extends React.PureComponent<
         adhocMetric={adhocMetric}
         title={title}
         columns={this.props.columns}
-        savedMetrics={this.props.savedMetrics}
+        savedMetricsOptions={this.props.savedMetricsOptions}
         savedMetric={this.props.savedMetric}
         datasourceType={this.props.datasourceType}
         onResize={this.onPopoverResize}
diff --git a/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionValue.jsx b/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionValue.jsx
index 30acfda..704c2c8 100644
--- a/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionValue.jsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionValue.jsx
@@ -35,6 +35,7 @@ const propTypes = {
   onDropLabel: PropTypes.func,
   columns: PropTypes.arrayOf(columnType),
   savedMetrics: PropTypes.arrayOf(savedMetricType),
+  savedMetricsOptions: PropTypes.arrayOf(savedMetricType),
   multi: PropTypes.bool,
   datasourceType: PropTypes.string,
 };
@@ -45,6 +46,7 @@ export default function MetricDefinitionValue({
   onRemoveMetric,
   columns,
   savedMetrics,
+  savedMetricsOptions,
   datasourceType,
   onMoveLabel,
   onDropLabel,
@@ -68,7 +70,7 @@ export default function MetricDefinitionValue({
       onMetricEdit,
       onRemoveMetric,
       columns,
-      savedMetrics,
+      savedMetricsOptions,
       datasourceType,
       adhocMetric,
       onMoveLabel,
diff --git a/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.jsx b/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.jsx
index 7b7233f..a4916e9 100644
--- a/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.jsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.jsx
@@ -64,6 +64,16 @@ const defaultProps = {
   columns: [],
 };
 
+function getOptionsForSavedMetrics(savedMetrics, currentMetricValues) {
+  return (
+    savedMetrics?.filter(savedMetric =>
+      Array.isArray(currentMetricValues)
+        ? !currentMetricValues.includes(savedMetric.metric_name)
+        : savedMetric,
+    ) ?? []
+  );
+}
+
 function isDictionaryForAdhocMetric(value) {
   return value && !(value instanceof AdhocMetric) && value.expressionType;
 }
@@ -131,6 +141,10 @@ class MetricsControl extends React.PureComponent {
         onRemoveMetric={() => this.onRemoveMetric(index)}
         columns={this.props.columns}
         savedMetrics={this.props.savedMetrics}
+        savedMetricsOptions={getOptionsForSavedMetrics(
+          this.props.savedMetrics,
+          this.props.value,
+        )}
         datasourceType={this.props.datasourceType}
         onMoveLabel={this.moveLabel}
         onDropLabel={() => this.props.onChange(this.state.value)}
@@ -268,7 +282,10 @@ class MetricsControl extends React.PureComponent {
         adhocMetric={new AdhocMetric({ isNew: true })}
         onMetricEdit={this.onNewMetric}
         columns={this.props.columns}
-        savedMetrics={this.props.savedMetrics}
+        savedMetricsOptions={getOptionsForSavedMetrics(
+          this.props.savedMetrics,
+          this.props.value,
+        )}
         savedMetric={{}}
         datasourceType={this.props.datasourceType}
         createNew