apache / superset

Apache Superset is a Data Visualization and Data Exploration Platform
https://superset.apache.org/
Apache License 2.0
62.8k stars 13.87k forks source link

Embedded dashboard charts "Applied Filter" not visible #30374

Open shubhshah01 opened 1 month ago

shubhshah01 commented 1 month ago

Bug description

So for embedded dashboards, If we apply a filter there is no indication of Applied Filter on each chart unless the hideChartControls is set to false in dashboardUiConfig parameter passed to superset embedding sdk.\ But i don't want to show chart controls, I just want to display what filters are applied on the charts. Is there a way to do it ?

image

How to reproduce the bug

  1. Embed a dashboard with below dashboardUiConfig
    {
        hideTab: true,
        hideTitle: true,
        hideChartControls: true,
        filters: {
          visible: false,
          expanded: false,
       }
    }
  2. Go to dashboard.
  3. Apply some filter
  4. The charts in the scope of that filter will have no indication of what filters are applied.

Screenshots/recordings

No response

Superset version

4.0.2

Python version

I don't know

Node version

I don't know

Browser

Chrome

Additional context

No response

Checklist

dosubot[bot] commented 1 month ago

Hey, @shubhshah01! I'm here to help you out with this dashboard issue. Let's work together to solve this!

There is a way to display the applied filters on embedded dashboard charts in Superset without showing the chart controls. The FiltersBadge component is designed to show the applied filters. This component can be used to display the applied filters without showing the chart controls.

Here is the relevant part of the code that handles the display of applied filters:

export const FiltersBadge = ({ chartId }: FiltersBadgeProps) => {
  // ... other code ...

  const indicators = useMemo(
    () =>
      uniqWith(
        sortByStatus([...dashboardIndicators, ...nativeIndicators]),
        (ind1, ind2) =>
          ind1.column === ind2.column &&
          ind1.name === ind2.name &&
          (ind1.status !== IndicatorStatus.Applied ||
            ind2.status !== IndicatorStatus.Applied),
      ),
    [dashboardIndicators, nativeIndicators],
  );

  const appliedCrossFilterIndicators = useMemo(
    () =>
      indicators.filter(
        indicator => indicator.status === IndicatorStatus.CrossFilterApplied,
      ),
    [indicators],
  );
  const appliedIndicators = useMemo(
    () =>
      indicators.filter(
        indicator => indicator.status === IndicatorStatus.Applied,
      ),
    [indicators],
  );
  const filterCount =
    appliedIndicators.length + appliedCrossFilterIndicators.length;

  if (!appliedCrossFilterIndicators.length && !appliedIndicators.length) {
    return null;
  }

  return (
    <DetailsPanelPopover
      appliedCrossFilterIndicators={appliedCrossFilterIndicators}
      appliedIndicators={appliedIndicators}
      onHighlightFilterSource={onHighlightFilterSource}
      setPopoverVisible={setPopoverVisible}
      popoverVisible={popoverVisible}
      popoverContentRef={popoverContentRef}
      popoverTriggerRef={popoverTriggerRef}
    >
      <StyledFilterCount
        aria-label={t('Applied filters (%s)', filterCount)}
        aria-haspopup="true"
        role="button"
        ref={popoverTriggerRef}
        className={cx(
          'filter-counts',
          !!appliedCrossFilterIndicators.length && 'has-cross-filters',
        )}
        tabIndex={0}
        onKeyDown={handleKeyDown}
      >
        <Icons.Filter iconSize="m" />
        <StyledBadge
          data-test="applied-filter-count"
          className="applied-count"
          count={filterCount}
          showZero
        />
      </StyledFilterCount>
    </DetailsPanelPopover>
  );
};

Additionally, in the SliceHeader component, you can see how the FiltersBadge is integrated to display the applied filters:

const SliceHeader: FC<SliceHeaderProps> = ({
  // ... other props ...
  slice,
  uiConfig,
  // ... other props ...
}) => {
  // ... other code ...

  return (
    <ChartHeaderStyles data-test="slice-header" ref={innerRef}>
      <div className="header-title" ref={headerRef}>
        {/* ... other code ... */}
      </div>
      <div className="header-controls">
        {!editMode && (
          <>
            {/* ... other code ... */}
            {!uiConfig.hideChartControls && (
              <FiltersBadge chartId={slice.slice_id} />
            )}
            {/* ... other code ... */}
          </>
        )}
      </div>
    </ChartHeaderStyles>
  );
};

This component can be embedded in your dashboard to show the applied filters without displaying the chart controls [1][2].

To continue talking to Dosu, mention @dosu.

shubhshah01 commented 1 month ago

@dosu I am using @superset-ui/embedded-sdk pkg to embed dashboards. Below is the code

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Superset Embedding POC</title>
    <style>
        iframe {
            width: 100%;
            height: 100%;
            border: none;
        }
    </style>
    <script src="https://unpkg.com/@superset-ui/embedded-sdk"></script>
