fix(explore): don't allow selecting duplicated saved metric (#12657)

This commit is contained in:
Kamil Gabryjelski 2021-01-22 00:51:59 +01:00 committed by GitHub
parent a90ebd94d4
commit 6280b34483
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 34 additions and 15 deletions

View File

@ -43,7 +43,7 @@ const propTypes = {
onResize: PropTypes.func.isRequired, onResize: PropTypes.func.isRequired,
getCurrentTab: PropTypes.func, getCurrentTab: PropTypes.func,
columns: PropTypes.arrayOf(columnType), columns: PropTypes.arrayOf(columnType),
savedMetrics: PropTypes.arrayOf(savedMetricType), savedMetricsOptions: PropTypes.arrayOf(savedMetricType),
savedMetric: savedMetricType, savedMetric: savedMetricType,
datasourceType: PropTypes.string, datasourceType: PropTypes.string,
title: PropTypes.shape({ title: PropTypes.shape({
@ -76,8 +76,8 @@ export default class AdhocMetricEditPopover extends React.Component {
// "Saved" is a default tab unless there are no saved metrics for dataset // "Saved" is a default tab unless there are no saved metrics for dataset
defaultActiveTabKey = defaultActiveTabKey =
(this.props.savedMetric.metric_name || this.props.adhocMetric.isNew) && (this.props.savedMetric.metric_name || this.props.adhocMetric.isNew) &&
Array.isArray(this.props.savedMetrics) && Array.isArray(this.props.savedMetricsOptions) &&
this.props.savedMetrics.length > 0 this.props.savedMetricsOptions.length > 0
? SAVED_TAB_KEY ? SAVED_TAB_KEY
: this.props.adhocMetric.expressionType; : this.props.adhocMetric.expressionType;
@ -173,7 +173,7 @@ export default class AdhocMetricEditPopover extends React.Component {
} }
onSavedMetricChange(savedMetricId) { onSavedMetricChange(savedMetricId) {
const savedMetric = this.props.savedMetrics.find( const savedMetric = this.props.savedMetricsOptions.find(
metric => metric.id === savedMetricId, metric => metric.id === savedMetricId,
); );
this.setState(prevState => ({ this.setState(prevState => ({
@ -259,7 +259,7 @@ export default class AdhocMetricEditPopover extends React.Component {
adhocMetric: propsAdhocMetric, adhocMetric: propsAdhocMetric,
savedMetric: propsSavedMetric, savedMetric: propsSavedMetric,
columns, columns,
savedMetrics, savedMetricsOptions,
onChange, onChange,
onClose, onClose,
onResize, onResize,
@ -303,7 +303,7 @@ export default class AdhocMetricEditPopover extends React.Component {
}; };
const savedSelectProps = { 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, value: savedMetric?.verbose_name || savedMetric?.metric_name,
onChange: this.onSavedMetricChange, onChange: this.onSavedMetricChange,
allowClear: true, allowClear: true,
@ -349,8 +349,8 @@ export default class AdhocMetricEditPopover extends React.Component {
<strong>{t('Saved metric')}</strong> <strong>{t('Saved metric')}</strong>
</FormLabel> </FormLabel>
<Select name="select-saved" {...savedSelectProps}> <Select name="select-saved" {...savedSelectProps}>
{Array.isArray(savedMetrics) && {Array.isArray(savedMetricsOptions) &&
savedMetrics.map(savedMetric => ( savedMetricsOptions.map(savedMetric => (
<Select.Option <Select.Option
value={savedMetric.id} value={savedMetric.id}
filterBy={ filterBy={

View File

@ -31,7 +31,7 @@ const propTypes = {
onMetricEdit: PropTypes.func.isRequired, onMetricEdit: PropTypes.func.isRequired,
onRemoveMetric: PropTypes.func, onRemoveMetric: PropTypes.func,
columns: PropTypes.arrayOf(columnType), columns: PropTypes.arrayOf(columnType),
savedMetrics: PropTypes.arrayOf(savedMetricType), savedMetricsOptions: PropTypes.arrayOf(savedMetricType),
savedMetric: savedMetricType, savedMetric: savedMetricType,
datasourceType: PropTypes.string, datasourceType: PropTypes.string,
onMoveLabel: PropTypes.func, onMoveLabel: PropTypes.func,
@ -55,7 +55,7 @@ class AdhocMetricOption extends React.PureComponent {
adhocMetric, adhocMetric,
onMetricEdit, onMetricEdit,
columns, columns,
savedMetrics, savedMetricsOptions,
savedMetric, savedMetric,
datasourceType, datasourceType,
onMoveLabel, onMoveLabel,
@ -67,7 +67,7 @@ class AdhocMetricOption extends React.PureComponent {
adhocMetric={adhocMetric} adhocMetric={adhocMetric}
onMetricEdit={onMetricEdit} onMetricEdit={onMetricEdit}
columns={columns} columns={columns}
savedMetrics={savedMetrics} savedMetricsOptions={savedMetricsOptions}
savedMetric={savedMetric} savedMetric={savedMetric}
datasourceType={datasourceType} datasourceType={datasourceType}
> >

View File

@ -29,7 +29,7 @@ export type AdhocMetricPopoverTriggerProps = {
adhocMetric: AdhocMetric; adhocMetric: AdhocMetric;
onMetricEdit: () => void; onMetricEdit: () => void;
columns: { column_name: string; type: string }[]; columns: { column_name: string; type: string }[];
savedMetrics: savedMetricType[]; savedMetricsOptions: savedMetricType[];
savedMetric: savedMetricType; savedMetric: savedMetricType;
datasourceType: string; datasourceType: string;
children: ReactNode; children: ReactNode;
@ -105,7 +105,7 @@ class AdhocMetricPopoverTrigger extends React.PureComponent<
adhocMetric={adhocMetric} adhocMetric={adhocMetric}
title={title} title={title}
columns={this.props.columns} columns={this.props.columns}
savedMetrics={this.props.savedMetrics} savedMetricsOptions={this.props.savedMetricsOptions}
savedMetric={this.props.savedMetric} savedMetric={this.props.savedMetric}
datasourceType={this.props.datasourceType} datasourceType={this.props.datasourceType}
onResize={this.onPopoverResize} onResize={this.onPopoverResize}

View File

@ -35,6 +35,7 @@ const propTypes = {
onDropLabel: PropTypes.func, onDropLabel: PropTypes.func,
columns: PropTypes.arrayOf(columnType), columns: PropTypes.arrayOf(columnType),
savedMetrics: PropTypes.arrayOf(savedMetricType), savedMetrics: PropTypes.arrayOf(savedMetricType),
savedMetricsOptions: PropTypes.arrayOf(savedMetricType),
multi: PropTypes.bool, multi: PropTypes.bool,
datasourceType: PropTypes.string, datasourceType: PropTypes.string,
}; };
@ -45,6 +46,7 @@ export default function MetricDefinitionValue({
onRemoveMetric, onRemoveMetric,
columns, columns,
savedMetrics, savedMetrics,
savedMetricsOptions,
datasourceType, datasourceType,
onMoveLabel, onMoveLabel,
onDropLabel, onDropLabel,
@ -68,7 +70,7 @@ export default function MetricDefinitionValue({
onMetricEdit, onMetricEdit,
onRemoveMetric, onRemoveMetric,
columns, columns,
savedMetrics, savedMetricsOptions,
datasourceType, datasourceType,
adhocMetric, adhocMetric,
onMoveLabel, onMoveLabel,

View File

@ -64,6 +64,16 @@ const defaultProps = {
columns: [], columns: [],
}; };
function getOptionsForSavedMetrics(savedMetrics, currentMetricValues) {
return (
savedMetrics?.filter(savedMetric =>
Array.isArray(currentMetricValues)
? !currentMetricValues.includes(savedMetric.metric_name)
: savedMetric,
) ?? []
);
}
function isDictionaryForAdhocMetric(value) { function isDictionaryForAdhocMetric(value) {
return value && !(value instanceof AdhocMetric) && value.expressionType; return value && !(value instanceof AdhocMetric) && value.expressionType;
} }
@ -131,6 +141,10 @@ class MetricsControl extends React.PureComponent {
onRemoveMetric={() => this.onRemoveMetric(index)} onRemoveMetric={() => this.onRemoveMetric(index)}
columns={this.props.columns} columns={this.props.columns}
savedMetrics={this.props.savedMetrics} savedMetrics={this.props.savedMetrics}
savedMetricsOptions={getOptionsForSavedMetrics(
this.props.savedMetrics,
this.props.value,
)}
datasourceType={this.props.datasourceType} datasourceType={this.props.datasourceType}
onMoveLabel={this.moveLabel} onMoveLabel={this.moveLabel}
onDropLabel={() => this.props.onChange(this.state.value)} onDropLabel={() => this.props.onChange(this.state.value)}
@ -268,7 +282,10 @@ class MetricsControl extends React.PureComponent {
adhocMetric={new AdhocMetric({ isNew: true })} adhocMetric={new AdhocMetric({ isNew: true })}
onMetricEdit={this.onNewMetric} onMetricEdit={this.onNewMetric}
columns={this.props.columns} columns={this.props.columns}
savedMetrics={this.props.savedMetrics} savedMetricsOptions={getOptionsForSavedMetrics(
this.props.savedMetrics,
this.props.value,
)}
savedMetric={{}} savedMetric={{}}
datasourceType={this.props.datasourceType} datasourceType={this.props.datasourceType}
createNew createNew