Skip to content
Snippets Groups Projects
Commit 95c057ad authored by Tom Robinson's avatar Tom Robinson
Browse files

Merge branch 'master' of github.com:metabase/metabase into table-columns-sync-and-add

parents 4f4ae029 8deb068a
No related branches found
No related tags found
No related merge requests found
Showing
with 215 additions and 186 deletions
......@@ -115,7 +115,7 @@ const AddUserRow = ({
onCancel={onCancel}
>
{selectedUsers.map(user => (
<div className="bg-slate-light p1 px2 mr1 rounded flex align-center">
<div className="bg-medium p1 px2 mr1 rounded flex align-center">
{user.common_name}
<Icon
className="pl1 cursor-pointer text-slate text-grey-4-hover"
......
......@@ -24,7 +24,7 @@ const ArchivedItem = ({
onToggleSelected,
showSelect,
}) => (
<div className="flex align-center p2 hover-parent hover--visibility border-bottom bg-grey-0-hover">
<div className="flex align-center p2 hover-parent hover--visibility border-bottom bg-light-hover">
<IconWrapper p={1} mr={1} align="center" justify="center">
<Swapper
startSwapped={showSelect}
......
......@@ -21,6 +21,9 @@ export const DatabaseListLoader = props => (
<EntityListLoader entityType="databases" {...props} />
);
const PAGE_PADDING = [1, 2, 4];
const ITEM_WIDTHS = [1, 1 / 2, 1 / 3];
const SchemaListLoader = ({ dbId, ...props }) => (
<EntityListLoader entityType="schemas" entityQuery={{ dbId }} {...props} />
);
......@@ -63,7 +66,7 @@ export class SchemaBrowser extends React.Component {
</Box>
<Grid>
{schemas.map(schema => (
<GridItem w={1 / 3}>
<GridItem w={ITEM_WIDTHS}>
<Link
to={`/browse/${dbId}/schema/${schema.name}`}
mb={1}
......@@ -121,7 +124,7 @@ export class TableBrowser extends React.Component {
}).getUrl();
return (
<GridItem w={1 / 3}>
<GridItem w={ITEM_WIDTHS}>
<Card
hoverable
px={1}
......@@ -183,7 +186,7 @@ export class TableBrowser extends React.Component {
export class BrowseApp extends React.Component {
render() {
return <Box mx={4}>{this.props.children}</Box>;
return <Box mx={PAGE_PADDING}>{this.props.children}</Box>;
}
}
......@@ -199,7 +202,7 @@ export class DatabaseBrowser extends React.Component {
return (
<Grid>
{databases.map(database => (
<GridItem>
<GridItem w={ITEM_WIDTHS}>
<Link to={`browse/${database.id}`}>
<Card p={3} hover={{ color: normal.blue }}>
<Icon name="database" color={normal.grey2} mb={3} />
......
import React from "react";
import { Flex } from "grid-styled";
import Ellipsified from "metabase/components/Ellipsified";
import Icon from "metabase/components/Icon";
import Link from "metabase/components/Link";
import colors, { normal } from "metabase/lib/colors";
const CollectionItem = ({ collection, color, iconName = "all" }) => (
<Link
to={`collection/${collection.id}`}
color={normal.grey2}
bg={colors["bg-medium"]}
className="block rounded"
hover={{
color: colors.primary,
backgroundColor: colors["bg-medium"],
}}
p={[1, 2]}
>
<Flex align="center" py={1} key={`collection-${collection.id}`}>
<Icon name={iconName} mx={1} />
<h4 className="overflow-hidden">
<Ellipsified>{collection.name}</Ellipsified>
</h4>
</Flex>
</Link>
);
export default CollectionItem;
......@@ -15,7 +15,7 @@ import Button from "metabase/components/Button";
import Card from "metabase/components/Card";
import Modal from "metabase/components/Modal";
import StackedCheckBox from "metabase/components/StackedCheckBox";
import EntityListItem from "metabase/components/EntityItem";
import EntityItem from "metabase/components/EntityItem";
import { Grid, GridItem } from "metabase/components/Grid";
import Icon from "metabase/components/Icon";
import Link from "metabase/components/Link";
......@@ -39,6 +39,7 @@ import PinDropTarget from "metabase/containers/dnd/PinDropTarget";
import ItemsDragLayer from "metabase/containers/dnd/ItemsDragLayer";
const ROW_HEIGHT = 72;
const PAGE_PADDING = [2, 3, 4];
import { entityListLoader } from "metabase/entities/containers/EntityListLoader";
......@@ -74,6 +75,7 @@ class DefaultLanding extends React.Component {
render() {
const {
ancestors,
collection,
collectionId,
......@@ -81,6 +83,7 @@ class DefaultLanding extends React.Component {
pinned,
unpinned,
isRoot,
selected,
selection,
onToggleSelected,
......@@ -97,17 +100,58 @@ class DefaultLanding extends React.Component {
onSelectNone();
};
const collectionWidth = unpinned.length > 0 ? 1 / 3 : 1;
const itemWidth = unpinned.length > 0 ? 2 / 3 : 0;
const collectionGridSize = unpinned.length > 0 ? 1 : 1 / 4;
const collectionWidth = unpinned.length > 0 ? [1, 1 / 3] : 1;
const itemWidth = unpinned.length > 0 ? [1, 2 / 3] : 0;
const collectionGridSize = unpinned.length > 0 ? 1 : [1, 1 / 4];
return (
<Box>
<Box>
<Flex
align="center"
pt={2}
pb={3}
px={4}
bg={pinned.length ? colors["bg-medium"] : null}
>
<Box>
<Box mb={1}>
<BrowserCrumbs
crumbs={[
...ancestors.map(({ id, name }) => ({
title: (
<CollectionDropTarget collection={{ id }} margin={8}>
{name}
</CollectionDropTarget>
),
to: Urls.collection(id),
})),
]}
/>
</Box>
<h1 style={{ fontWeight: 900 }}>{collection.name}</h1>
</Box>
<Flex ml="auto">
{collection &&
collection.can_write &&
!collection.personal_owner_id && (
<Box ml={1}>
<CollectionEditMenu
collectionId={collectionId}
isRoot={isRoot}
/>
</Box>
)}
<Box ml={1}>
<CollectionBurgerMenu />
</Box>
</Flex>
</Flex>
<Box>
<Box>
{pinned.length > 0 ? (
<Box mx={4} mt={2} mb={3}>
<Box px={PAGE_PADDING} pt={2} pb={3} bg={colors["bg-medium"]}>
<CollectionSectionHeading>{t`Pins`}</CollectionSectionHeading>
<PinDropTarget
pinIndex={pinned[pinned.length - 1].collection_position + 1}
......@@ -117,7 +161,11 @@ class DefaultLanding extends React.Component {
>
<Grid>
{pinned.map((item, index) => (
<GridItem w={1 / 3} className="relative">
<GridItem
w={[1, 1 / 3]}
className="relative"
key={index}
>
<ItemDragSource item={item}>
<PinnedItem
key={`${item.type}:${item.id}`}
......@@ -163,10 +211,10 @@ class DefaultLanding extends React.Component {
)}
</PinDropTarget>
)}
<Box pt={2} px={4} bg="white">
<Box pt={[1, 2]} px={[2, 4]}>
<Grid>
<GridItem w={collectionWidth}>
<Box pr={2}>
<Box pr={2} className="relative">
<Box py={2}>
<CollectionSectionHeading>
{t`Collections`}
......@@ -185,41 +233,43 @@ class DefaultLanding extends React.Component {
<PinDropTarget pinIndex={null} margin={8}>
<Box>
<ItemTypeFilterBar />
<Box
mb={selected.length > 0 ? 5 : 2}
style={{
position: "relative",
height: ROW_HEIGHT * unpinned.length,
}}
>
<VirtualizedList
items={
location.query.type
? unpinned.filter(
u => u.model === location.query.type,
)
: unpinned
}
rowHeight={ROW_HEIGHT}
renderItem={({ item, index }) => (
<ItemDragSource
item={item}
selection={selection}
>
<NormalItem
key={`${item.type}:${item.id}`}
<Card mt={1}>
<Box
mb={selected.length > 0 ? 5 : 2}
style={{
position: "relative",
height: ROW_HEIGHT * unpinned.length,
}}
>
<VirtualizedList
items={
location.query.type
? unpinned.filter(
u => u.model === location.query.type,
)
: unpinned
}
rowHeight={ROW_HEIGHT}
renderItem={({ item, index }) => (
<ItemDragSource
item={item}
collection={collection}
selection={selection}
onToggleSelected={onToggleSelected}
onMove={moveItems =>
this.setState({ moveItems })
}
/>
</ItemDragSource>
)}
/>
</Box>
>
<NormalItem
key={`${item.type}:${item.id}`}
item={item}
collection={collection}
selection={selection}
onToggleSelected={onToggleSelected}
onMove={moveItems =>
this.setState({ moveItems })
}
/>
</ItemDragSource>
)}
/>
</Box>
</Card>
</Box>
</PinDropTarget>
) : (
......@@ -308,8 +358,9 @@ export const NormalItem = ({
onToggleSelected,
onMove,
}) => (
<Link to={item.getUrl()} className="block">
<EntityListItem
<Link to={item.getUrl()} px={2}>
<EntityItem
variant="list"
showSelect={selection.size > 0}
selectable
item={item}
......@@ -413,55 +464,16 @@ class CollectionLanding extends React.Component {
return (
<Box>
<Box>
<Flex align="center" my={3} mx={4}>
<Box>
<Box mb={1}>
<BrowserCrumbs
crumbs={[
...ancestors.map(({ id, name }) => ({
title: (
<CollectionDropTarget collection={{ id }} margin={8}>
{name}
</CollectionDropTarget>
),
to: Urls.collection(id),
})),
]}
/>
</Box>
<h2 style={{ fontWeight: 900 }} className="pt1">
{currentCollection.name}
</h2>
</Box>
<Flex ml="auto">
{currentCollection &&
currentCollection.can_write &&
!currentCollection.personal_owner_id && (
<Box ml={1}>
<CollectionEditMenu
collectionId={collectionId}
isRoot={isRoot}
/>
</Box>
)}
<Box ml={1}>
<CollectionBurgerMenu />
</Box>
</Flex>
</Flex>
</Box>
<Box>
<DefaultLanding
collection={currentCollection}
collectionId={collectionId}
/>
{
// Need to have this here so the child modals will show up
this.props.children
}
</Box>
<DefaultLanding
isRoot={isRoot}
ancestors={ancestors}
collection={currentCollection}
collectionId={collectionId}
/>
{
// Need to have this here so the child modals will show up
this.props.children
}
</Box>
);
}
......
......@@ -3,10 +3,10 @@ import { t } from "c-3po";
import { Box, Flex } from "grid-styled";
import { connect } from "react-redux";
import colors, { normal } from "metabase/lib/colors";
import * as Urls from "metabase/lib/urls";
import Ellipsified from "metabase/components/Ellipsified";
import CollectionItem from "metabase/components/CollectionItem";
import { normal } from "metabase/lib/colors";
import { Grid, GridItem } from "metabase/components/Grid";
import Icon from "metabase/components/Icon";
import Link from "metabase/components/Link";
......@@ -14,23 +14,6 @@ import Link from "metabase/components/Link";
import CollectionDropTarget from "metabase/containers/dnd/CollectionDropTarget";
import ItemDragSource from "metabase/containers/dnd/ItemDragSource";
const CollectionItem = ({ collection, color, iconName = "all" }) => (
<Link
to={`collection/${collection.id}`}
color={color || normal.grey2}
className="text-brand-hover"
>
<Box bg={colors["bg-light"]} p={2}>
<Flex align="center" py={1} key={`collection-${collection.id}`}>
<Icon name={iconName} mx={1} />
<h4 className="overflow-hidden">
<Ellipsified>{collection.name}</Ellipsified>
</h4>
</Flex>
</Box>
</Link>
);
@connect(({ currentUser }) => ({ currentUser }), null)
class CollectionList extends React.Component {
render() {
......@@ -47,7 +30,7 @@ class CollectionList extends React.Component {
{collections
.filter(c => c.id !== currentUser.personal_collection_id)
.map(collection => (
<GridItem w={w}>
<GridItem w={w} key={collection.id}>
<CollectionDropTarget collection={collection}>
<ItemDragSource item={collection}>
<CollectionItem collection={collection} />
......
import React from "react";
import { t } from "c-3po";
import cx from "classnames";
import { Flex } from "grid-styled";
import { Box, Flex } from "grid-styled";
import EntityMenu from "metabase/components/EntityMenu";
import Swapper from "metabase/components/Swapper";
import IconWrapper from "metabase/components/IconWrapper";
......@@ -20,14 +21,6 @@ const EntityItemWrapper = Flex.extend`
}
`;
export const EntityListItem = props => <EntityItem {...props} />;
export const EntityCardItem = props => (
<Box my={1}>
<EntityItem {...props} />
</Box>
);
const EntityItem = ({
name,
iconName,
......@@ -40,6 +33,7 @@ const EntityItem = ({
selected,
onToggleSelected,
selectable,
variant,
}) => {
const actions = [
onPin && {
......@@ -59,8 +53,29 @@ const EntityItem = ({
},
].filter(action => action);
let spacing;
switch (variant) {
case "list":
spacing = {
px: 2,
py: 2,
};
break;
default:
spacing = {
py: 2,
};
break;
}
return (
<EntityItemWrapper py={2} className="hover-parent hover--visibility">
<EntityItemWrapper
{...spacing}
className={cx("hover-parent hover--visibility", {
"bg-light-hover": variant === "list",
})}
>
<IconWrapper
p={1}
mr={2}
......
......@@ -26,7 +26,7 @@ export default class ErrorDetails extends React.Component {
<h2>{t`Here's the full error message`}</h2>
<div
style={{ fontFamily: "monospace" }}
className="QueryError2-detailBody bordered rounded bg-grey-0 text-bold p2 mt1"
className="QueryError2-detailBody bordered rounded bg-light text-bold p2 mt1"
>
{/* ensure we don't try to render anything except a string */}
{typeof details === "string"
......
......@@ -158,7 +158,7 @@ export const ExploreList = ({
export const ExploreOption = ({ option }: { option: Candidate }) => (
<Link
to={option.url}
className="flex align-center text-bold no-decoration text-grey-5 text-brand-hover bg-grey-0 p2 py3"
className="flex align-center text-bold no-decoration text-grey-5 text-brand-hover bg-light p2 py3"
>
<Icon
name="bolt"
......
......@@ -14,7 +14,7 @@ GridItem.defaultProps = {
};
export const Grid = ({ children }) => (
<Flex wrap mx={-1}>
<Flex mx={-1} style={{ flexWrap: "wrap" }}>
{children}
</Flex>
);
......@@ -7,6 +7,7 @@ import { color, space, hover } from "styled-system";
import cx from "classnames";
import { loadIcon } from "metabase/icon_paths";
import { stripLayoutProps } from "metabase/lib/utils";
import Tooltipify from "metabase/hoc/Tooltipify";
......@@ -56,7 +57,7 @@ class BaseIcon extends Component {
return <svg {...props} dangerouslySetInnerHTML={{ __html: icon.svg }} />;
} else {
return (
<svg {...props}>
<svg {...stripLayoutProps(props)}>
<path d={icon.path} />
</svg>
);
......
......@@ -2,7 +2,7 @@ import { Flex } from "grid-styled";
import colors from "metabase/lib/colors";
const IconWrapper = Flex.extend`
background: ${props => colors["bg-light"]};
background: ${colors["bg-medium"]};
border-radius: 6px;
`;
......
......@@ -36,7 +36,7 @@ const ItemTypeFilterBar = props => {
return (
<Flex align="center" className="border-bottom mt1">
{props.filters.map(f => {
let isActive = location.query.type === f.filter;
let isActive = location && location.query.type === f.filter;
if (!location.query.type && !f.filter) {
isActive = true;
......@@ -54,6 +54,7 @@ const ItemTypeFilterBar = props => {
hover={{ color: colors.brand }}
className="flex-full flex align-center justify-center sm-block"
mr={[0, 2]}
key={f.filter}
py={1}
style={{
borderBottom: `2px solid ${
......
......@@ -2,9 +2,14 @@ import React from "react";
import { Link as ReactRouterLink } from "react-router";
import styled from "styled-components";
import { display, color, hover, space } from "styled-system";
import { stripLayoutProps } from "metabase/lib/utils";
const BaseLink = ({ to, className, children, ...props }) => (
<ReactRouterLink to={to} className={className || "link"} {...props}>
<ReactRouterLink
to={to}
className={className || "link"}
{...stripLayoutProps(props)}
>
{children}
</ReactRouterLink>
);
......
......@@ -11,7 +11,7 @@ const ToggleLarge = ({
textRight,
}) => (
<div
className={cx(className, "bg-grey-1 flex relative text-bold", {
className={cx(className, "bg-medium flex relative text-bold", {
"cursor-pointer": onChange,
})}
style={{ borderRadius: 8, ...style }}
......
......@@ -556,7 +556,7 @@ export default class TokenField extends Component {
<li
key={index}
className={cx(
`mt1 ml1 py1 pl2 rounded bg-grey-05`,
`mt1 ml1 py1 pl2 rounded bg-medium`,
multi ? "pr1" : "pr2",
)}
>
......@@ -612,9 +612,9 @@ export default class TokenField extends Component {
}
className={cx(
`py1 pl1 pr2 block rounded text-bold text-${color}-hover inline-block full cursor-pointer`,
`bg-grey-0-hover`,
`bg-light-hover`,
{
[`text-${color} bg-grey-0`]:
[`text-${color} bg-light`]:
!this.state.listIsHovered &&
this._valueIsEqual(
selectedOptionValue,
......
......@@ -185,7 +185,7 @@ export default class EntitySearch extends Component {
filteredEntities.length > 0;
return (
<div className="bg-slate-extra-light full Entity-search">
<div className="bg-light full Entity-search">
<div className="wrapper wrapper--small pt4 pb4">
<div className="flex mb4 align-center" style={{ height: "50px" }}>
<div
......@@ -449,7 +449,7 @@ export const SearchResultsGroup = ({
}) => (
<div>
{groupName !== null && (
<div className="flex align-center bg-slate-almost-extra-light bordered mt3 px3 py2">
<div className="flex align-center bg-medium bordered mt3 px3 py2">
<Icon
className="mr1"
style={{ color: colors["text-light"] }}
......@@ -497,8 +497,8 @@ class SearchResultsList extends Component {
<span
className={cx(
"mx1 flex align-center justify-center rounded",
{ "cursor-pointer bg-grey-2 text-white": !isInBeginning },
{ "bg-grey-0 text-grey-1": isInBeginning },
{ "cursor-pointer bg-medium text-white": !isInBeginning },
{ "bg-light text-grey-1": isInBeginning },
)}
style={{ width: "22px", height: "22px" }}
onClick={() =>
......@@ -510,8 +510,8 @@ class SearchResultsList extends Component {
<span
className={cx(
"flex align-center justify-center rounded",
{ "cursor-pointer bg-grey-2 text-white": !isInEnd },
{ "bg-grey-0 text-grey-2": isInEnd },
{ "cursor-pointer bg-medium text-white": !isInEnd },
{ "bg-light text-grey-2": isInEnd },
)}
style={{ width: "22px", height: "22px" }}
onClick={() => !isInEnd && setCurrentPage(entities, currentPage + 1)}
......@@ -587,8 +587,8 @@ export class SearchResultListItem extends Component {
<li>
<Link
className={cx(
"no-decoration flex py2 px3 cursor-pointer bg-slate-extra-light-hover border-bottom",
{ "bg-grey-0": highlight },
"no-decoration flex py2 px3 cursor-pointer bg-light-hover border-bottom",
{ "bg-light": highlight },
)}
to={getUrlForEntity(entity)}
>
......
......@@ -109,7 +109,10 @@ class Overworld extends React.Component {
<Grid>
{pinnedDashboards.map(pin => {
return (
<GridItem w={[1, 1 / 2, 1 / 3]}>
<GridItem
w={[1, 1 / 2, 1 / 3]}
key={`${pin.model}-${pin.id}`}
>
<Link
to={Urls.dashboard(pin.id)}
hover={{ color: normal.blue }}
......@@ -166,7 +169,7 @@ class Overworld extends React.Component {
return (
<Grid>
{databases.map(database => (
<GridItem w={[1, 1 / 3]}>
<GridItem w={[1, 1 / 3]} key={database.id}>
<Link
to={`browse/${database.id}`}
hover={{ color: normal.blue }}
......
......@@ -15,7 +15,7 @@ const DropTargetBackgroundAndBorder = ({
<div
className={cx("absolute rounded", {
"pointer-events-none": !highlighted,
"bg-slate-almost-extra-light": highlighted,
"bg-medium": highlighted,
})}
style={{
top: -marginTop,
......
......@@ -225,48 +225,24 @@
color: var(--color-text-medium);
}
.bg-grey-0,
.bg-grey-0-hover:hover {
background-color: var(--color-bg-light);
}
.bg-grey-05 {
background-color: var(--color-bg-medium);
}
.bg-grey-1 {
background-color: var(--color-bg-medium);
}
.bg-grey-2 {
background-color: var(--color-bg-medium);
}
.bg-grey-3 {
background-color: var(--color-bg-dark);
}
.bg-grey-4 {
background-color: var(--color-bg-dark);
}
.bg-grey-5 {
background-color: var(--color-bg-dark);
.text-dark,
:local(.text-dark) {
color: var(--color-text-dark);
}
.bg-slate {
background-color: var(--color-bg-dark);
}
.bg-slate-light {
background-color: var(--color-bg-medium);
}
.bg-slate-almost-extra-light {
background-color: var(--color-bg-medium);
}
.bg-slate-extra-light {
.bg-light,
.bg-light-hover:hover {
background-color: var(--color-bg-light);
}
.bg-slate-extra-light-hover:hover {
background-color: var(--color-bg-light);
.bg-medium,
.bg-medium-hover:hover {
background-color: var(--color-bg-medium);
}
.text-dark,
:local(.text-dark) {
color: var(--color-text-dark);
.bg-dark,
.bg-dark-hover:hover {
background-color: var(--color-bg-dark);
}
/* white - move to bottom for specificity since its often used on hovers, etc */
......
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