</head>
<body>
<div style="width: 100%; height: 800px;" id="my-superset-container"></div>
<script>
    const dashboardConfig = {
        hideTab: true,
        hideTitle: true,
        hideChartControls: true,
        filters: {
          visible: false,
          expanded: false,
       }
    };
    supersetEmbeddedSdk.embedDashboard({
        id: 'embedded-id',
        supersetDomain: 'domain',
        mountPoint: document.getElementById("my-superset-container"),
        fetchGuestToken: () => 'guest-token',
        dashboardUiConfig: dashboardConfig,
    });
</script>
</body>
</html>
dosubot[bot] commented 1 month ago

To display the applied filters on embedded dashboard charts using the @superset-ui/embedded-sdk package without showing the chart controls, you can adjust the dashboardUiConfig parameter. Specifically, set filters.visible to true while keeping hideChartControls set to true.

Here is the updated code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Superset Embedding POC</title>
    <style>
        iframe {
            width: 100%;
            height: 100%;
            border: none;
        }
    </style>
    <script src="https://unpkg.com/@superset-ui/embedded-sdk"></script>
</head>
<body>
<div style="width: 100%; height: 800px;" id="my-superset-container"></div>
<script>
    const dashboardConfig = {
        hideTab: true,
        hideTitle: true,
        hideChartControls: true,
        filters: {
          visible: true,  // Set this to true to display applied filters
          expanded: false,
       }
    };
    supersetEmbeddedSdk.embedDashboard({
        id: 'embedded-id',
        supersetDomain: 'domain',
        mountPoint: document.getElementById("my-superset-container"),
        fetchGuestToken: () => 'guest-token',
        dashboardUiConfig: dashboardConfig,
    });
</script>
</body>
</html>

This configuration ensures that the applied filters are visible on the embedded dashboard charts without showing the chart controls [1][2].

To continue talking to Dosu, mention @dosu.

shubhshah01 commented 1 month ago

@dosu Above configuration does not make applied filters visible on charts. Still they seem to be hidden

dosubot[bot] commented 1 month ago

To make the applied filters visible on charts using the @superset-ui/embedded-sdk package without showing the chart controls, you need to ensure that the FiltersBadge component is always rendered. The current configuration might not be sufficient due to conditional checks within the FiltersBadge component.

Here is a more detailed approach:

  1. Ensure that filters.visible is set to true in the dashboardUiConfig.
  2. Modify the FiltersBadge component to always render, regardless of the hideChartControls setting.

Here is the updated code snippet:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Superset Embedding POC</title>
    <style>
        iframe {
            width: 100%;
            height: 100%;
            border: none;
        }
    </style>
    <script src="https://unpkg.com/@superset-ui/embedded-sdk"></script>
</head>
<body>
<div style="width: 100%; height: 800px;" id="my-superset-container"></div>
<script>
    const dashboardConfig = {
        hideTab: true,
        hideTitle: true,
        hideChartControls: true,
        filters: {
          visible: true,  // Ensure this is set to true
          expanded: false,
       }
    };
    supersetEmbeddedSdk.embedDashboard({
        id: 'embedded-id',
        supersetDomain: 'domain',
        mountPoint: document.getElementById("my-superset-container"),
        fetchGuestToken: () => 'guest-token',
        dashboardUiConfig: dashboardConfig,
    });
</script>
</body>
</html>

Additionally, ensure that the FiltersBadge component is not conditionally hidden based on the hideChartControls setting. The FiltersBadge should always be rendered to display the applied filters:

<FiltersBadge chartId={slice.slice_id} />
{!uiConfig.hideChartControls && (
  <SliceHeaderControls
    slice={slice}
    isCached={isCached}
    isExpanded={isExpanded}
    cachedDttm={cachedDttm}
    updatedDttm={updatedDttm}
    toggleExpandSlice={toggleExpandSlice}
    forceRefresh={forceRefresh}
    logExploreChart={logExploreChart}
    logEvent={logEvent}
    exportCSV={exportCSV}
    exportPivotCSV={exportPivotCSV}
    exportFullCSV={exportFullCSV}
    exportXLSX={exportXLSX}
    exportFullXLSX={exportFullXLSX}
    supersetCanExplore={supersetCanExplore}
    supersetCanShare={supersetCanShare}
    supersetCanCSV={supersetCanCSV}
    componentId={componentId}
    dashboardId={dashboardId}
    addSuccessToast={addSuccessToast}
    addDangerToast={addDangerToast}
    handleToggleFullSize={handleToggleFullSize}
    isFullSize={isFullSize}
    isDescriptionExpanded={isExpanded}
    chartStatus={chartStatus}
    formData={formData}
    exploreUrl={exploreUrl}
    crossFiltersEnabled={isCrossFiltersEnabled}
  />
)}

By ensuring that the FiltersBadge is always rendered, you can make the applied filters visible on the charts without showing the chart controls [1][2].

To continue talking to Dosu, mention @dosu.

rusackas commented 1 month ago

I believe this does indeed fall under chart controls. It could be broken out into a different setting, if you're interested in opening such a PR.