Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drill By Modal window disappear when chart is not in view in embedded mode #29973

Open
3 tasks done
changwuf31 opened this issue Aug 20, 2024 · 4 comments
Open
3 tasks done

Comments

@changwuf31
Copy link

Bug description

When we embed a long dashboard with lots of chart,
and when we go to the bottom-most chart, eg: table chart,
and we click drill by, and choose a dimension,
the drill by modal is shown at the top of the iframe, which is not out of sight.
When we move the mouse to view the modal contents, and the source chart is out of view,
then the drill by modal disappear by itself.
The Chrome Inspector console doesn't have anything useful.

When we click the view query, it's not an issue, even though the modal position is at the top, it doesn't auto close / disappear, when the source chart is out of view.

How to reproduce the bug

  1. Create a dashboard with lots of chart
  2. Put a table chart at the bottom of the dashboard
  3. Embed the dashboard inside an iframe
  4. Open the page containing the iframe
  5. Wait for the page and the charts to load
  6. Scroll to the bottom of the page
  7. Click Drill By, and choose a dimension
  8. The Drill By Modal is far at the top of the page
  9. Scroll up to view the Drill By Modal
  10. Ensure that the source chart is out of sight
  11. Voila, the Drill By Modal disappear.

Screenshots/recordings

No response

Superset version

4.0.2

Python version

3.10

Node version

18 or greater

Browser

Chrome

Additional context

No response

Checklist

  • I have searched Superset docs and Slack and didn't find a solution to my problem.
  • I have searched the GitHub issue tracker and didn't find a similar bug report.
  • I have checked Superset's logs for errors and if I found a relevant Python stacktrace, I included it here as text in the "additional context" section.
@changwuf31
Copy link
Author

To add more information, this works fine on superset without embedding it in an iframe

Copy link

dosubot bot commented Aug 20, 2024

Hey @changwuf31! I'm here to help you with any bugs, questions, or contributions you might have. Let's tackle this together!

To prevent the "Drill By" modal from disappearing when the source chart is out of view in an embedded Superset dashboard, you need to ensure that the maskClosable property of the Modal component is set to false. This ensures that the modal will not close when clicking outside of it. Here is the relevant code snippet:

<Modal
  show={showModal}
  onHide={onHideModal ?? (() => null)}
  css={css`
    .ant-modal-body {
      display: flex;
      flex-direction: column;
    }
  `}
  title={t('Drill to detail: %s', chartName)}
  footer={
    <ModalFooter exploreChart={exploreChart} canExplore={canExplore} />
  }
  responsive
  resizable
  resizableConfig={{
    minHeight: theme.gridUnit * 128,
    minWidth: theme.gridUnit * 128,
    defaultSize: {
      width: 'auto',
      height: '75vh',
    },
  }}
  draggable
  destroyOnClose
  maskClosable={false}
>
  <DrillDetailPane formData={formData} initialFilters={initialFilters} />
</Modal>

Additionally, ensure that the modal remains visible and functional by handling its visibility and interactions properly. For example, in the Cypress test for the "Drill By" modal, the modal's visibility and interactions are verified to ensure it remains functional even when the source chart is out of view:

cy.get('@drillByModal')
  .find('.draggable-trigger')
  .should('contain', 'Drill by: Table');

cy.get('@drillByModal')
  .find('[data-test="metadata-bar"]')
  .should('be.visible');

cy.get('@drillByModal')
  .find('.ant-breadcrumb')
  .should('be.visible')
  .and('contain', 'gender (boy)')
  .and('contain', '/')
  .and('contain', 'state');

cy.get('@drillByModal')
  .find('[data-test="drill-by-chart"]')
  .should('be.visible')
  .and('contain', 'state')
  .and('contain', 'sum__num');

This configuration and testing approach should prevent the "Drill By" modal from disappearing when the source chart is out of view [1][2][3].

To continue talking to Dosu, mention @dosu.

@changwuf31
Copy link
Author

@dosu maskClosable is already {false}
and your cypress test doesn't involve any scrolling to make the chart out of sight,
it also do not check the chart in embedded dashboard.

Copy link

dosubot bot commented Aug 20, 2024

To prevent the "Drill By" modal from disappearing when the source chart is out of view in an embedded Superset dashboard, you can ensure that the modal remains visible by modifying the Cypress test to handle scrolling and visibility checks. Since maskClosable is already set to false, the modal should not close when clicking outside of it. However, you need to ensure that the modal remains in view even if the source chart is scrolled out of view.

Here is an example of how you can modify the Cypress test to handle this scenario:

import { waitForChartLoad } from 'cypress/utils';
import { SUPPORTED_CHARTS_DASHBOARD } from 'cypress/utils/urls';
import {
  openTopLevelTab,
  SUPPORTED_TIER1_CHARTS,
} from './utils';

