Skip to content
Snippets Groups Projects
Unverified Commit 7ae5237b authored by Alexander Lesnenko's avatar Alexander Lesnenko Committed by GitHub
Browse files

allow using public questions and dashboards in click behavior (#22801)

parent ce0d4eae
Branches
Tags
No related merge requests found
......@@ -20,6 +20,7 @@ import DashboardPicker from "metabase/containers/DashboardPicker";
import Questions from "metabase/entities/questions";
import QuestionPicker from "metabase/containers/QuestionPicker";
import Sidebar from "metabase/dashboard/components/Sidebar";
import CheckBox from "metabase/core/components/CheckBox";
import ClickMappings, {
withUserAttributes,
clickTargetObjectType,
......@@ -789,6 +790,18 @@ function QuestionDashboardPicker({ dashcard, clickBehavior, updateSettings }) {
<Entity.Loader id={clickBehavior.targetId}>
{({ object }) => (
<div className="pt1">
{object.public_uuid && (
<CheckBox
label={t`Use public link`}
checked={clickBehavior.use_public_link}
onChange={e =>
updateSettings({
...clickBehavior,
use_public_link: e.target.checked,
})
}
/>
)}
<Heading>
{
{
......
......@@ -72,14 +72,19 @@ export default ({ question, clicked }) => {
},
};
} else {
const targetDashboard = extraData.dashboards[targetId];
const queryParams = getParameterValuesBySlug(parameterMapping, {
data,
extraData,
clickBehavior,
});
const urlSearchParams = querystring.stringify(queryParams);
const url = `/dashboard/${targetId}?${urlSearchParams}`;
const path =
clickBehavior.use_public_link && targetDashboard.public_uuid
? `/public/dashboard/${targetDashboard.public_uuid}`
: `/dashboard/${targetId}`;
const url = `${path}?${querystring.stringify(queryParams)}`;
behavior = { url: () => url };
}
} else if (linkType === "question" && extraData && extraData.questions) {
......@@ -104,9 +109,16 @@ export default ({ question, clicked }) => {
}))
.value();
const url = targetQuestion.isStructured()
? targetQuestion.getUrlWithParameters(parameters, queryParams)
: `${targetQuestion.getUrl()}?${querystring.stringify(queryParams)}`;
let url = null;
if (clickBehavior.use_public_link && targetQuestion.publicUUID()) {
url = `/public/question/${targetQuestion.publicUUID()}?${querystring.stringify(
queryParams,
)}`;
} else {
url = targetQuestion.isStructured()
? targetQuestion.getUrlWithParameters(parameters, queryParams)
: `${targetQuestion.getUrl()}?${querystring.stringify(queryParams)}`;
}
behavior = { url: () => url };
}
......
......@@ -58,7 +58,7 @@ const mapDispatchToProps = {
// NOTE: this should use DashboardData HoC
class PublicDashboard extends Component {
async UNSAFE_componentWillMount() {
_initialize = async () => {
const {
initialize,
fetchDashboard,
......@@ -82,14 +82,22 @@ class PublicDashboard extends Component {
console.error(error);
setErrorPage(error);
}
};
async componentDidMount() {
this._initialize();
}
componentWillUnmount() {
this.props.cancelFetchDashboardCardData();
}
UNSAFE_componentWillReceiveProps(nextProps) {
if (!_.isEqual(this.props.parameterValues, nextProps.parameterValues)) {
async componentDidUpdate(prevProps) {
if (this.props.dashboardId !== prevProps.dashboardId) {
return this._initialize();
}
if (!_.isEqual(this.props.parameterValues, prevProps.parameterValues)) {
this.props.fetchDashboardCardData({ reload: false, clear: true });
}
}
......
......@@ -11,78 +11,56 @@ describe("issue 17160", () => {
beforeEach(() => {
restore();
cy.signInAsAdmin();
});
cy.createNativeQuestion({
name: `17160Q`,
native: {
query: "SELECT * FROM products WHERE {{CATEGORY}}",
"template-tags": {
CATEGORY: {
id: "6b8b10ef-0104-1047-1e1b-2492d5954322",
name: "CATEGORY",
display_name: "CATEGORY",
type: "dimension",
dimension: ["field", PRODUCTS.CATEGORY, null],
"widget-type": "category",
default: null,
},
},
},
}).then(({ body: { id: questionId } }) => {
cy.createDashboard({ name: "17160D" }).then(
({ body: { id: dashboardId } }) => {
// Add the question to the dashboard
cy.request("POST", `/api/dashboard/${dashboardId}/cards`, {
cardId: questionId,
}).then(({ body: { id: dashCardId } }) => {
// Add dashboard filter
cy.request("PUT", `/api/dashboard/${dashboardId}`, {
parameters: [
{
id: CATEGORY_FILTER_PARAMETER_ID,
name: "Category",
slug: "category",
sectionId: "string",
type: "string/=",
},
],
});
it("should pass multiple filter values to questions and dashboards (metabase#17160-1)", () => {
setup(false);
cy.findByText("Category").click();
createTargetDashboardForClickBehavior().then(targetDashboardId => {
// Create a click behavior and resize the question card
cy.request("PUT", `/api/dashboard/${dashboardId}/cards`, {
cards: [
{
id: dashCardId,
card_id: questionId,
row: 0,
col: 0,
sizeX: 12,
sizeY: 10,
parameter_mappings: [
{
parameter_id: CATEGORY_FILTER_PARAMETER_ID,
card_id: 4,
target: ["dimension", ["template-tag", "CATEGORY"]],
},
],
visualization_settings: getVisualSettingsWithClickBehavior(
questionId,
targetDashboardId,
),
},
],
});
visitDashboard(dashboardId);
});
});
},
);
popover().within(() => {
cy.findByText("Doohickey").click();
cy.findByText("Gadget").click();
cy.button("Add filter").click();
});
// Check click behavior connected to a question
cy.findAllByText("click-behavior-question-label")
.eq(0)
.click();
cy.url().should("include", "/question");
assertMultipleValuesFilterState();
// Go back to the dashboard
cy.go("back");
// Check click behavior connected to a dashboard
cy.findAllByText("click-behavior-dashboard-label")
.eq(0)
.click();
cy.url().should("include", "/dashboard");
cy.findByText(TARGET_DASHBOARD_NAME);
assertMultipleValuesFilterState();
});
it("should pass multiple filter values to a SQL question parameter (metabase#17160)", () => {
it("should pass multiple filter values to public questions and dashboards (metabase#17160-2)", () => {
setup(true);
cy.icon("share").click();
// Open the dashboard public link
cy.findByText("Public link")
.parent()
.within(() => {
cy.get("input").then(input => {
cy.visit(input.val());
});
});
cy.findByText("Category").click();
popover().within(() => {
......@@ -97,7 +75,7 @@ describe("issue 17160", () => {
.eq(0)
.click();
cy.url().should("include", "/question");
cy.url().should("include", "/public/question");
assertMultipleValuesFilterState();
......@@ -109,7 +87,7 @@ describe("issue 17160", () => {
.eq(0)
.click();
cy.url().should("include", "/dashboard");
cy.url().should("include", "/public/dashboard");
cy.findByText(TARGET_DASHBOARD_NAME);
assertMultipleValuesFilterState();
......@@ -127,11 +105,94 @@ function assertMultipleValuesFilterState() {
);
}
function getVisualSettingsWithClickBehavior(questionTarget, dashboardTarget) {
function setup(shouldUsePublicLinks) {
cy.createNativeQuestion({
name: `17160Q`,
native: {
query: "SELECT * FROM products WHERE {{CATEGORY}}",
"template-tags": {
CATEGORY: {
id: "6b8b10ef-0104-1047-1e1b-2492d5954322",
name: "CATEGORY",
display_name: "CATEGORY",
type: "dimension",
dimension: ["field", PRODUCTS.CATEGORY, null],
"widget-type": "category",
default: null,
},
},
},
}).then(({ body: { id: questionId } }) => {
// Share the question
cy.request("POST", `/api/card/${questionId}/public_link`);
cy.createDashboard({ name: "17160D" }).then(
({ body: { id: dashboardId } }) => {
// Share the dashboard
cy.request("POST", `/api/dashboard/${dashboardId}/public_link`);
// Add the question to the dashboard
cy.request("POST", `/api/dashboard/${dashboardId}/cards`, {
cardId: questionId,
}).then(({ body: { id: dashCardId } }) => {
// Add dashboard filter
cy.request("PUT", `/api/dashboard/${dashboardId}`, {
parameters: [
{
id: CATEGORY_FILTER_PARAMETER_ID,
name: "Category",
slug: "category",
sectionId: "string",
type: "string/=",
},
],
});
createTargetDashboardForClickBehavior().then(targetDashboardId => {
// Create a click behavior and resize the question card
cy.request("PUT", `/api/dashboard/${dashboardId}/cards`, {
cards: [
{
id: dashCardId,
card_id: questionId,
row: 0,
col: 0,
sizeX: 12,
sizeY: 10,
parameter_mappings: [
{
parameter_id: CATEGORY_FILTER_PARAMETER_ID,
card_id: 4,
target: ["dimension", ["template-tag", "CATEGORY"]],
},
],
visualization_settings: getVisualSettingsWithClickBehavior(
questionId,
targetDashboardId,
shouldUsePublicLinks,
),
},
],
});
visitDashboard(dashboardId);
});
});
},
);
});
}
function getVisualSettingsWithClickBehavior(
questionTarget,
dashboardTarget,
shouldUsePublicLinks = false,
) {
return {
column_settings: {
'["name","ID"]': {
click_behavior: {
use_public_link: shouldUsePublicLinks,
targetId: questionTarget,
parameterMapping: {
"6b8b10ef-0104-1047-1e1b-2492d5954322": {
......@@ -155,6 +216,7 @@ function getVisualSettingsWithClickBehavior(questionTarget, dashboardTarget) {
'["name","EAN"]': {
click_behavior: {
use_public_link: shouldUsePublicLinks,
targetId: dashboardTarget,
parameterMapping: {
dd19ec03: {
......@@ -192,6 +254,10 @@ function createTargetDashboardForClickBehavior() {
},
})
.then(({ body: { id, card_id, dashboard_id } }) => {
// Share the dashboard
cy.request("POST", `/api/dashboard/${dashboard_id}/public_link`);
// Add a filter
cy.request("PUT", `/api/dashboard/${dashboard_id}`, {
parameters: [
{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment