You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by li...@apache.org on 2021/11/09 19:53:51 UTC

[superset] branch embedded updated: feat(dashboard): embedded dashboard UI configuration (#17175)

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

lilykuang pushed a commit to branch embedded
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/embedded by this push:
     new 36246f9  feat(dashboard): embedded dashboard UI configuration (#17175)
36246f9 is described below

commit 36246f95ff02e54a11db7e1eccef9f8a83316779
Author: Lily Kuang <li...@preset.io>
AuthorDate: Tue Nov 9 11:51:57 2021 -0800

    feat(dashboard): embedded dashboard UI configuration (#17175)
    
    * setup embedded provider
    
    * update ui configuration
    
    * fix test
---
 superset-frontend/src/components/Menu/Menu.tsx     |  4 +-
 .../src/components/UiConfigContext/index.tsx       | 58 +++++++++++++++++++++
 superset-frontend/src/constants.ts                 |  4 ++
 .../DashboardBuilder/DashboardBuilder.tsx          | 10 +++-
 .../src/dashboard/components/SliceHeader/index.tsx | 59 ++++++++++++----------
 superset-frontend/src/views/App.tsx                | 19 ++++---
 6 files changed, 116 insertions(+), 38 deletions(-)

diff --git a/superset-frontend/src/components/Menu/Menu.tsx b/superset-frontend/src/components/Menu/Menu.tsx
index 13d19fb..01e0c1c 100644
--- a/superset-frontend/src/components/Menu/Menu.tsx
+++ b/superset-frontend/src/components/Menu/Menu.tsx
@@ -29,6 +29,7 @@ import Icons from 'src/components/Icons';
 import { URL_PARAMS } from 'src/constants';
 import RightMenu from './MenuRight';
 import { Languages } from './LanguagePicker';
+import { useUiConfig } from '../UiConfigContext';
 
 interface BrandProps {
   path: string;
@@ -177,6 +178,7 @@ export function Menu({
 }: MenuProps) {
   const [showMenu, setMenu] = useState<MenuMode>('horizontal');
   const screens = useBreakpoint();
+  const uiConig = useUiConfig();
 
   useEffect(() => {
     function handleResize() {
@@ -191,7 +193,7 @@ export function Menu({
   }, []);
 
   const standalone = getUrlParam(URL_PARAMS.standalone);
-  if (standalone) return <></>;
+  if (standalone || uiConig.hideNav) return <></>;
 
   const renderSubMenu = ({
     label,
diff --git a/superset-frontend/src/components/UiConfigContext/index.tsx b/superset-frontend/src/components/UiConfigContext/index.tsx
new file mode 100644
index 0000000..b5c2f53
--- /dev/null
+++ b/superset-frontend/src/components/UiConfigContext/index.tsx
@@ -0,0 +1,58 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import React, { createContext, useContext, useState } from 'react';
+import { URL_PARAMS } from 'src/constants';
+import { getUrlParam } from 'src/utils/urlUtils';
+
+interface UiConfigType {
+  hideTitle: boolean;
+  hideTab: boolean;
+  hideNav: boolean;
+  hideChartControls: boolean;
+}
+interface EmbeddedUiConfigProviderProps {
+  children: JSX.Element;
+}
+
+export const UiConfigContext = createContext<UiConfigType>({
+  hideTitle: false,
+  hideTab: false,
+  hideNav: false,
+  hideChartControls: false,
+});
+
+export const useUiConfig = () => useContext(UiConfigContext);
+
+export const EmbeddedUiConfigProvider: React.FC<EmbeddedUiConfigProviderProps> = ({
+  children,
+}) => {
+  const config = getUrlParam(URL_PARAMS.uiConfig);
+  const [embeddedConfig] = useState({
+    hideTitle: (config & 1) !== 0,
+    hideTab: (config & 2) !== 0,
+    hideNav: (config & 4) !== 0,
+    hideChartControls: (config & 8) !== 0,
+  });
+
+  return (
+    <UiConfigContext.Provider value={embeddedConfig}>
+      {children}
+    </UiConfigContext.Provider>
+  );
+};
diff --git a/superset-frontend/src/constants.ts b/superset-frontend/src/constants.ts
index ab0fb9d..2539f23 100644
--- a/superset-frontend/src/constants.ts
+++ b/superset-frontend/src/constants.ts
@@ -31,6 +31,10 @@ export const URL_PARAMS = {
     name: 'standalone',
     type: 'number',
   },
+  uiConfig: {
+    name: 'uiConfig',
+    type: 'number',
+  },
   preselectFilters: {
     name: 'preselect_filters',
     type: 'object',
diff --git a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx
index 7d583d8..bc8f882 100644
--- a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx
+++ b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx
@@ -49,6 +49,7 @@ import {
 import FilterBar from 'src/dashboard/components/nativeFilters/FilterBar';
 import Loading from 'src/components/Loading';
 import { Global } from '@emotion/react';
+import { useUiConfig } from 'src/components/UiConfigContext';
 import { shouldFocusTabs, getRootLevelTabsComponent } from './utils';
 import DashboardContainer from './DashboardContainer';
 import { useNativeFilters } from './state';
@@ -199,6 +200,8 @@ const StyledDashboardContent = styled.div<{
 
 const DashboardBuilder: FC<DashboardBuilderProps> = () => {
   const dispatch = useDispatch();
+  const uiConfig = useUiConfig();
+
   const dashboardLayout = useSelector<RootState, DashboardLayout>(
     state => state.dashboardLayout.present,
   );
@@ -243,7 +246,9 @@ const DashboardBuilder: FC<DashboardBuilderProps> = () => {
   const standaloneMode = getUrlParam(URL_PARAMS.standalone);
   const isReport = standaloneMode === DashboardStandaloneMode.REPORT;
   const hideDashboardHeader =
-    standaloneMode === DashboardStandaloneMode.HIDE_NAV_AND_TITLE || isReport;
+    uiConfig.hideTitle ||
+    standaloneMode === DashboardStandaloneMode.HIDE_NAV_AND_TITLE ||
+    isReport;
 
   const barTopOffset =
     (hideDashboardHeader ? 0 : HEADER_HEIGHT) +
@@ -288,7 +293,7 @@ const DashboardBuilder: FC<DashboardBuilderProps> = () => {
       <div>
         {!hideDashboardHeader && <DashboardHeader />}
         {dropIndicatorProps && <div {...dropIndicatorProps} />}
-        {!isReport && topLevelTabs && (
+        {!isReport && topLevelTabs && !uiConfig.hideNav && (
           <WithPopoverMenu
             shouldFocus={shouldFocusTabs}
             menuItems={[
@@ -321,6 +326,7 @@ const DashboardBuilder: FC<DashboardBuilderProps> = () => {
       hideDashboardHeader,
       isReport,
       topLevelTabs,
+      uiConfig.hideNav,
     ],
   );
 
diff --git a/superset-frontend/src/dashboard/components/SliceHeader/index.tsx b/superset-frontend/src/dashboard/components/SliceHeader/index.tsx
index 9b42c81..a92fcc4 100644
--- a/superset-frontend/src/dashboard/components/SliceHeader/index.tsx
+++ b/superset-frontend/src/dashboard/components/SliceHeader/index.tsx
@@ -18,6 +18,7 @@
  */
 import React, { FC, useMemo } from 'react';
 import { styled, t } from '@superset-ui/core';
+import { useUiConfig } from 'src/components/UiConfigContext';
 import { Tooltip } from 'src/components/Tooltip';
 import { useDispatch, useSelector } from 'react-redux';
 import EditableTitle from 'src/components/EditableTitle';
@@ -44,7 +45,6 @@ type SliceHeaderProps = SliceHeaderControlsProps & {
 
 const annotationsLoading = t('Annotation layers are still loading.');
 const annotationsError = t('One ore more annotation layers failed loading.');
-
 const CrossFilterIcon = styled(Icons.CursorTarget)`
   cursor: pointer;
   color: ${({ theme }) => theme.colors.primary.base};
@@ -84,6 +84,7 @@ const SliceHeader: FC<SliceHeaderProps> = ({
   formData,
 }) => {
   const dispatch = useDispatch();
+  const uiConfig = useUiConfig();
   // TODO: change to indicator field after it will be implemented
   const crossFilterValue = useSelector<RootState, any>(
     state => state.dataMask[slice?.slice_id]?.filterState?.value,
@@ -157,32 +158,36 @@ const SliceHeader: FC<SliceHeaderProps> = ({
                 />
               </Tooltip>
             )}
-            <FiltersBadge chartId={slice.slice_id} />
-            <SliceHeaderControls
-              slice={slice}
-              isCached={isCached}
-              isExpanded={isExpanded}
-              cachedDttm={cachedDttm}
-              updatedDttm={updatedDttm}
-              toggleExpandSlice={toggleExpandSlice}
-              forceRefresh={forceRefresh}
-              logExploreChart={logExploreChart}
-              exploreUrl={exploreUrl}
-              exportCSV={exportCSV}
-              exportFullCSV={exportFullCSV}
-              supersetCanExplore={supersetCanExplore}
-              supersetCanShare={supersetCanShare}
-              supersetCanCSV={supersetCanCSV}
-              sliceCanEdit={sliceCanEdit}
-              componentId={componentId}
-              dashboardId={dashboardId}
-              addSuccessToast={addSuccessToast}
-              addDangerToast={addDangerToast}
-              handleToggleFullSize={handleToggleFullSize}
-              isFullSize={isFullSize}
-              chartStatus={chartStatus}
-              formData={formData}
-            />
+            {!uiConfig.hideChartControls && (
+              <FiltersBadge chartId={slice.slice_id} />
+            )}
+            {!uiConfig.hideChartControls && (
+              <SliceHeaderControls
+                slice={slice}
+                isCached={isCached}
+                isExpanded={isExpanded}
+                cachedDttm={cachedDttm}
+                updatedDttm={updatedDttm}
+                toggleExpandSlice={toggleExpandSlice}
+                forceRefresh={forceRefresh}
+                logExploreChart={logExploreChart}
+                exploreUrl={exploreUrl}
+                exportCSV={exportCSV}
+                exportFullCSV={exportFullCSV}
+                supersetCanExplore={supersetCanExplore}
+                supersetCanShare={supersetCanShare}
+                supersetCanCSV={supersetCanCSV}
+                sliceCanEdit={sliceCanEdit}
+                componentId={componentId}
+                dashboardId={dashboardId}
+                addSuccessToast={addSuccessToast}
+                addDangerToast={addDangerToast}
+                handleToggleFullSize={handleToggleFullSize}
+                isFullSize={isFullSize}
+                chartStatus={chartStatus}
+                formData={formData}
+              />
+            )}
           </>
         )}
       </div>
diff --git a/superset-frontend/src/views/App.tsx b/superset-frontend/src/views/App.tsx
index e23695c..605ed20 100644
--- a/superset-frontend/src/views/App.tsx
+++ b/superset-frontend/src/views/App.tsx
@@ -31,6 +31,7 @@ import { QueryParamProvider } from 'use-query-params';
 import { initFeatureFlags } from 'src/featureFlags';
 import { ThemeProvider } from '@superset-ui/core';
 import { DynamicPluginProvider } from 'src/components/DynamicPlugins';
+import { EmbeddedUiConfigProvider } from 'src/components/UiConfigContext';
 import ErrorBoundary from 'src/components/ErrorBoundary';
 import Loading from 'src/components/Loading';
 import Menu from 'src/components/Menu/Menu';
@@ -68,14 +69,16 @@ const RootContextProviders: React.FC = ({ children }) => {
       <ReduxProvider store={store}>
         <DndProvider backend={HTML5Backend}>
           <FlashProvider messages={common.flash_messages}>
-            <DynamicPluginProvider>
-              <QueryParamProvider
-                ReactRouterRoute={Route}
-                stringifyOptions={{ encode: false }}
-              >
-                {children}
-              </QueryParamProvider>
-            </DynamicPluginProvider>
+            <EmbeddedUiConfigProvider>
+              <DynamicPluginProvider>
+                <QueryParamProvider
+                  ReactRouterRoute={Route}
+                  stringifyOptions={{ encode: false }}
+                >
+                  {children}
+                </QueryParamProvider>
+              </DynamicPluginProvider>
+            </EmbeddedUiConfigProvider>
           </FlashProvider>
         </DndProvider>
       </ReduxProvider>