superset-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ccwilli...@apache.org
Subject [incubator-superset] branch chris--grid-root-and-spacer updated: [dashboard-builder] add info toast when dropResult overflows parent
Date Wed, 04 Apr 2018 22:50:23 GMT
This is an automated email from the ASF dual-hosted git repository.

ccwilliams pushed a commit to branch chris--grid-root-and-spacer
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/chris--grid-root-and-spacer by this push:
     new 0e6a175  [dashboard-builder] add info toast when dropResult overflows parent
0e6a175 is described below

commit 0e6a17540ad63f9157ac0dd2b36f5344aebe1883
Author: Chris Williams <chris.williams@airbnb.com>
AuthorDate: Wed Apr 4 15:49:59 2018 -0700

    [dashboard-builder] add info toast when dropResult overflows parent
---
 .../javascripts/components/EditableTitle.jsx       | 16 ++++++++----
 superset/assets/javascripts/dashboard/index.jsx    |  7 +-----
 .../dashboard/v2/actions/dashboardLayout.js        | 19 +++++++++-----
 .../dashboard/v2/actions/messageToasts.js          | 22 ++++++++--------
 .../dashboard/v2/components/dnd/handleDrop.js      |  2 +-
 .../v2/components/gridComponents/Header.jsx        |  2 +-
 .../dashboard/v2/reducers/messageToasts.js         |  4 +--
 .../dashboard/v2/stylesheets/toast.less            | 14 +++++------
 .../dashboard/v2/util/dropOverflowsParent.js       | 24 ++++++++++++++++++
 superset/assets/stylesheets/superset.less          | 29 +++++++++++++---------
 10 files changed, 88 insertions(+), 51 deletions(-)