const ensureModalInView = () => {
  cy.get('@drillByModal').then($modal => {
    if ($modal.is(':hidden')) {
      cy.get('@drillByModal').scrollIntoView();
    }
  });
};

describe('Drill by modal', () => {
  beforeEach(() => {
    closeModal();
  });
  before(() => {
    cy.visit(SUPPORTED_CHARTS_DASHBOARD);
  });

  describe('Modal actions   Table', () => {
    before(() => {
      closeModal();
      openTopLevelTab('Tier 1');
      SUPPORTED_TIER1_CHARTS.forEach(waitForChartLoad);
    });

    it('opens the modal from the context menu', () => {
      openTableContextMenu('boy');
      drillBy('state').then(intercepted => {
        verifyExpectedFormData(intercepted, {
          groupby: ['state'],
          adhoc_filters: [
            {
              clause: 'WHERE',
              comparator: 'boy',
              expressionType: 'SIMPLE',
              operator: '==',
              operatorId: 'EQUALS',
              subject: 'gender',
            },
          ],
        });
      });

      cy.getBySel('"Drill by: Table-modal"').as('drillByModal');

      ensureModalInView();

      cy.get('@drillByModal')
        .find('.draggable-trigger')
        .should('contain', 'Drill by: Table');

      cy.get('@drillByModal')
        .find('[data-test="metadata-bar"]')
        .should('be.visible');

      cy.get('@drillByModal')
        .find('.ant-breadcrumb')
        .should('be.visible')
        .and('contain', 'gender (boy)')
        .and('contain', '/')
        .and('contain', 'state');

      cy.get('@drillByModal')
        .find('[data-test="drill-by-chart"]')
        .should('be.visible')
        .and('contain', 'state')
        .and('contain', 'sum__num');

      // further drilling
      openTableContextMenu('CA', '[data-test="drill-by-chart"]');
      drillBy('name').then(intercepted => {
        verifyExpectedFormData(intercepted, {
          groupby: ['name'],
          adhoc_filters: [
            {
              clause: 'WHERE',
              comparator: 'boy',
              expressionType: 'SIMPLE',
              operator: '==',
              operatorId: 'EQUALS',
              subject: 'gender',
            },
            {
              clause: 'WHERE',
              comparator: 'CA',
              expressionType: 'SIMPLE',
              operator: '==',
              operatorId: 'EQUALS',
              subject: 'state',
            },
          ],
        });
      });

      ensureModalInView();

      cy.get('@drillByModal')
        .find('[data-test="drill-by-chart"]')
        .should('be.visible')
        .and('not.contain', 'state')
        .and('contain', 'name')
        .and('contain', 'sum__num');

      // undo - back to drill by state
      interceptV1ChartData('drillByUndo');
      interceptFormDataKey();
      cy.get('@drillByModal')
        .find('.ant-breadcrumb')
        .should('be.visible')
        .and('contain', 'gender (boy)')
        .and('contain', '/')
        .and('contain', 'state (CA)')
        .and('contain', 'name')
        .contains('state (CA)')
        .click();
      cy.wait('@drillByUndo').then(intercepted => {
        verifyExpectedFormData(intercepted, {
          groupby: ['state'],
          adhoc_filters: [
            {
              clause: 'WHERE',
              comparator: 'boy',
              expressionType: 'SIMPLE',
              operator: '==',
              operatorId: 'EQUALS',
              subject: 'gender',
            },
          ],
        });
      });

      ensureModalInView();

      cy.get('@drillByModal')
        .find('[data-test="drill-by-chart"]')
        .should('be.visible')
        .and('not.contain', 'name')
        .and('contain', 'state')
        .and('contain', 'sum__num');

      cy.get('@drillByModal')
        .find('.ant-breadcrumb')
        .should('be.visible')
        .and('contain', 'gender (boy)')
        .and('contain', '/')
        .and('not.contain', 'state (CA)')
        .and('not.contain', 'name')
        .and('contain', 'state');

      cy.get('@drillByModal')
        .find('[data-test="drill-by-display-toggle"]')
        .contains('Table')
        .click();

      cy.getBySel('drill-by-chart').should('not.exist');

      cy.get('@drillByModal')
        .find('[data-test="drill-by-results-table"]')
        .should('be.visible');
      cy.wait('@formDataKey').then(intercept => {
        cy.get('@drillByModal')
          .contains('Edit chart')
          .should('have.attr', 'href')
          .and(
            'contain',
            `/explore/?form_data_key=${intercept.response?.body?.key}`,
          );
      });
    });
  });
});

This code ensures that the modal is scrolled into view if it is hidden, thus preventing it from disappearing when the source chart is out of view [1][2].

To continue talking to Dosu, mention @dosu.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant