You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by kg...@apache.org on 2022/04/13 12:23:05 UTC

[superset] branch master updated: fix(dashboard): Fix BigNumber causing dashboard to crash when overflowing (#19688)

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

kgabryje 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 ee85466f2e fix(dashboard): Fix BigNumber causing dashboard to crash when overflowing (#19688)
ee85466f2e is described below

commit ee85466f2ed45d3f51a7609ef4e30cf087c033e4
Author: Kamil Gabryjelski <ka...@gmail.com>
AuthorDate: Wed Apr 13 14:22:46 2022 +0200

    fix(dashboard): Fix BigNumber causing dashboard to crash when overflowing (#19688)
    
    * fix(dashboard): fix(plugin-chart-echarts): Fix BigNumber causing dashboard to crash when overflowing
    
    * Add tooltips for truncated titles
    
    * Fix type
---
 .../src/components/EditableTitle/index.tsx         |  9 ++--
 .../components/SliceHeader/SliceHeader.test.tsx    |  2 +
 .../src/dashboard/components/SliceHeader/index.tsx | 49 +++++++++++++++-------
 .../dashboard/components/gridComponents/Chart.jsx  | 17 ++++++--
 .../src/dashboard/stylesheets/dashboard.less       |  8 ++++
 5 files changed, 63 insertions(+), 22 deletions(-)

diff --git a/superset-frontend/src/components/EditableTitle/index.tsx b/superset-frontend/src/components/EditableTitle/index.tsx
index 6839b45c7d..ddd8587556 100644
--- a/superset-frontend/src/components/EditableTitle/index.tsx
+++ b/superset-frontend/src/components/EditableTitle/index.tsx
@@ -57,6 +57,8 @@ export default function EditableTitle({
   placeholder = '',
   certifiedBy,
   certificationDetails,
+  // rest is related to title tooltip
+  ...rest
 }: EditableTitleProps) {
   const [isEditing, setIsEditing] = useState(editing);
   const [currentTitle, setCurrentTitle] = useState(title);
@@ -214,11 +216,7 @@ export default function EditableTitle({
   }
   if (!canEdit) {
     // don't actually want an input in this case
-    titleComponent = (
-      <span data-test="editable-title-input" title={value}>
-        {value}
-      </span>
-    );
+    titleComponent = <span data-test="editable-title-input">{value}</span>;
   }
   return (
     <span
@@ -230,6 +228,7 @@ export default function EditableTitle({
         isEditing && 'editable-title--editing',
       )}
       style={style}
+      {...rest}
     >
       {certifiedBy && (
         <>
diff --git a/superset-frontend/src/dashboard/components/SliceHeader/SliceHeader.test.tsx b/superset-frontend/src/dashboard/components/SliceHeader/SliceHeader.test.tsx
index b1a2efc7b8..fd5892f427 100644
--- a/superset-frontend/src/dashboard/components/SliceHeader/SliceHeader.test.tsx
+++ b/superset-frontend/src/dashboard/components/SliceHeader/SliceHeader.test.tsx
@@ -157,6 +157,8 @@ const createProps = () => ({
   exportCSV: jest.fn(),
   onExploreChart: jest.fn(),
   formData: { slice_id: 1, datasource: '58__table' },
+  width: 100,
+  height: 100,
 });
 
 test('Should render', () => {
diff --git a/superset-frontend/src/dashboard/components/SliceHeader/index.tsx b/superset-frontend/src/dashboard/components/SliceHeader/index.tsx
index 88e9a4c69f..44ddf7b5ad 100644
--- a/superset-frontend/src/dashboard/components/SliceHeader/index.tsx
+++ b/superset-frontend/src/dashboard/components/SliceHeader/index.tsx
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import React, { FC, useMemo } from 'react';
+import React, { FC, useEffect, useMemo, useRef, useState } from 'react';
 import { styled, t } from '@superset-ui/core';
 import { useUiConfig } from 'src/components/UiConfigContext';
 import { Tooltip } from 'src/components/Tooltip';
@@ -41,6 +41,8 @@ type SliceHeaderProps = SliceHeaderControlsProps & {
   filters: object;
   handleToggleFullSize: () => void;
   formData: object;
+  width: number;
+  height: number;
 };
 
 const annotationsLoading = t('Annotation layers are still loading.');
@@ -82,9 +84,13 @@ const SliceHeader: FC<SliceHeaderProps> = ({
   isFullSize,
   chartStatus,
   formData,
+  width,
+  height,
 }) => {
   const dispatch = useDispatch();
   const uiConfig = useUiConfig();
+  const [headerTooltip, setHeaderTooltip] = useState<string | null>(null);
+  const headerRef = useRef<HTMLDivElement>(null);
   // TODO: change to indicator field after it will be implemented
   const crossFilterValue = useSelector<RootState, any>(
     state => state.dataMask[slice?.slice_id]?.filterState?.value,
@@ -98,21 +104,36 @@ const SliceHeader: FC<SliceHeaderProps> = ({
     [crossFilterValue],
   );
 
+  useEffect(() => {
+    const headerElement = headerRef.current;
+    if (
+      headerElement &&
+      (headerElement.scrollWidth > headerElement.offsetWidth ||
+        headerElement.scrollHeight > headerElement.offsetHeight)
+    ) {
+      setHeaderTooltip(sliceName ?? null);
+    } else {
+      setHeaderTooltip(null);
+    }
+  }, [sliceName, width, height]);
+
   return (
     <div className="chart-header" data-test="slice-header" ref={innerRef}>
-      <div className="header-title">
-        <EditableTitle
-          title={
-            sliceName ||
-            (editMode
-              ? '---' // this makes an empty title clickable
-              : '')
-          }
-          canEdit={editMode}
-          emptyText=""
-          onSaveTitle={updateSliceName}
-          showTooltip={false}
-        />
+      <div className="header-title" ref={headerRef}>
+        <Tooltip title={headerTooltip}>
+          <EditableTitle
+            title={
+              sliceName ||
+              (editMode
+                ? '---' // this makes an empty title clickable
+                : '')
+            }
+            canEdit={editMode}
+            emptyText=""
+            onSaveTitle={updateSliceName}
+            showTooltip={false}
+          />
+        </Tooltip>
         {!!Object.values(annotationQuery).length && (
           <Tooltip
             id="annotations-loading-tooltip"
diff --git a/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx b/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx
index 134e026d7a..b212af44e5 100644
--- a/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx
+++ b/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx
@@ -113,6 +113,12 @@ const ChartOverlay = styled.div`
   }
 `;
 
+const SliceContainer = styled.div`
+  display: flex;
+  flex-direction: column;
+  max-height: 100%;
+`;
+
 export default class Chart extends React.Component {
   constructor(props) {
     super(props);
@@ -210,7 +216,10 @@ export default class Chart extends React.Component {
 
   getChartHeight() {
     const headerHeight = this.getHeaderHeight();
-    return this.state.height - headerHeight - this.state.descriptionHeight;
+    return Math.max(
+      this.state.height - headerHeight - this.state.descriptionHeight,
+      20,
+    );
   }
 
   getHeaderHeight() {
@@ -370,7 +379,7 @@ export default class Chart extends React.Component {
         })
       : {};
     return (
-      <div
+      <SliceContainer
         className="chart-slice"
         data-test="chart-grid-component"
         data-test-chart-id={id}
@@ -407,6 +416,8 @@ export default class Chart extends React.Component {
           isFullSize={isFullSize}
           chartStatus={chart.chartStatus}
           formData={formData}
+          width={width}
+          height={this.getHeaderHeight()}
         />
 
         {/*
@@ -468,7 +479,7 @@ export default class Chart extends React.Component {
             datasetsStatus={datasetsStatus}
           />
         </div>
-      </div>
+      </SliceContainer>
     );
   }
 }
diff --git a/superset-frontend/src/dashboard/stylesheets/dashboard.less b/superset-frontend/src/dashboard/stylesheets/dashboard.less
index a3409c4d48..b9b2b0aab9 100644
--- a/superset-frontend/src/dashboard/stylesheets/dashboard.less
+++ b/superset-frontend/src/dashboard/stylesheets/dashboard.less
@@ -63,12 +63,20 @@ body {
   display: flex;
   max-width: 100%;
   align-items: flex-start;
+  min-height: 0;
 
   & > .header-title {
     overflow: hidden;
     text-overflow: ellipsis;
     max-width: 100%;
     flex-grow: 1;
+    display: -webkit-box;
+    -webkit-line-clamp: 2;
+    -webkit-box-orient: vertical;
+
+    & > span.ant-tooltip-open {
+      display: inline;
+    }
   }
 
   & > .header-controls {