diff --git a/superset/assets/javascripts/components/EditableTitle.jsx b/superset/assets/javascripts/components/EditableTitle.jsx
index a7e3f17..45fea1d 100644
--- a/superset/assets/javascripts/components/EditableTitle.jsx
+++ b/superset/assets/javascripts/components/EditableTitle.jsx
@@ -116,7 +116,7 @@ class EditableTitle extends React.PureComponent {
   }
 
   render() {
-    let input = (
+    let content = (
       <input
         required
         type={this.state.isEditing ? 'text' : 'button'}
@@ -129,19 +129,25 @@ class EditableTitle extends React.PureComponent {
       />
     );
     if (this.props.showTooltip) {
-      input = (
+      content = (
         <TooltipWrapper
           label="title"
           tooltip={this.props.canEdit ? t('click to edit title') :
               this.props.noPermitTooltip || t('You don\'t have the rights to alter this title.')}
         >
-          {input}
+          {content}
         </TooltipWrapper>
       );
     }
     return (
-      <span className={cx('editable-title', this.props.canEdit && 'editable-title--editable')}>
-        {input}
+      <span
+        className={cx(
+          'editable-title',
+          this.props.canEdit && 'editable-title--editable',
+          this.state.isEditing && 'editable-title--editing',
+        )}
+      >
+        {content}
       </span>
     );
   }
diff --git a/superset/assets/javascripts/dashboard/index.jsx b/superset/assets/javascripts/dashboard/index.jsx
index 6f6d177..1aadc58 100644
--- a/superset/assets/javascripts/dashboard/index.jsx
+++ b/superset/assets/javascripts/dashboard/index.jsx
@@ -27,12 +27,7 @@ const initState = {
     future: [],
   },
   editMode: true,
-  messageToasts: [
-    { text: 'Info!', id: '157234', toastType: 'INFO_TOAST' },
-    { text: 'Success!', id: '1237545745', toastType: 'SUCCESS_TOAST' },
-    { text: 'Warning!', id: '154623', toastType: 'WARNING_TOAST' },
-    { text: 'Danger!', id: '9128346', toastType: 'DANGER_TOAST' },
-  ],
+  messageToasts: [],
 };
 
 const store = createStore(
diff --git a/superset/assets/javascripts/dashboard/v2/actions/dashboardLayout.js b/superset/assets/javascripts/dashboard/v2/actions/dashboardLayout.js
index 2a503c3..b6d41c4 100644
--- a/superset/assets/javascripts/dashboard/v2/actions/dashboardLayout.js
+++ b/superset/assets/javascripts/dashboard/v2/actions/dashboardLayout.js
@@ -1,10 +1,8 @@
+import { addInfoToast } from './messageToasts';
+import { CHART_TYPE, MARKDOWN_TYPE, TABS_TYPE } from '../util/componentTypes';
 import { DASHBOARD_ROOT_ID, NEW_COMPONENTS_SOURCE_ID } from '../util/constants';
+import dropOverflowsParent from '../util/dropOverflowsParent';
 import findParentId from '../util/findParentId';
-import {
-  CHART_TYPE,
-  MARKDOWN_TYPE,
-  TABS_TYPE,
-} from '../util/componentTypes';
 
 // Component CRUD -------------------------------------------------------------
 export const UPDATE_COMPONENTS = 'UPDATE_COMPONENTS';
@@ -114,6 +112,15 @@ export function moveComponent(dropResult) {
 export const HANDLE_COMPONENT_DROP = 'HANDLE_COMPONENT_DROP';
 export function handleComponentDrop(dropResult) {
   return (dispatch, getState) => {
+    const overflowsParent = dropOverflowsParent(dropResult, getState().dashboardLayout.present);
+
+    if (overflowsParent) {
+      return dispatch(addInfoToast(
+        `Parent does not have enough space for this component.
+         Try decreasing its width or add it to a new row.`,
+      ));
+    }
+
     const { source, destination } = dropResult;
     const droppedOnRoot = destination && destination.id === DASHBOARD_ROOT_ID;
     const isNewComponent = source.id === NEW_COMPONENTS_SOURCE_ID;
@@ -133,7 +140,7 @@ export function handleComponentDrop(dropResult) {
       dispatch(moveComponent(dropResult));
     }
 
-    // if we moved a tab and the parent tabs no longer has children, delete it.
+    // if we moved a Tab and the parent Tabs no longer has children, delete it.
     if (!isNewComponent) {
       const { dashboardLayout: undoableLayout } = getState();
       const { present: layout } = undoableLayout;
diff --git a/superset/assets/javascripts/dashboard/v2/actions/messageToasts.js b/superset/assets/javascripts/dashboard/v2/actions/messageToasts.js
index c49c94a..af10ead 100644
--- a/superset/assets/javascripts/dashboard/v2/actions/messageToasts.js
+++ b/superset/assets/javascripts/dashboard/v2/actions/messageToasts.js
@@ -6,6 +6,7 @@ function getToastUuid(type) {
 
 export const ADD_TOAST = 'ADD_TOAST';
 export function addToast({ toastType, text }) {
+  debugger;
   return {
     type: ADD_TOAST,
     payload: {
@@ -16,6 +17,17 @@ export function addToast({ toastType, text }) {
   };
 }
 
+export const REMOVE_TOAST = 'REMOVE_TOAST';
+export function removeToast(id) {
+  return {
+    type: REMOVE_TOAST,
+    payload: {
+      id,
+    },
+  };
+}
+
+// Different types of toasts
 export const ADD_INFO_TOAST = 'ADD_INFO_TOAST';
 export function addInfoToast(text) {
   return dispatch => dispatch(addToast({ text, toastType: INFO_TOAST }));
@@ -35,13 +47,3 @@ export const ADD_DANGER_TOAST = 'ADD_DANGER_TOAST';
 export function addDangerToast(text) {
   return dispatch => dispatch(addToast({ text, toastType: DANGER_TOAST }));
 }
-
-export const REMOVE_TOAST = 'REMOVE_TOAST';
-export function removeToast(id) {
-  return {
-    type: REMOVE_TOAST,
-    payload: {
-      id,
-    },
-  };
-}
diff --git a/superset/assets/javascripts/dashboard/v2/components/dnd/handleDrop.js b/superset/assets/javascripts/dashboard/v2/components/dnd/handleDrop.js
index 2207ca6..f27b604 100644
--- a/superset/assets/javascripts/dashboard/v2/components/dnd/handleDrop.js
+++ b/superset/assets/javascripts/dashboard/v2/components/dnd/handleDrop.js
@@ -2,7 +2,7 @@ import getDropPosition, { DROP_TOP, DROP_RIGHT, DROP_BOTTOM, DROP_LEFT } from
'.
 
 export default function handleDrop(props, monitor, Component) {
   // this may happen due to throttling
-  if (!Component.mounted || !Component.props.onDrop) return undefined;
+  if (!Component.mounted) return undefined;
 
   Component.setState(() => ({ dropIndicator: null }));
   const dropPosition = getDropPosition(monitor, Component);
diff --git a/superset/assets/javascripts/dashboard/v2/components/gridComponents/Header.jsx
b/superset/assets/javascripts/dashboard/v2/components/gridComponents/Header.jsx
index 594cf6b..97945a9 100644
--- a/superset/assets/javascripts/dashboard/v2/components/gridComponents/Header.jsx
+++ b/superset/assets/javascripts/dashboard/v2/components/gridComponents/Header.jsx
@@ -138,7 +138,7 @@ class Header extends React.PureComponent {
               >
                 <EditableTitle
                   title={component.meta.text}
-                  canEdit={editMode && isFocused}
+                  canEdit={editMode}
                   onSaveTitle={this.handleChangeText}
                   showTooltip={false}
                 />
diff --git a/superset/assets/javascripts/dashboard/v2/reducers/messageToasts.js b/superset/assets/javascripts/dashboard/v2/reducers/messageToasts.js
index 3b40da4..1f5728a 100644
--- a/superset/assets/javascripts/dashboard/v2/reducers/messageToasts.js
+++ b/superset/assets/javascripts/dashboard/v2/reducers/messageToasts.js
@@ -3,8 +3,8 @@ import { ADD_TOAST, REMOVE_TOAST } from '../actions/messageToasts';
 export default function messageToastsReducer(toasts = [], action) {
   switch (action.type) {
     case ADD_TOAST: {
-      const { payload: { id, type, text } } = action;
-      return [...toasts, { id, type, text }];
+      const { payload: toast } = action;
+      return [toast, ...toasts];
     }
 
     case REMOVE_TOAST: {
diff --git a/superset/assets/javascripts/dashboard/v2/stylesheets/toast.less b/superset/assets/javascripts/dashboard/v2/stylesheets/toast.less
index b324137..a508637 100644
--- a/superset/assets/javascripts/dashboard/v2/stylesheets/toast.less
+++ b/superset/assets/javascripts/dashboard/v2/stylesheets/toast.less
@@ -8,18 +8,16 @@
 }
 
 .toast {
-  will-change: transform, opacity;
-  transform: translateY(-100%);
-  transition: transform .3s, opacity .3s;
+  background: white;
+  color: @almost-black;
   opacity: 0;
   position: relative;
+  white-space: pre-line;
   box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.15);
-}
-
-.toast {
   border-radius: 2px;
-  background: white;
-  color: @almost-black;
+  will-change: transform, opacity;
+  transform: translateY(-100%);
+  transition: transform .3s, opacity .3s;
 }
 
 .toast > button {
diff --git a/superset/assets/javascripts/dashboard/v2/util/dropOverflowsParent.js b/superset/assets/javascripts/dashboard/v2/util/dropOverflowsParent.js
new file mode 100644
index 0000000..0fd0c4e
--- /dev/null
+++ b/superset/assets/javascripts/dashboard/v2/util/dropOverflowsParent.js
@@ -0,0 +1,24 @@
+import { COLUMN_TYPE } from '../util/componentTypes';
+import { GRID_COLUMN_COUNT, NEW_COMPONENTS_SOURCE_ID } from './constants';
+import findParentId from './findParentId';
+import getChildWidth from './getChildWidth';
+import newComponentFactory from './newComponentFactory';
+
+export default function doesChildOverflowParent(dropResult, components) {
+  const { source, destination, dragging } = dropResult;
+  const isNewComponent = source.id === NEW_COMPONENTS_SOURCE_ID;
+
+  const grandparentId = findParentId({ childId: destination.id, components });
+
+  const child = isNewComponent ? newComponentFactory(dragging.type) : components[dragging.id]
|| {};
+  const parent = components[destination.id] || {};
+  const grandparent = components[grandparentId] || {};
+
+  const grandparentWidth = (grandparent.meta && grandparent.meta.width) || GRID_COLUMN_COUNT;
+  const parentWidth = (parent.meta && parent.meta.width) || grandparentWidth;
+  const parentChildWidth = parent.type === COLUMN_TYPE
+    ? 0 : getChildWidth({ id: destination.id, components });
+  const childWidth = (child.meta && child.meta.width) || 0;
+
+  return parentWidth - parentChildWidth < childWidth;
+}
diff --git a/superset/assets/stylesheets/superset.less b/superset/assets/stylesheets/superset.less
index a7a69b1..84089d0 100644
--- a/superset/assets/stylesheets/superset.less
+++ b/superset/assets/stylesheets/superset.less
@@ -233,32 +233,37 @@ table.table-no-hover tr:hover {
   border: none;
   box-shadow: none;
   padding: 0;
+  cursor: initial;
 }
 
 .editable-title input[type="button"] {
-    border-color: transparent;
-    background: transparent;
-    font-size: inherit;
-    line-height: inherit;
-    white-space: normal;
-    text-align: left;
+  border-color: transparent;
+  background: transparent;
+  font-size: inherit;
+  line-height: inherit;
+  white-space: normal;
+  text-align: left;
 }
 
-.editable-title--editable input[type="button"]:hover {
-    cursor: text;
+.editable-title.editable-title--editable {
+  cursor: pointer;
+}
+
+.editable-title.editable-title--editing {
+  cursor: text;
 }
 
 .m-r-5 {
-    margin-right: 5px;
+  margin-right: 5px;
 }
 .m-r-3 {
-    margin-right: 3px;
+  margin-right: 3px;
 }
 .m-t-5 {
-    margin-top: 5px;
+  margin-top: 5px;
 }
 .m-t-10 {
-    margin-top: 10px;
+  margin-top: 10px;
 }
 .m-b-10 {
     margin-bottom: 10px;

-- 
To stop receiving notification emails like this one, please contact
ccwilliams@apache.org.

Mime
View raw message