-
Oisin Coveney authoredOisin Coveney authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
StaticQuestion.tsx 4.58 KiB
import cx from "classnames";
import { useEffect, useState } from "react";
import { useSdkSelector } from "embedding-sdk/store";
import { getIsInitialized, getIsLoggedIn } from "embedding-sdk/store/selectors";
import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
import CS from "metabase/css/core/index.css";
import { useSelector } from "metabase/lib/redux";
import {
onCloseChartType,
onOpenChartSettings,
setUIControls,
} from "metabase/query_builder/actions";
import QueryVisualization from "metabase/query_builder/components/QueryVisualization";
import ChartTypeSidebar from "metabase/query_builder/components/view/sidebars/ChartTypeSidebar";
import { getMetadata } from "metabase/selectors/metadata";
import { CardApi } from "metabase/services";
import { Box, Group, Text } from "metabase/ui";
import { PublicMode } from "metabase/visualizations/click-actions/modes/PublicMode";
import Question from "metabase-lib/v1/Question";
import type { Card, CardId, Dataset } from "metabase-types/api";
interface QueryVisualizationProps {
questionId: CardId;
showVisualizationSelector?: boolean;
}
type State = {
loading: boolean;
card: Card | null;
cardError?: Card | string | null;
result: Dataset | null;
resultError?: Dataset | string | null;
};
export const StaticQuestion = ({
questionId,
showVisualizationSelector,
}: QueryVisualizationProps): JSX.Element | null => {
const isInitialized = useSdkSelector(getIsInitialized);
const isLoggedIn = useSdkSelector(getIsLoggedIn);
const metadata = useSelector(getMetadata);
const [{ loading, card, result, cardError, resultError }, setState] =
useState<State>({
loading: false,
card: null,
cardError: null,
result: null,
resultError: null,
});
const loadCardData = async ({ questionId }: { questionId: number }) => {
setState(prevState => ({
...prevState,
loading: true,
}));
Promise.all([
CardApi.get({ cardId: questionId }),
CardApi.query({
cardId: questionId,
}),
])
.then(([card, result]) => {
setState(prevState => ({
...prevState,
card,
result,
loading: false,
cardError: null,
resultError: null,
}));
})
.catch(([cardError, resultError]) => {
setState(prevState => ({
...prevState,
result: null,
card: null,
loading: false,
cardError,
resultError,
}));
});
};
useEffect(() => {
if (!isInitialized || !isLoggedIn) {
setState({
loading: false,
card: null,
result: null,
cardError: null,
resultError: null,
});
} else {
loadCardData({ questionId });
}
}, [isInitialized, isLoggedIn, questionId]);
const changeVisualization = (newQuestion: Question) => {
setState({
card: newQuestion.card(),
result: result,
loading: false,
});
};
if (!isInitialized) {
return null;
}
if (!isLoggedIn) {
return (
<div>
<Text>You should be logged in to see this content.</Text>
</div>
);
}
const isLoading = loading || (!result && !resultError);
return (
<LoadingAndErrorWrapper
className={cx(CS.flexFull, CS.fullWidth)}
loading={isLoading}
error={cardError || resultError}
noWrapper
>
{() => {
const question = new Question(card, metadata);
const legacyQuery = question.legacyQuery({
useStructuredQuery: true,
});
return (
<Group h="100%" pos="relative" align="flex-start">
{showVisualizationSelector && (
<Box w="355px">
<ChartTypeSidebar
question={question}
result={result}
onOpenChartSettings={onOpenChartSettings}
onCloseChartType={onCloseChartType}
query={legacyQuery}
setUIControls={setUIControls}
updateQuestion={changeVisualization}
/>
</Box>
)}
<QueryVisualization
className={cx(CS.flexFull, CS.fullWidth)}
question={question}
rawSeries={[{ card, data: result?.data }]}
isRunning={isLoading}
isObjectDetail={false}
isResultDirty={false}
isNativeEditorOpen={false}
result={result}
noHeader
mode={PublicMode}
/>
</Group>
);
}}
</LoadingAndErrorWrapper>
);
};