diff --git a/.prettierrc b/.prettierrc
index f1ce769cc165c..bf357fbbc081d 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -1,3 +1,3 @@
{
- "trailing-comma": "all"
+ "trailingComma": "all"
}
diff --git a/frontend/src/metabase/components/CheckBox.jsx b/frontend/src/metabase/components/CheckBox.jsx
index 4a76ed419b485..b1ab71d20b52f 100644
--- a/frontend/src/metabase/components/CheckBox.jsx
+++ b/frontend/src/metabase/components/CheckBox.jsx
@@ -7,10 +7,12 @@ import { normal as defaultColors } from "metabase/lib/colors";
export default class CheckBox extends Component {
static propTypes = {
checked: PropTypes.bool,
+ indeterminate: PropTypes.bool,
onChange: PropTypes.func,
color: PropTypes.oneOf(Object.keys(defaultColors)),
size: PropTypes.number, // TODO - this should probably be a concrete set of options
padding: PropTypes.number, // TODO - the component should pad itself properly based on the size
+ noIcon: PropTypes.bool,
};
static defaultProps = {
@@ -31,15 +33,16 @@ export default class CheckBox extends Component {
}
render() {
- const { checked, color, padding, size } = this.props;
+ const { checked, indeterminate, color, padding, size, noIcon } = this.props;
- const themeColor = defaultColors[color];
+ const checkedColor = defaultColors[color];
+ const uncheckedColor = "#ddd";
const checkboxStyle = {
width: size,
height: size,
- backgroundColor: checked ? themeColor : "white",
- border: `2px solid ${checked ? themeColor : "#ddd"}`,
+ backgroundColor: checked ? checkedColor : "white",
+ border: `2px solid ${checked ? checkedColor : uncheckedColor}`,
};
return (
- {checked && (
-
- )}
+ {(checked || indeterminate) &&
+ !noIcon && (
+
+ )}
);
diff --git a/frontend/src/metabase/components/CollectionLanding.jsx b/frontend/src/metabase/components/CollectionLanding.jsx
index 45c26ba13a45f..0d7c8b8d9e4f8 100644
--- a/frontend/src/metabase/components/CollectionLanding.jsx
+++ b/frontend/src/metabase/components/CollectionLanding.jsx
@@ -104,7 +104,23 @@ const ROW_HEIGHT = 72;
entityQuery: (state, props) => ({ collection: props.collectionId }),
wrapped: true,
})
-@listSelect({ keyForItem: item => `${item.entity_type}:${item.id}` })
+@connect((state, props) => {
+ // split out collections, pinned, and unpinned since bulk actions only apply to unpinned
+ const [collections, items] = _.partition(
+ props.list || [],
+ item => item.entity_type === "collections",
+ );
+ const [pinned, unpinned] = _.partition(
+ items,
+ item => item.collection_position != null,
+ );
+ return { collections, pinned, unpinned };
+})
+// only apply bulk actions to unpinned items
+@listSelect({
+ listProp: "unpinned",
+ keyForItem: item => `${item.entity_type}:${item.id}`,
+})
class DefaultLanding extends React.Component {
state = {
moveItems: null,
@@ -113,9 +129,12 @@ class DefaultLanding extends React.Component {
render() {
const {
collectionId,
- list,
- onToggleSelected,
+ collections,
+ pinned,
+ unpinned,
+ selected,
selection,
+ onToggleSelected,
onSelectNone,
} = this.props;
const { moveItems } = this.state;
@@ -128,16 +147,6 @@ class DefaultLanding extends React.Component {
onSelectNone();
};
- // exclude collections from selection since they can't currently be selected
- const selected = this.props.selected.filter(
- item => item.model !== "collection",
- );
-
- const [collections, items] = _.partition(
- list,
- item => item.entity_type === "collections",
- );
-
// Show the
const showCollectionList =
collectionId === "root" || collections.length > 0;
@@ -159,15 +168,10 @@ class DefaultLanding extends React.Component {
{({ object: collection }) => {
- if (items.length === 0) {
+ if (pinned.length === 0 && unpinned.length === 0) {
return ;
}
- const [pinned, unpinned] = _.partition(
- items,
- i => i.collection_position != null,
- );
-
// sort the pinned items by collection_position
pinned.sort(
(a, b) => a.collection_position - b.collection_position,
@@ -587,7 +591,6 @@ const PINNABLE_ENTITY_TYPES = new Set(["questions", "dashboards"]);
class PinPositionDropTarget extends React.Component {
render() {
const {
- index,
left,
right,
connectDropTarget,
@@ -750,9 +753,11 @@ const SelectionControls = ({
onSelectNone,
}) =>
deselected.length === 0 ? (
-
+
+ ) : selected.length === 0 ? (
+
) : (
-
+
);
// TODO - this should be a selector
diff --git a/frontend/src/metabase/components/StackedCheckBox.jsx b/frontend/src/metabase/components/StackedCheckBox.jsx
index f265e6af62907..c7549d230a139 100644
--- a/frontend/src/metabase/components/StackedCheckBox.jsx
+++ b/frontend/src/metabase/components/StackedCheckBox.jsx
@@ -13,7 +13,7 @@ const StackedCheckBox = props => (
zIndex: -1,
}}
>
-
+
diff --git a/frontend/src/metabase/icon_paths.js b/frontend/src/metabase/icon_paths.js
index 7ca1ed6511783..d3b5c6d8b0df3 100644
--- a/frontend/src/metabase/icon_paths.js
+++ b/frontend/src/metabase/icon_paths.js
@@ -110,6 +110,7 @@ export const ICON_PATHS = {
"M27,19 C25.3431458,19 24,17.6568542 24,16 C24,14.3431458 25.3431458,13 27,13 C28.6568542,13 30,14.3431458 30,16 C30,17.6568542 28.6568542,19 27,19 Z M16,8 C14.3431458,8 13,6.65685425 13,5 C13,3.34314575 14.3431458,2 16,2 C17.6568542,2 19,3.34314575 19,5 C19,6.65685425 17.6568542,8 16,8 Z M16,30 C14.3431458,30 13,28.6568542 13,27 C13,25.3431458 14.3431458,24 16,24 C17.6568542,24 19,25.3431458 19,27 C19,28.6568542 17.6568542,30 16,30 Z M5,19 C3.34314575,19 2,17.6568542 2,16 C2,14.3431458 3.34314575,13 5,13 C6.65685425,13 8,14.3431458 8,16 C8,17.6568542 6.65685425,19 5,19 Z M16,19 C14.3431458,19 13,17.6568542 13,16 C13,14.3431458 14.3431458,13 16,13 C17.6568542,13 19,14.3431458 19,16 C19,17.6568542 17.6568542,19 16,19 Z M10,12 C8.8954305,12 8,11.1045695 8,10 C8,8.8954305 8.8954305,8 10,8 C11.1045695,8 12,8.8954305 12,10 C12,11.1045695 11.1045695,12 10,12 Z M22,12 C20.8954305,12 20,11.1045695 20,10 C20,8.8954305 20.8954305,8 22,8 C23.1045695,8 24,8.8954305 24,10 C24,11.1045695 23.1045695,12 22,12 Z M22,24 C20.8954305,24 20,23.1045695 20,22 C20,20.8954305 20.8954305,20 22,20 C23.1045695,20 24,20.8954305 24,22 C24,23.1045695 23.1045695,24 22,24 Z M10,24 C8.8954305,24 8,23.1045695 8,22 C8,20.8954305 8.8954305,20 10,20 C11.1045695,20 12,20.8954305 12,22 C12,23.1045695 11.1045695,24 10,24 Z",
database:
"M1.18285296e-08,10.5127919 C-1.47856568e-08,7.95412848 1.18285298e-08,4.57337284 1.18285298e-08,4.57337284 C1.18285298e-08,4.57337284 1.58371041,5.75351864e-10 15.6571342,0 C29.730558,-5.7535027e-10 31.8900148,4.13849684 31.8900148,4.57337284 L31.8900148,10.4843058 C31.8900148,10.4843058 30.4448001,15.1365942 16.4659751,15.1365944 C2.48715012,15.1365947 2.14244494e-08,11.4353349 1.18285296e-08,10.5127919 Z M0.305419478,21.1290071 C0.305419478,21.1290071 0.0405133833,21.2033291 0.0405133833,21.8492606 L0.0405133833,27.3032816 C0.0405133833,27.3032816 1.46515486,31.941655 15.9641228,31.941655 C30.4630908,31.941655 32,27.3446712 32,27.3446712 C32,27.3446712 32,21.7986104 32,21.7986105 C32,21.2073557 31.6620557,21.0987647 31.6620557,21.0987647 C31.6620557,21.0987647 29.7146434,25.22314 16.0318829,25.22314 C2.34912233,25.22314 0.305419478,21.1290071 0.305419478,21.1290071 Z M0.305419478,12.656577 C0.305419478,12.656577 0.0405133833,12.730899 0.0405133833,13.3768305 L0.0405133833,18.8308514 C0.0405133833,18.8308514 1.46515486,23.4692249 15.9641228,23.4692249 C30.4630908,23.4692249 32,18.8722411 32,18.8722411 C32,18.8722411 32,13.3261803 32,13.3261803 C32,12.7349256 31.6620557,12.6263346 31.6620557,12.6263346 C31.6620557,12.6263346 29.7146434,16.7507099 16.0318829,16.7507099 C2.34912233,16.7507099 0.305419478,12.656577 0.305419478,12.656577 Z",
+ dash: "M0 13h32v6.61H0z",
dashboard:
"M32 28a4 4 0 0 1-4 4H4a4.002 4.002 0 0 1-3.874-3H0V4a4 4 0 0 1 4-4h25a3 3 0 0 1 3 3v25zm-4 0V8H4v20h24zM7.273 18.91h10.182v4.363H7.273v-4.364zm0-6.82h17.454v4.365H7.273V12.09zm13.09 6.82h4.364v4.363h-4.363v-4.364z",
curve: