-
Phoomparin Mano authored
* cancel request on unmount in static question * use deferred promise * remove logs * alias cancelled to deferred.promise * extract useLoadStaticQuestion hook * add tests for request cancellation * change updateQuestion method * add sanity check with fetchMock
Phoomparin Mano authored* cancel request on unmount in static question * use deferred promise * remove logs * alias cancelled to deferred.promise * extract useLoadStaticQuestion hook * add tests for request cancellation * change updateQuestion method * add sanity check with fetchMock
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
StaticQuestion.tsx 3.84 KiB
import cx from "classnames";
import { t } from "ttag";
import {
SdkError,
SdkLoader,
withPublicComponentWrapper,
} from "embedding-sdk/components/private/PublicComponentWrapper";
import { useLoadStaticQuestion } from "embedding-sdk/hooks/private/use-load-static-question";
import { getDefaultVizHeight } from "embedding-sdk/lib/default-height";
import CS from "metabase/css/core/index.css";
import { useValidatedEntityId } from "metabase/lib/entity-id/hooks/use-validated-entity-id";
import { getResponseErrorMessage } from "metabase/lib/errors";
import { useSelector } from "metabase/lib/redux";
import QueryVisualization from "metabase/query_builder/components/QueryVisualization";
import {
ChartTypeSettings,
useChartTypeVisualizations,
} from "metabase/query_builder/components/chart-type-selector";
import { getMetadata } from "metabase/selectors/metadata";
import { Box, Group } from "metabase/ui";
import { PublicMode } from "metabase/visualizations/click-actions/modes/PublicMode";
import Question from "metabase-lib/v1/Question";
import type { CardEntityId, CardId, Dataset } from "metabase-types/api";
export type StaticQuestionProps = {
questionId: CardId | CardEntityId;
showVisualizationSelector?: boolean;
height?: string | number;
parameterValues?: Record<string, string | number>;
};
type StaticQuestionVisualizationSelectorProps = {
question: Question;
result: Dataset | null;
onUpdateQuestion: (question: Question) => void;
};
const StaticQuestionVisualizationSelector = ({
question,
result,
onUpdateQuestion,
}: StaticQuestionVisualizationSelectorProps) => {
const {
selectedVisualization,
updateQuestionVisualization,
sensibleVisualizations,
nonSensibleVisualizations,
} = useChartTypeVisualizations({
question,
result,
onUpdateQuestion,
});
return (
<Box w="355px">
<ChartTypeSettings
selectedVisualization={selectedVisualization}
onSelectVisualization={updateQuestionVisualization}
sensibleVisualizations={sensibleVisualizations}
nonSensibleVisualizations={nonSensibleVisualizations}
/>
</Box>
);
};
const StaticQuestionInner = ({
questionId: initId,
showVisualizationSelector,
height,
parameterValues,
}: StaticQuestionProps): JSX.Element | null => {
const { isLoading: isValidatingEntityId, id: questionId } =
useValidatedEntityId({
type: "card",
id: initId,
});
const metadata = useSelector(getMetadata);
const { card, loading, result, error, updateQuestion } =
useLoadStaticQuestion(questionId, parameterValues);
const isLoading = loading || (!result && !error) || isValidatingEntityId;
if (error) {
return (
<SdkError
message={getResponseErrorMessage(error) ?? t`Invalid question ID`}
/>
);
}
if (isLoading) {
return <SdkLoader />;
}
const question = new Question(card, metadata);
const defaultHeight = card ? getDefaultVizHeight(card.display) : undefined;
return (
<Box
className={cx(CS.flexFull, CS.fullWidth)}
h={height ?? defaultHeight}
bg="var(--mb-color-bg-question)"
>
<Group h="100%" pos="relative" align="flex-start">
{showVisualizationSelector && (
<StaticQuestionVisualizationSelector
question={question}
result={result}
onUpdateQuestion={updateQuestion}
/>
)}
<QueryVisualization
className={cx(CS.flexFull, CS.fullWidth, CS.fullHeight)}
question={question}
rawSeries={[{ card, data: result?.data }]}
isRunning={isLoading}
isObjectDetail={false}
isResultDirty={false}
isNativeEditorOpen={false}
result={result}
noHeader
mode={PublicMode}
/>
</Group>
</Box>
);
};
export const StaticQuestion = withPublicComponentWrapper(StaticQuestionInner);