diff --git a/superset-frontend/spec/helpers/reducerIndex.ts b/superset-frontend/spec/helpers/reducerIndex.ts index edfaf7bb5c..459a112e22 100644 --- a/superset-frontend/spec/helpers/reducerIndex.ts +++ b/superset-frontend/spec/helpers/reducerIndex.ts @@ -31,13 +31,13 @@ import explore from 'src/explore/reducers/exploreReducer'; import sqlLab from 'src/SqlLab/reducers/sqlLab'; import localStorageUsageInKilobytes from 'src/SqlLab/reducers/localStorageUsage'; import reports from 'src/reports/reducers/reports'; +import getBootstrapData from 'src/utils/getBootstrapData'; const impressionId = (state = '') => state; -const container = document.getElementById('app'); -const bootstrap = JSON.parse(container?.getAttribute('data-bootstrap') ?? '{}'); -const common = { ...bootstrap.common }; -const user = { ...bootstrap.user }; +const bootstrapData = getBootstrapData(); +const common = { ...bootstrapData.common }; +const user = { ...bootstrapData.user }; const noopReducer = (initialState: unknown) => diff --git a/superset-frontend/spec/helpers/setup.ts b/superset-frontend/spec/helpers/setup.ts index bd2961e23c..281ab4ae4b 100644 --- a/superset-frontend/spec/helpers/setup.ts +++ b/superset-frontend/spec/helpers/setup.ts @@ -25,5 +25,5 @@ configureTestingLibrary({ testIdAttribute: 'data-test', }); -document.body.innerHTML = '
'; +document.body.innerHTML = ''; expect.extend(matchers); diff --git a/superset-frontend/src/SqlLab/App.jsx b/superset-frontend/src/SqlLab/App.jsx index 812202eec2..4a30095803 100644 --- a/superset-frontend/src/SqlLab/App.jsx +++ b/superset-frontend/src/SqlLab/App.jsx @@ -30,6 +30,7 @@ import { FeatureFlag, } from 'src/featureFlags'; import setupExtensions from 'src/setup/setupExtensions'; +import getBootstrapData from 'src/utils/getBootstrapData'; import getInitialState from './reducers/getInitialState'; import rootReducer from './reducers/index'; import { initEnhancer } from '../reduxUtils'; @@ -48,8 +49,7 @@ import { theme } from '../preamble'; setupApp(); setupExtensions(); -const appContainer = document.getElementById('app'); -const bootstrapData = JSON.parse(appContainer.getAttribute('data-bootstrap')); +const bootstrapData = getBootstrapData(); initFeatureFlags(bootstrapData.common.feature_flags); diff --git a/superset-frontend/src/SqlLab/components/ScheduleQueryButton/index.tsx b/superset-frontend/src/SqlLab/components/ScheduleQueryButton/index.tsx index 780bc4d96d..c78e2bd32d 100644 --- a/superset-frontend/src/SqlLab/components/ScheduleQueryButton/index.tsx +++ b/superset-frontend/src/SqlLab/components/ScheduleQueryButton/index.tsx @@ -25,11 +25,9 @@ import * as chrono from 'chrono-node'; import ModalTrigger, { ModalTriggerRef } from 'src/components/ModalTrigger'; import { Form, FormItem } from 'src/components/Form'; import Button from 'src/components/Button'; +import getBootstrapData from 'src/utils/getBootstrapData'; -const appContainer = document.getElementById('app'); -const bootstrapData = JSON.parse( - appContainer?.getAttribute('data-bootstrap') || '{}', -); +const bootstrapData = getBootstrapData(); const scheduledQueriesConf = bootstrapData?.common?.conf?.SCHEDULED_QUERIES; const validators = { diff --git a/superset-frontend/src/SqlLab/components/SqlEditor/index.jsx b/superset-frontend/src/SqlLab/components/SqlEditor/index.jsx index 8e48cbefbe..e27f6c1e0b 100644 --- a/superset-frontend/src/SqlLab/components/SqlEditor/index.jsx +++ b/superset-frontend/src/SqlLab/components/SqlEditor/index.jsx @@ -74,6 +74,7 @@ import { } from 'src/utils/localStorageHelpers'; import { FeatureFlag, isFeatureEnabled } from 'src/featureFlags'; import { EmptyStateBig } from 'src/components/EmptyState'; +import getBootstrapData from 'src/utils/getBootstrapData'; import { isEmpty } from 'lodash'; import TemplateParamsEditor from '../TemplateParamsEditor'; import SouthPane from '../SouthPane'; @@ -86,10 +87,7 @@ import AceEditorWrapper from '../AceEditorWrapper'; import RunQueryActionButton from '../RunQueryActionButton'; import QueryLimitSelect from '../QueryLimitSelect'; -const appContainer = document.getElementById('app'); -const bootstrapData = JSON.parse( - appContainer.getAttribute('data-bootstrap') || '{}', -); +const bootstrapData = getBootstrapData(); const validatorMap = bootstrapData?.common?.conf?.SQL_VALIDATORS_BY_ENGINE || {}; const scheduledQueriesConf = bootstrapData?.common?.conf?.SCHEDULED_QUERIES; diff --git a/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.jsx b/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.jsx index 63c7cc862c..ca53fed709 100644 --- a/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.jsx +++ b/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.jsx @@ -28,6 +28,7 @@ import { Tooltip } from 'src/components/Tooltip'; import { detectOS } from 'src/utils/common'; import * as Actions from 'src/SqlLab/actions/sqlLab'; import { EmptyStateBig } from 'src/components/EmptyState'; +import getBootstrapData from 'src/utils/getBootstrapData'; import SqlEditor from '../SqlEditor'; import SqlEditorTabHeader from '../SqlEditorTabHeader'; @@ -106,13 +107,10 @@ class TabbedSqlEditors extends React.PureComponent { } // merge post form data with GET search params - // Hack: this data should be comming from getInitialState + // Hack: this data should be coming from getInitialState // but for some reason this data isn't being passed properly through // the reducer. - const appContainer = document.getElementById('app'); - const bootstrapData = JSON.parse( - appContainer?.getAttribute('data-bootstrap') || '{}', - ); + const bootstrapData = getBootstrapData(); const query = { ...bootstrapData.requested_query, ...URI(window.location).search(true), diff --git a/superset-frontend/src/addSlice/AddSliceContainer.test.tsx b/superset-frontend/src/addSlice/AddSliceContainer.test.tsx index e5f62fd258..1e26c84995 100644 --- a/superset-frontend/src/addSlice/AddSliceContainer.test.tsx +++ b/superset-frontend/src/addSlice/AddSliceContainer.test.tsx @@ -84,7 +84,7 @@ async function getWrapper(user = mockUser) { return wrapper; } -test('renders a select and a VizTypeControl', async () => { +test('renders a select and a VizTypeGallery', async () => { const wrapper = await getWrapper(); expect(wrapper.find(AsyncSelect)).toExist(); expect(wrapper.find(VizTypeGallery)).toExist(); diff --git a/superset-frontend/src/addSlice/AddSliceContainer.tsx b/superset-frontend/src/addSlice/AddSliceContainer.tsx index f63c53f337..c50bcad9a2 100644 --- a/superset-frontend/src/addSlice/AddSliceContainer.tsx +++ b/superset-frontend/src/addSlice/AddSliceContainer.tsx @@ -39,6 +39,7 @@ import VizTypeGallery, { } from 'src/explore/components/controls/VizTypeControl/VizTypeGallery'; import { findPermission } from 'src/utils/findPermission'; import { UserWithPermissionsAndRoles } from 'src/types/bootstrapTypes'; +import getBootstrapData from 'src/utils/getBootstrapData'; type Dataset = { id: number; @@ -62,6 +63,9 @@ export type AddSliceContainerState = { const ESTIMATED_NAV_HEIGHT = 56; const ELEMENTS_EXCEPT_VIZ_GALLERY = ESTIMATED_NAV_HEIGHT + 250; +const bootstrapData = getBootstrapData(); +const denyList: string[] = bootstrapData.common.conf.VIZ_TYPE_DENYLIST || []; + const StyledContainer = styled.div` ${({ theme }) => ` flex: 1 1 auto; @@ -395,6 +399,7 @@ export class AddSliceContainer extends React.PureComponent< description={{' '} - {t('joined')} {moment(user.createdOn, 'YYYYMMDD').fromNow()} + {t('joined')} {moment(user?.createdOn, 'YYYYMMDD').fromNow()}
- {user.email} + {user?.email}
- {Object.keys(user.roles).join(', ')} + {' '} + {Object.keys(user?.roles || {}).join(', ')}
{t('id:')} - {user.userId} + {user?.userId}