Skip to content
Snippets Groups Projects
Unverified Commit 16a4ac4a authored by Raphael Krut-Landau's avatar Raphael Krut-Landau Committed by GitHub
Browse files

In sidesheets, show correct sources for a model (#49119)

parent a223f819
No related branches found
No related tags found
No related merge requests found
......@@ -71,7 +71,7 @@ export const QuestionDetails = ({ question }: { question: Question }) => {
</Flex>
</SidesheetCardSection>
<SharingDisplay question={question} />
<QuestionSources question={question} />
<QuestionSources />
</>
);
};
......
......@@ -3,30 +3,35 @@ import { c } from "ttag";
import { SidesheetCardSection } from "metabase/common/components/Sidesheet";
import Link from "metabase/core/components/Link";
import { useSelector } from "metabase/lib/redux";
import { getQuestionWithParameters } from "metabase/query_builder/selectors";
import { Flex, FixedSizeIcon as Icon } from "metabase/ui";
import type Question from "metabase-lib/v1/Question";
import { getDataSourceParts } from "../../../ViewHeader/components/QuestionDataSource/utils";
import type { QuestionSource } from "./types";
import { getIconPropsForSource } from "./utils";
export const QuestionSources = ({ question }: { question: Question }) => {
const sources = getDataSourceParts({
question,
subHead: false,
isObjectDetail: true,
formatTableAsComponent: false,
}) as unknown as QuestionSource[];
export const QuestionSources = () => {
/** Retrieve current question from the Redux store */
const questionWithParameters = useSelector(getQuestionWithParameters);
const sourcesWithIcons: QuestionSource[] = useMemo(() => {
const sources = questionWithParameters
? (getDataSourceParts({
question: questionWithParameters,
subHead: false,
isObjectDetail: true,
formatTableAsComponent: false,
}) as QuestionSource[])
: [];
return sources.map(source => ({
...source,
iconProps: getIconPropsForSource(source),
}));
}, [sources]);
}, [questionWithParameters]);
if (!sources.length) {
if (!questionWithParameters || !sourcesWithIcons.length) {
return null;
}
......@@ -47,7 +52,9 @@ export const QuestionSources = ({ question }: { question: Question }) => {
{name}
</Flex>
</Link>
{index < sources.length - 1 && <Flex lh="1.25rem">{"/"}</Flex>}
{index < sourcesWithIcons.length - 1 && (
<Flex lh="1.25rem">{"/"}</Flex>
)}
</Fragment>
))}
</Flex>
......
......@@ -5,13 +5,14 @@ import { mockSettings } from "__support__/settings";
import { createMockEntitiesState } from "__support__/store";
import { renderWithProviders, screen, within } from "__support__/ui";
import { modelIconMap } from "metabase/lib/icon";
import { checkNotNull } from "metabase/lib/types";
import { getMetadata } from "metabase/selectors/metadata";
import { convertSavedQuestionToVirtualTable } from "metabase-lib/v1/metadata/utils/saved-questions";
import type { Card, NormalizedTable } from "metabase-types/api";
import { createMockCard, createMockSettings } from "metabase-types/api/mocks";
import { createSampleDatabase } from "metabase-types/api/mocks/presets";
import { createMockState } from "metabase-types/store/mocks";
import {
createMockQueryBuilderState,
createMockState,
} from "metabase-types/store/mocks";
import { QuestionSources } from "./QuestionSources";
......@@ -25,6 +26,7 @@ const setup = async ({
sourceCard,
}: SetupOpts = {}) => {
const state = createMockState({
qb: createMockQueryBuilderState({ card }),
settings: mockSettings(createMockSettings()),
entities: createMockEntitiesState({
databases: [createSampleDatabase()],
......@@ -54,16 +56,11 @@ const setup = async ({
};
}
const metadata = getMetadata(state);
const question = checkNotNull(metadata.question(card.id));
return renderWithProviders(
<Route
path="/"
component={() => <QuestionSources question={question} />}
/>,
<Route path="/" component={() => <QuestionSources />} />,
{
withRouter: true,
storeInitialState: state,
},
);
};
......@@ -142,4 +139,37 @@ describe("QuestionSources", () => {
"/question/2-my-source-question",
);
});
it("shows source information for a model (its database and table)", async () => {
const model = createMockCard({
name: "My Model",
type: "model",
});
await setup({ card: model });
const databaseLink = await screen.findByRole("link", {
name: /Sample Database/i,
});
expect(
await within(databaseLink).findByLabelText("database icon"),
).toBeInTheDocument();
expect(databaseLink).toHaveAttribute(
"href",
"/browse/databases/1-sample-database",
);
expect(screen.getByText("/")).toBeInTheDocument();
const tableLink = await screen.findByRole("link", { name: /Products/i });
expect(tableLink).toBeInTheDocument();
expect(
await within(tableLink).findByLabelText(`table icon`),
).toBeInTheDocument();
expect(tableLink).toHaveAttribute(
"href",
expect.stringMatching(/^\/question#[a-zA-Z0-9]{20}/),
);
});
});
......@@ -20,7 +20,10 @@ import {
createMockUser,
} from "metabase-types/api/mocks";
import { createSampleDatabase } from "metabase-types/api/mocks/presets";
import { createMockState } from "metabase-types/store/mocks";
import {
createMockQueryBuilderState,
createMockState,
} from "metabase-types/store/mocks";
import { QuestionInfoSidebar } from "../QuestionInfoSidebar";
......@@ -47,6 +50,7 @@ export const setup = async ({
const state = createMockState({
currentUser,
settings: mockSettings(settings),
qb: createMockQueryBuilderState({ card }),
entities: createMockEntitiesState({
databases: [createSampleDatabase()],
questions: [card],
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment