Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvement/updating metabase to v0.38 #2

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion bin/i18n/src/i18n/common.clj
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

(defn- catalog ^Catalog [locale]
(let [parser (PoParser.)]
(.parseCatalog parser (io/file (locale-source-po-filename "es")))))
(.parseCatalog parser (io/file (locale-source-po-filename locale)))))

(defn po-headers [locale]
(when-let [^Message message (.locateHeader (catalog locale))]
Expand Down
3 changes: 3 additions & 0 deletions dev/src/dev.clj
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@

(comment debug-qp/keep-me)

(defn tap>-spy [x]
(doto x tap>))

(p/import-vars
[debug-qp process-query-debug])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
(:require [clojure.data :as diff]
[clojure.java.io :as io]
[clojure.test :refer [deftest is]]
[expectations :refer [expect]]
[metabase-enterprise.serialization.cmd :refer [dump load]]
[metabase-enterprise.serialization.test-util :as ts]
[metabase.models :refer [Card Collection Dashboard DashboardCard DashboardCardSeries Database Dependency Dimension Field FieldValues Metric Pulse PulseCard PulseChannel Segment Table User]]
[metabase.models :refer [Card Collection Dashboard DashboardCard DashboardCardSeries Database Dependency
Dimension Field FieldValues Metric Pulse PulseCard PulseChannel Segment Table User]]
[metabase.test.data.users :as test-users]
[metabase.util :as u]
[toucan.db :as db])
Expand Down
Original file line number Diff line number Diff line change
@@ -1,66 +1,39 @@
(ns metabase-enterprise.serialization.names-test
(:require [expectations :refer :all]
[metabase-enterprise.serialization.names :as names :refer :all]
(:require [clojure.test :refer :all]
[metabase-enterprise.serialization.names :as names]
[metabase-enterprise.serialization.test-util :as ts]
[metabase.models :refer [Card Collection Dashboard Database Field Metric Segment Table]]
[metabase.util :as u]))

(expect
(= (safe-name {:name "foo"}) "foo"))
(expect
(= (safe-name {:name "foo/bar baz"}) "foo%2Fbar baz"))

(expect
(= (unescape-name "foo") "foo"))
(expect
(= (unescape-name "foo%2Fbar baz") "foo/bar baz"))

(expect
(let [n "foo/bar baz"]
(= (-> {:name n} safe-name unescape-name (= n)))))

(defn- test-fully-qualified-name-roundtrip
[entity]
(let [context (fully-qualified-name->context (fully-qualified-name entity))]
(= (u/get-id entity) ((some-fn :field :metric :segment :card :dashboard :collection :table :database) context))))

(expect
(ts/with-world
(test-fully-qualified-name-roundtrip (Card card-id-root))))
(expect
(ts/with-world
(test-fully-qualified-name-roundtrip (Card card-id))))
(expect
(ts/with-world
(test-fully-qualified-name-roundtrip (Card card-id-nested))))

(expect
(ts/with-world
(test-fully-qualified-name-roundtrip (Table table-id))))

(expect
(ts/with-world
(test-fully-qualified-name-roundtrip (Field category-field-id))))

(expect
(ts/with-world
(test-fully-qualified-name-roundtrip (Metric metric-id))))

(expect
(ts/with-world
(test-fully-qualified-name-roundtrip (Segment segment-id))))

(expect
(ts/with-world
(test-fully-qualified-name-roundtrip (Collection collection-id))))
(expect
(ts/with-world
(test-fully-qualified-name-roundtrip (Collection collection-id-nested))))

(expect
(ts/with-world
(test-fully-qualified-name-roundtrip (Dashboard dashboard-id))))

(expect
(ts/with-world
(test-fully-qualified-name-roundtrip (Database db-id))))
(deftest safe-name-test
(are [s expected] (= (names/safe-name {:name s}) expected)
"foo" "foo"
"foo/bar baz" "foo%2Fbar baz"))

(deftest unescape-name-test
(are [s expected] (= expected
(names/unescape-name s))
"foo" "foo"
"foo%2Fbar baz" "foo/bar baz"))

(deftest safe-name-unescape-name-test
(is (= "foo/bar baz"
(-> {:name "foo/bar baz"} names/safe-name names/unescape-name))))

(deftest roundtrip-test
(ts/with-world
(doseq [object [(Card card-id-root)
(Card card-id)
(Card card-id-nested)
(Table table-id)
(Field category-field-id)
(Metric metric-id)
(Segment segment-id)
(Collection collection-id)
(Collection collection-id-nested)
(Dashboard dashboard-id)
(Database db-id)]]
(testing (class object)
(let [context (names/fully-qualified-name->context (names/fully-qualified-name object))]
(is (= (u/the-id object)
((some-fn :field :metric :segment :card :dashboard :collection :table :database) context))))))))
10 changes: 8 additions & 2 deletions frontend/src/metabase-lib/lib/Question.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ import * as Card_DEPRECATED from "metabase/lib/card";
import * as Urls from "metabase/lib/urls";
import { syncTableColumnsToQuery } from "metabase/lib/dataset";
import { getParametersWithExtras, isTransientId } from "metabase/meta/Card";
import { parameterToMBQLFilter } from "metabase/meta/Parameter";
import {
parameterToMBQLFilter,
mapUIParameterToQueryParameter,
} from "metabase/meta/Parameter";
import {
aggregate,
breakout,
Expand Down Expand Up @@ -823,7 +826,10 @@ export default class Question {
// include only parameters that have a value applied
.filter(param => _.has(param, "value"))
// only the superset of parameters object that API expects
.map(param => _.pick(param, "type", "target", "value"));
.map(param => _.pick(param, "type", "target", "value"))
.map(({ type, value, target }) => {
return mapUIParameterToQueryParameter(type, value, target);
});

if (canUseCardApiEndpoint) {
const queryParams = {
Expand Down
63 changes: 63 additions & 0 deletions frontend/src/metabase/components/CollapseSection.info.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React from "react";
import CollapseSection from "metabase/components/CollapseSection";
import Icon from "metabase/components/Icon";

export const component = CollapseSection;
export const category = "layout";
export const description = `
A collapsible section with a clickable header.
`;

export const examples = {
"Collapsed by default": (
<CollapseSection header="Section header">
foo foo foo foo foo foo foo foo
</CollapseSection>
),
"Settable collpased/expanded initial state": (
<CollapseSection initialState="expanded" header="Foo">
foo foo foo foo foo
</CollapseSection>
),
"Components in header": (
<CollapseSection
header={
<div>
<Icon className="mr1" name="folder" size={12} />
Component header
</div>
}
>
foo foo foo foo foo
</CollapseSection>
),
"Header and body classes": (
<CollapseSection
initialState="expanded"
header="Section header"
headerClass="text-brand flex-reverse justify-between p1 border-bottom"
bodyClass="p2"
>
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus neque
tellus, mattis ut felis non, tempus mollis lacus. Vivamus nulla massa,
accumsan non ligula eu, dapibus volutpat libero. Mauris sollicitudin
dolor et ipsum fringilla auctor. Praesent et diam non nisi consequat
ornare. Aenean et risus vel dolor maximus dapibus a id massa. Nam
finibus quis libero eu finibus. Sed vehicula ac enim pellentesque
luctus. Phasellus vehicula et ipsum porttitor mollis. Fusce blandit
lacus a elit pretium, vestibulum porta nisi vehicula. Aliquam vel ligula
enim. Orci varius natoque penatibus et magnis dis parturient montes,
nascetur ridiculus mus. Pellentesque eget porta mi. Duis et lectus eget
dolor convallis mollis. Sed commodo nec urna eget egestas.
<br />
<br />
Mauris in ante sit amet ipsum tempus consequat. Curabitur auctor massa
vitae dui auctor scelerisque. Donec in leo a libero commodo sodales.
Integer egestas lacinia elit, vitae cursus sem mollis ut. Proin ut
dapibus metus, vel accumsan justo. Pellentesque eget finibus elit, ut
commodo felis. Ut non lacinia metus. Maecenas eget bibendum nisl.
</div>
</CollapseSection>
),
};
70 changes: 70 additions & 0 deletions frontend/src/metabase/components/CollapseSection.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/* eslint "react/prop-types": 2 */

import React, { useState } from "react";
import PropTypes from "prop-types";
import cx from "classnames";

import Icon from "metabase/components/Icon";

function CollapseSection({
children,
className,
header,
headerClass,
bodyClass,
initialState = "collapsed",
}) {
const [isExpanded, setIsExpanded] = useState(initialState === "expanded");

return (
<div
className={cx(
"collapse-section",
isExpanded && "collapse-section--expanded",
className,
)}
role="tab"
aria-expanded={isExpanded}
>
<div
role="button"
tabIndex="0"
className={cx(
"collapse-section__header cursor-pointer flex align-center",
headerClass,
)}
onClick={() => setIsExpanded(isExpanded => !isExpanded)}
onKeyDown={e =>
e.key === "Enter" && setIsExpanded(isExpanded => !isExpanded)
}
>
<Icon
className="mr1"
name={isExpanded ? "chevrondown" : "chevronright"}
size={12}
/>
<span className="collapse-section__header-text flex align-center">
{header}
</span>
</div>
<div role="tabpanel" className="collapse-section__body-container">
{isExpanded && (
<div className={cx("collapse-section__body-container", bodyClass)}>
{children}
</div>
)}
</div>
</div>
);
}

CollapseSection.propTypes = {
children: PropTypes.node,
className: PropTypes.string,
header: PropTypes.node,
headerClass: PropTypes.string,
bodyClass: PropTypes.string,
initialState: PropTypes.oneOf(["expanded", "collapsed"]),
};

export default CollapseSection;
21 changes: 16 additions & 5 deletions frontend/src/metabase/dashboard/components/ParametersPopover.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import React, { Component } from "react";
import { t } from "ttag";
import { PARAMETER_SECTIONS } from "metabase/meta/Dashboard";
import Icon from "metabase/components/Icon";
import { getParameterIconName } from "metabase/meta/Parameter";
import styled from "styled-components";

import type {
Parameter,
Expand All @@ -11,6 +14,10 @@ import _ from "underscore";

import type { ParameterSection } from "metabase/meta/Dashboard";

const PopoverBody = styled.div`
max-width: 300px;
`;

export default class ParametersPopover extends Component {
props: {
onAddParameter: (option: ParameterOption) => Promise<Parameter>,
Expand Down Expand Up @@ -68,7 +75,11 @@ export const ParameterOptionsSection = ({
onClick: () => any,
}) => (
<li onClick={onClick} className="p1 px3 cursor-pointer brand-hover">
<div className="text-brand text-bold" style={{ marginBottom: 4 }}>
<div
className="text-brand text-bold flex align-center"
style={{ marginBottom: 4 }}
>
<Icon size="16" name={getParameterIconName(section.id)} className="mr1" />
{section.name}
</div>
<div className="text-medium">{section.description}</div>
Expand All @@ -82,7 +93,7 @@ export const ParameterOptionsSectionsPane = ({
sections: Array<ParameterSection>,
onSelectSection: ParameterSection => any,
}) => (
<div className="pb2">
<PopoverBody className="pb2">
<h3 className="pb2 pt3 px3">{t`What do you want to filter?`}</h3>
<ul>
{sections.map(section => (
Expand All @@ -92,7 +103,7 @@ export const ParameterOptionsSectionsPane = ({
/>
))}
</ul>
</div>
</PopoverBody>
);

export const ParameterOptionItem = ({
Expand All @@ -117,7 +128,7 @@ export const ParameterOptionsPane = ({
options: ?Array<ParameterOption>,
onSelectOption: ParameterOption => any,
}) => (
<div className="pb2">
<PopoverBody className="pb2">
<h3 className="pb2 pt3 px3">{t`What kind of filter?`}</h3>
<ul>
{options &&
Expand All @@ -128,5 +139,5 @@ export const ParameterOptionsPane = ({
/>
))}
</ul>
</div>
</PopoverBody>
);
12 changes: 12 additions & 0 deletions frontend/src/metabase/dashboard/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,3 +251,15 @@ export const makeGetParameterMappingOptions = () => {
);
return getParameterMappingOptions;
};

export const getDefaultParametersById = createSelector(
[getDashboard],
dashboard =>
((dashboard && dashboard.parameters) || []).reduce((map, parameter) => {
if (parameter.default) {
map[parameter.id] = parameter.default;
}

return map;
}, {}),
);
Loading