Skip to content

Commit

Permalink
Merge pull request #42 from metabase/master
Browse files Browse the repository at this point in the history
Fork Sync: Update from parent repository
  • Loading branch information
zaycev authored Dec 6, 2023
2 parents 3bf0ac7 + 19e1f98 commit 841ee2a
Show file tree
Hide file tree
Showing 113 changed files with 5,342 additions and 4,454 deletions.
3 changes: 2 additions & 1 deletion .clj-kondo/config.edn
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@
metabase.models.interface mi
metabase.models.moderation-review moderation-review
metabase.models.native-query-snippet native-query-snippet
metabase.models.params params
metabase.models.permissions perms
metabase.models.permissions-group perms-group
metabase.models.permissions-group-membership perms-group-membership
Expand All @@ -338,7 +339,7 @@
metabase.pulse.render.common common
metabase.pulse.render.style style
metabase.pulse.test-util pulse.test-util
metabase.pulse.parameters params
metabase.pulse.parameters pulse-params
metabase.query-processor-test qp.test
metabase.query-processor.context qp.context
metabase.query-processor.error-type qp.error-type
Expand Down
15 changes: 15 additions & 0 deletions .github/scripts/write-poms.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env bash

set -euo pipefail

function pom() {
path=$1
echo "Writing ${path}/pom.xml"
(cd "$path" && clojure -X:deps mvn-pom)
}

pom .

for k in $(ls modules/drivers/); do
test -d "modules/drivers/$k" && pom "modules/drivers/$k"
done
3 changes: 2 additions & 1 deletion .github/team.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"tsmacdonald",
"qnkhuat",
"calherries",
"piranha"
"piranha",
"levex"
]
},
{
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/backport.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ jobs:
id: branch_info
with:
script: |
await github.rest.reactions.createForIssueComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: context.payload.comment.id,
content: 'eyes',
});
// Example: @metabase-bot backport release-x.40.x
const [_botName, _command, targetBranch] = context.payload.comment.body.split(" ");
console.log(`Target branch is ${targetBranch}`);
Expand Down
7 changes: 6 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -596,10 +596,15 @@ jobs:
uses: actions/github-script@v6
with:
script: | # js
const { closeMilestone, openNextMilestones } = require('${{ github.workspace }}/release/dist/index.cjs');
const { closeMilestone, openNextMilestones, isRCVersion } = require('${{ github.workspace }}/release/dist/index.cjs');
const version = '${{ inputs.version }}';
if (isRCVersion(version)) {
console.log("This is a release candidate, skipping milestone management");
return;
}
await closeMilestone({
github,
owner: context.repo.owner,
Expand Down
38 changes: 38 additions & 0 deletions .github/workflows/snyk.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: "Snyk"

on:
push:
branches:
- 'master'
- 'release-**'
paths:
- '**/deps.edn'
- '**/package.json'
- '.github/workflows/snyk.yml'
- '.github/scripts/write-poms.xml'
schedule:
- cron: '0 5 * * *'


jobs:
monitor:
name: Generate Snyk report
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Prepare back-end environment
uses: ./.github/actions/prepare-backend
with:
m2-cache-key: 'snyk'
- uses: snyk/actions/[email protected]
- name: Generate all pom.xml
run: .github/scripts/write-poms.sh
- name: Run snyk
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
continue-on-error: true
run: snyk test --all-projects --sarif-file-output=snyk.sarif
- name: Upload result to GitHub Code Scanning
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: snyk.sarif
11 changes: 11 additions & 0 deletions docs/dashboards/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,17 @@ Click on the **pencil** icon to enter dashboard edit mode, hover over the questi

![Visualization settings](images/visualization-settings.png)

### Hiding a card when it doesn't return results

One neat thing to call out: if you have a question card that rarely returns results, but you still want to include it in your dashboard because you want to know when it _does_ return results, you can tell Metabase to hide the card unless it returns at least one row of data.

When in dashboard edit mode, click on the **Visualization settings** for the card.

- If the card displays a table, the option is in the **Columns** tab.
- If the card displays a chart, the option is in the **Display** tab.

Toggle the option **Hide this card if there are no results**. When you turn on this option, the query will still run in the background, but the dashboard won't display the card. If the query returns results, the dashboard will display the card, moving the other cards around to make room for it according to how you've arranged the cards in dashboard edit mode.

## Resetting a card's visualization settings

If you want to revert a dashboard card to its original visualization settings (i.e., the settings on the question when it was _first_ saved to your dashboard):
Expand Down
14 changes: 14 additions & 0 deletions e2e/support/helpers/e2e-embedding-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,17 @@ export function visitIframe() {
cy.visit(iframe.src);
});
}

