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/03/15 10:48:18 UTC
[superset] branch master updated: feat(explore): Drag and drop UX
improvements (#13598)
This is an automated email from the ASF dual-hosted git repository.
villebro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new ae66f5f feat(explore): Drag and drop UX improvements (#13598)
ae66f5f is described below
commit ae66f5fa782155392c3b15f06ae5ba2c5cbee063
Author: Kamil Gabryjelski <ka...@gmail.com>
AuthorDate: Mon Mar 15 11:47:13 2021 +0100
feat(explore): Drag and drop UX improvements (#13598)
* Create a metric immediately when saved metric is dropped
* Display borders around control boxes when metric or column is dragged
* Fix imports
* Display ghost button
* Rename placeholder to ghostButton
---
.../src/explore/components/OptionControls.tsx | 2 +-
.../DndColumnSelectControl/DndColumnSelect.tsx | 1 -
.../DndColumnSelectControl/DndFilterSelect.tsx | 7 ++--
.../DndColumnSelectControl/DndMetricSelect.tsx | 46 ++++++++++------------
.../DndColumnSelectControl/DndSelectLabel.tsx | 15 +++----
.../controls/DndColumnSelectControl/types.ts | 7 ++--
6 files changed, 36 insertions(+), 42 deletions(-)
diff --git a/superset-frontend/src/explore/components/OptionControls.tsx b/superset-frontend/src/explore/components/OptionControls.tsx
index 0e8f777..6a3b66e 100644
--- a/superset-frontend/src/explore/components/OptionControls.tsx
+++ b/superset-frontend/src/explore/components/OptionControls.tsx
@@ -99,7 +99,7 @@ export const DndLabelsContainer = styled.div<{
}>`
padding: ${({ theme }) => theme.gridUnit}px;
border: ${({ canDrop, isOver, theme }) => {
- if (isOver && canDrop) {
+ if (canDrop) {
return `dashed 1px ${theme.colors.info.dark1}`;
}
if (isOver && !canDrop) {
diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.tsx
index 130f44b..67c8d61 100644
--- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.tsx
+++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.tsx
@@ -72,7 +72,6 @@ export const DndColumnSelect = (props: LabelProps) => {
return (
<DndSelectLabel<string | string[], ColumnMeta[]>
- values={values}
onDrop={onDrop}
canDrop={canDrop}
valuesRenderer={valuesRenderer}
diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.tsx
index e835f99..9e94d0a 100644
--- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.tsx
+++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.tsx
@@ -17,8 +17,8 @@
* under the License.
*/
import React, { useEffect, useMemo, useState } from 'react';
-import { logging, SupersetClient, t } from '@superset-ui/core';
-import { ColumnMeta, Metric } from '@superset-ui/chart-controls';
+import { logging, SupersetClient, t, Metric } from '@superset-ui/core';
+import { ColumnMeta } from '@superset-ui/chart-controls';
import { Tooltip } from 'src/common/components/Tooltip';
import { OPERATORS } from 'src/explore/constants';
import { OptionSortType } from 'src/explore/types';
@@ -300,7 +300,6 @@ export const DndFilterSelect = (props: DndFilterSelectProps) => {
return (
<>
<DndSelectLabel<OptionValueType, OptionValueType[]>
- values={values}
onDrop={(item: DatasourcePanelDndItem) => {
setDroppedItem(item.value);
togglePopover(true);
@@ -313,7 +312,7 @@ export const DndFilterSelect = (props: DndFilterSelectProps) => {
DndItemType.MetricOption,
DndItemType.AdhocMetricOption,
]}
- placeholderText={t('Drop columns or metrics')}
+ ghostButtonText={t('Drop columns or metrics')}
{...props}
/>
<AdhocFilterPopoverTrigger
diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndMetricSelect.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndMetricSelect.tsx
index 7fe1b4b..eb55faa 100644
--- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndMetricSelect.tsx
+++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndMetricSelect.tsx
@@ -241,41 +241,35 @@ export const DndMetricSelect = (props: any) => {
togglePopover(false);
};
- const { savedMetric, adhocMetric } = useMemo(() => {
- if (droppedItem?.type === 'column') {
- const itemValue = droppedItem?.value as ColumnMeta;
- return {
- savedMetric: {} as savedMetricType,
- adhocMetric: new AdhocMetric({
- column: { column_name: itemValue?.column_name },
- }),
- };
+ const handleDrop = (item: DatasourcePanelDndItem) => {
+ if (item.type === DndItemType.Metric) {
+ onNewMetric(item.value as Metric);
+ }
+ if (item.type === DndItemType.Column) {
+ setDroppedItem(item);
+ togglePopover(true);
}
- if (droppedItem?.type === 'metric') {
- const itemValue = droppedItem?.value as savedMetricType;
- return {
- savedMetric: itemValue,
- adhocMetric: new AdhocMetric({ isNew: true }),
- };
+ };
+
+ const adhocMetric = useMemo(() => {
+ if (droppedItem?.type === DndItemType.Column) {
+ const itemValue = droppedItem?.value as ColumnMeta;
+ return new AdhocMetric({
+ column: { column_name: itemValue?.column_name },
+ });
}
- return {
- savedMetric: {} as savedMetricType,
- adhocMetric: new AdhocMetric({ isNew: true }),
- };
+ return new AdhocMetric({ isNew: true });
}, [droppedItem?.type, droppedItem?.value]);
return (
<div className="metrics-select">
<DndSelectLabel<OptionValueType, OptionValueType[]>
- values={value}
- onDrop={(item: DatasourcePanelDndItem) => {
- setDroppedItem(item);
- togglePopover(true);
- }}
+ onDrop={handleDrop}
canDrop={canDrop}
valuesRenderer={valuesRenderer}
accept={[DndItemType.Column, DndItemType.Metric]}
- placeholderText={t('Drop columns or metrics')}
+ ghostButtonText={t('Drop columns or metrics')}
+ displayGhostButton={multi || value.length === 0}
{...props}
/>
<AdhocMetricPopoverTrigger
@@ -286,7 +280,7 @@ export const DndMetricSelect = (props: any) => {
props.savedMetrics,
props.value,
)}
- savedMetric={savedMetric}
+ savedMetric={{} as savedMetricType}
datasourceType={props.datasourceType}
isControlledComponent
visible={newMetricPopoverVisible}
diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndSelectLabel.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndSelectLabel.tsx
index f0ee950..c316d5c 100644
--- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndSelectLabel.tsx
+++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndSelectLabel.tsx
@@ -18,7 +18,6 @@
*/
import React from 'react';
import { useDrop } from 'react-dnd';
-import { isEmpty } from 'lodash';
import { t, useTheme } from '@superset-ui/core';
import ControlHeader from 'src/explore/components/ControlHeader';
import {
@@ -30,9 +29,10 @@ import { DatasourcePanelDndItem } from 'src/explore/components/DatasourcePanel/t
import Icon from 'src/components/Icon';
import { DndColumnSelectProps } from './types';
-export default function DndSelectLabel<T, O>(
- props: DndColumnSelectProps<T, O>,
-) {
+export default function DndSelectLabel<T, O>({
+ displayGhostButton = true,
+ ...props
+}: DndColumnSelectProps<T, O>) {
const theme = useTheme();
const [{ isOver, canDrop }, datasourcePanelDrop] = useDrop({
@@ -51,11 +51,11 @@ export default function DndSelectLabel<T, O>(
}),
});
- function renderPlaceHolder() {
+ function renderGhostButton() {
return (
<AddControlLabel cancelHover>
<Icon name="plus-small" color={theme.colors.grayscale.light1} />
- {t(props.placeholderText || 'Drop columns')}
+ {t(props.ghostButtonText || 'Drop columns')}
</AddControlLabel>
);
}
@@ -66,7 +66,8 @@ export default function DndSelectLabel<T, O>(
<ControlHeader {...props} />
</HeaderContainer>
<DndLabelsContainer canDrop={canDrop} isOver={isOver}>
- {isEmpty(props.values) ? renderPlaceHolder() : props.valuesRenderer()}
+ {props.valuesRenderer()}
+ {displayGhostButton && renderGhostButton()}
</DndLabelsContainer>
</div>
);
diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/types.ts b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/types.ts
index 68f830f..a34bda5 100644
--- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/types.ts
+++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/types.ts
@@ -17,7 +17,8 @@
* under the License.
*/
import { ReactNode } from 'react';
-import { ColumnMeta, Metric } from '@superset-ui/chart-controls';
+import { Metric } from '@superset-ui/core';
+import { ColumnMeta } from '@superset-ui/chart-controls';
import { DatasourcePanelDndItem } from '../../DatasourcePanel/types';
import { DndItemType } from '../../DndItemType';
@@ -45,12 +46,12 @@ export interface DndColumnSelectProps<
T = string[] | string,
O = string[] | string
> extends LabelProps<T> {
- values?: O;
onDrop: (item: DatasourcePanelDndItem) => void;
canDrop: (item: DatasourcePanelDndItem) => boolean;
valuesRenderer: () => ReactNode;
accept: DndItemType | DndItemType[];
- placeholderText?: string;
+ ghostButtonText?: string;
+ displayGhostButton?: boolean;
}
export type OptionValueType = Record<string, any>;