diff --git a/package.json b/package.json index 1bb9c7d4..50582bf8 100644 --- a/package.json +++ b/package.json @@ -96,6 +96,7 @@ "@emotion/styled": "^11.14.1", "@mui/x-date-pickers": "^7.29.4", "@mui/x-tree-view": "^8.12.0", + "@superset-ui/embedded-sdk": "^0.2.0", "ag-grid-community": "~34.2.0", "ag-grid-react": "~34.2.0", "clsx": "^2.1.1", diff --git a/src/charts/SupersetEmbed/SupersetEmbed.js b/src/charts/SupersetEmbed/SupersetEmbed.js new file mode 100644 index 00000000..c2d980e3 --- /dev/null +++ b/src/charts/SupersetEmbed/SupersetEmbed.js @@ -0,0 +1,89 @@ +// Copyright (c) Cosmo Tech. +// Licensed under the MIT license. +import React, { useEffect, useRef, useState } from 'react'; +import PropTypes from 'prop-types'; +import { Box, CircularProgress, Backdrop } from '@mui/material'; +import { embedDashboard } from '@superset-ui/embedded-sdk'; + +export const SupersetEmbed = ({ + isLoading = false, + guestToken, + report, + style = { width: '100%', height: '800px' }, + options, +}) => { + const containerRef = useRef(null); + const [isEmbedded, setIsEmbedded] = useState(false); + + useEffect(() => { + const loadSuperset = async () => { + if (!guestToken || !report?.id || !options?.supersetUrl) return; + + try { + setIsEmbedded(false); + await embedDashboard({ + id: report.id, + supersetDomain: options.supersetUrl, + mountPoint: containerRef.current, + fetchGuestToken: async () => guestToken, + dashboardUiConfig: report?.uiConfig || {}, + }); + setIsEmbedded(true); + } catch (error) { + console.error('Superset embedding failed:', error); + } + }; + + loadSuperset(); + + if (containerRef.current && containerRef.current.children[0]) { + containerRef.current.children[0].style.width = '100%'; + containerRef.current.children[0].style.height = '100%'; + } + }, [guestToken, report, options]); + + return ( + + theme.zIndex.drawer + 1, + }} + > + + + + + ); +}; + +SupersetEmbed.propTypes = { + isLoading: PropTypes.bool, + guestToken: PropTypes.string.isRequired, + report: PropTypes.shape({ + id: PropTypes.string.isRequired, + uiConfig: PropTypes.object, + }).isRequired, + style: PropTypes.object, + options: PropTypes.shape({ + supersetUrl: PropTypes.string.isRequired, + }).isRequired, +}; diff --git a/src/charts/SupersetEmbed/index.js b/src/charts/SupersetEmbed/index.js new file mode 100644 index 00000000..70d71bc3 --- /dev/null +++ b/src/charts/SupersetEmbed/index.js @@ -0,0 +1,4 @@ +// Copyright (c) Cosmo Tech. +// Licensed under the MIT license. + +export { SupersetEmbed } from './SupersetEmbed'; diff --git a/src/charts/index.js b/src/charts/index.js index f7c28cb8..3135221d 100644 --- a/src/charts/index.js +++ b/src/charts/index.js @@ -5,3 +5,4 @@ export { CytoViz } from './CytoViz'; export { Dashboard } from './Dashboard'; export { ScenarioManagerTreeList } from './ScenarioManagerTreeList'; export { SimplePowerBIReportEmbed } from './SimplePowerBIReportEmbed'; +export { SupersetEmbed } from './SupersetEmbed'; diff --git a/src/index.js b/src/index.js index ccf59b30..7f689380 100644 --- a/src/index.js +++ b/src/index.js @@ -3,7 +3,7 @@ export { CreateScenarioButton, SelfDestructLinkButton, SignInButton, RolesEditionButton } from './buttons'; export { ScenarioNode, ResourceCard } from './cards'; -export { CytoViz, Dashboard, ScenarioManagerTreeList, SimplePowerBIReportEmbed } from './charts'; +export { CytoViz, Dashboard, ScenarioManagerTreeList, SimplePowerBIReportEmbed, SupersetEmbed } from './charts'; export { SimpleTwoActionsDialog, DontAskAgainDialog } from './dialogs'; export { HierarchicalComboBox, diff --git a/yarn.lock b/yarn.lock index fea5a843..c3bd8513 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1876,6 +1876,7 @@ __metadata: "@rollup/plugin-commonjs": "npm:^28.0.6" "@rollup/plugin-image": "npm:^3.0.3" "@rollup/plugin-node-resolve": "npm:^16.0.1" + "@superset-ui/embedded-sdk": "npm:^0.2.0" "@testing-library/dom": "npm:^10.4.1" "@testing-library/jest-dom": "npm:^6.8.0" "@testing-library/react": "npm:^16.3.0" @@ -3530,6 +3531,23 @@ __metadata: languageName: node linkType: hard +"@superset-ui/embedded-sdk@npm:^0.2.0": + version: 0.2.0 + resolution: "@superset-ui/embedded-sdk@npm:0.2.0" + dependencies: + "@superset-ui/switchboard": "npm:^0.20.3" + jwt-decode: "npm:^4.0.0" + checksum: 10c0/9cae6956fc96361f8b8e495e726b52c9eca7e927de2163e6c69efcdfa80778de90d0912638e738bed8f10e958077ab414cfa264b180d2b316188932f8a5b0154 + languageName: node + linkType: hard + +"@superset-ui/switchboard@npm:^0.20.3": + version: 0.20.3 + resolution: "@superset-ui/switchboard@npm:0.20.3" + checksum: 10c0/867786b3f1b389dd19e9555eaba6ab2e6cdd3528103bed6bb601e29e10455507d36f2f4ed2978dae1d07030cb35ef612ea4f24db0867a48eab63ac530f7b8a05 + languageName: node + linkType: hard + "@testing-library/dom@npm:^10.4.1": version: 10.4.1 resolution: "@testing-library/dom@npm:10.4.1" @@ -8795,6 +8813,13 @@ __metadata: languageName: node linkType: hard +"jwt-decode@npm:^4.0.0": + version: 4.0.0 + resolution: "jwt-decode@npm:4.0.0" + checksum: 10c0/de75bbf89220746c388cf6a7b71e56080437b77d2edb29bae1c2155048b02c6b8c59a3e5e8d6ccdfd54f0b8bda25226e491a4f1b55ac5f8da04cfbadec4e546c + languageName: node + linkType: hard + "keyv@npm:^4.5.4": version: 4.5.4 resolution: "keyv@npm:4.5.4"