/**
* Get page iframe body wrapped in `cy` helper
* @param {string} [selector]
*/
export function getIframeBody(selector = "iframe") {
return cy
.get(selector)
.its("0.contentDocument")
.should("exist")
.its("body")
.should("not.be.null")
.then(cy.wrap);
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,13 @@ describe("personal collections", () => {
});

cy.visit("/collection/root");
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.findByText("Your personal collection");
cy.findByRole("tree").findByText("Your personal collection");
navigationSidebar().within(() => {
cy.icon("ellipsis").click();
});
popover().findByText("Other users' personal collections").click();
cy.location("pathname").should("eq", "/collection/users");
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.findByText(/All personal collections/i);
cy.findByTestId("browsercrumbs").findByText(/All personal collections/i);
Object.values(USERS).forEach(user => {
const FULL_NAME = `${user.first_name} ${user.last_name}`;
cy.findByText(FULL_NAME);
Expand Down
75 changes: 75 additions & 0 deletions e2e/test/scenarios/dashboard-cards/click-behavior.cy.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { USER_GROUPS } from "e2e/support/cypress_data";
import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
import {
addOrUpdateDashboardCard,
dashboardHeader,
editDashboard,
getActionCardDetails,
getDashboardCard,
Expand Down Expand Up @@ -203,13 +204,27 @@ describe("scenarios > dashboard > dashboard cards > click behavior", () => {

saveDashboard();

cy.intercept(
"GET",
"/api/collection/root",
cy.spy().as("rootCollection"),
);
cy.intercept("GET", "/api/collection", cy.spy().as("collections"));

clickLineChartPoint();
cy.get("@targetDashboardId").then(targetDashboardId => {
cy.location().should(({ pathname, search }) => {
expect(pathname).to.equal(`/dashboard/${targetDashboardId}`);
expect(search).to.equal("");
});
});

cy.log("Should navigate to question using router (metabase#33379)");
dashboardHeader().findByText(TARGET_DASHBOARD.name).should("be.visible");
// If the page was reloaded, many API request would have been made and theses
// calls are 2 of those.
cy.get("@rootCollection").should("not.have.been.called");
cy.get("@collections").should("not.have.been.called");
});

it("allows setting dashboard with single parameter as custom destination", () => {
Expand Down Expand Up @@ -577,6 +592,13 @@ describe("scenarios > dashboard > dashboard cards > click behavior", () => {

saveDashboard();

cy.intercept(
"GET",
"/api/collection/root",
cy.spy().as("rootCollection"),
);
cy.intercept("GET", "/api/collection", cy.spy().as("collections"));

clickLineChartPoint();
cy.location().should(({ hash, pathname }) => {
expect(pathname).to.equal("/question");
Expand All @@ -586,6 +608,13 @@ describe("scenarios > dashboard > dashboard cards > click behavior", () => {
expect(card.dataset_query.query).to.deep.equal(TARGET_QUESTION.query);
});

cy.log("Should navigate to question using router (metabase#33379)");
cy.findByTestId("view-footer").should("contain", "Showing 5 rows");
// If the page was reloaded, many API request would have been made and theses
// calls are 2 of those.
cy.get("@rootCollection").should("not.have.been.called");
cy.get("@collections").should("not.have.been.called");

cy.go("back");
testChangingBackToDefaultBehavior();
});
Expand Down Expand Up @@ -1433,6 +1462,52 @@ describe("scenarios > dashboard > dashboard cards > click behavior", () => {
clickLineChartPoint();
});

it("allows opening custom URL destination that is not a Metabase instance URL using link (metabase#33379)", () => {
cy.request("PUT", "/api/setting/site-url", {
value: "https://localhost:4000/subpath",
});
const dashboardDetails = {
enable_embedding: true,
};

const metabaseInstanceUrl = "http://localhost:4000";
cy.createQuestionAndDashboard({
questionDetails,
dashboardDetails,
}).then(({ body: card }) => {
addOrUpdateDashboardCard({
dashboard_id: card.dashboard_id,
card_id: card.card_id,
card: {
id: card.id,
visualization_settings: {
click_behavior: {
type: "link",
linkType: "url",
linkTemplate: `${metabaseInstanceUrl}/404`,
},
},
},
});

visitEmbeddedPage({
resource: { dashboard: card.dashboard_id },
params: {},
});
cy.wait("@dashboard");
cy.wait("@cardQuery");
});

clickLineChartPoint();

cy.log(
"This is app 404 page, the embed 404 page will have different copy",
);
cy.findByRole("main")
.findByText("The page you asked for couldn't be found.")
.should("be.visible");
});

it("allows updating multiple dashboard filters", () => {
const dashboardDetails = {
parameters: [DASHBOARD_FILTER_TEXT, DASHBOARD_FILTER_TIME],
Expand Down
33 changes: 33 additions & 0 deletions e2e/test/scenarios/onboarding/search/search.cy.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
setActionsEnabledForDB,
setTokenFeatures,
summarize,
assertIsEllipsified,
} from "e2e/support/helpers";
import {
ADMIN_USER_ID,
Expand Down Expand Up @@ -174,6 +175,38 @@ describe("scenarios > search", () => {

cy.get("@search.all").should("have.length", 1);
});

it("should render a preview of markdown descriptions", () => {
cy.createQuestion({
name: "Description Test",
query: { "source-table": ORDERS_ID },
description: `![alt](https://upload.wikimedia.org/wikipedia/commons/a/a2/Cat_outside.jpg)
Lorem ipsum dolor sit amet.
----
## Heading 1
This is a [link](https://upload.wikimedia.org/wikipedia/commons/a/a2/Cat_outside.jpg).
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. `,
}).then(() => {
cy.signInAsNormalUser();
cy.visit("/");
getSearchBar().type("Test");
});

//Enseure that text is ellipsified
cy.findByTestId("result-description")
.findByText(/Lorem ipsum dolor sit amet./)
.then(el => assertIsEllipsified(el[0]));

//Ensure that images are not being rendered in the descriptions
cy.findByTestId("result-description")
.findByRole("img")
.should("not.exist");
});
});
describe("accessing full page search with `Enter`", () => {
it("should not render full page search if user has not entered a text query", () => {
Expand Down
12 changes: 0 additions & 12 deletions e2e/test/scenarios/onboarding/urls.cy.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,18 +106,6 @@ describe("URLs", () => {
cy.location("pathname").should("eq", "/collection/users");
});

it("should slugify users' personal collection URLs", () => {
cy.visit("/collection/users");
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.findByText(getFullName(normal)).click();
cy.location("pathname").should(
"eq",
`/collection/${NORMAL_PERSONAL_COLLECTION_ID}-${getUsersPersonalCollectionSlug(
normal,
)}`,
);
});

it("should open slugified URLs correctly", () => {
cy.visit(`/collection/${FIRST_COLLECTION_ID}-first-collection`);
cy.findByTestId("collection-name-heading").should(
Expand Down
Loading

0 comments on commit 841ee2a

Please sign in to comment.