Skip to content

Commit

Permalink
Virtualize question list and misc cleanup / flow typing
Browse files Browse the repository at this point in the history
  • Loading branch information
tlrobinson committed Mar 23, 2018
1 parent 08bc82e commit 369b43e
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 169 deletions.
10 changes: 10 additions & 0 deletions frontend/src/metabase/meta/types/Label.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* @flow */

export type LabelId = number;

export type Label = {
id: LabelId,
name: string,
slug: string,
icon: string,
};
36 changes: 33 additions & 3 deletions frontend/src/metabase/questions/components/Item.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* @flow */
/* eslint "react/prop-types": "warn" */
import React from "react";
import PropTypes from "prop-types";
Expand All @@ -19,6 +20,35 @@ import * as Urls from "metabase/lib/urls";

const ITEM_ICON_SIZE = 20;

import type { Item as ItemType, Entity } from "../types";
import type { Collection } from "metabase/meta/types/Collection";
import type { Label } from "metabase/meta/types/Label";

type ItemProps = ItemType & {
showCollectionName: boolean,
setItemSelected: (selected: { [key: number]: boolean }) => void,
setFavorited: (id: number, favorited: boolean) => void,
setArchived: (id: number, archived: boolean, undoable: boolean) => void,
onEntityClick: (entity: Entity) => void,
};

type ItemBodyProps = {
entity: Entity,
id: number,
name: string,
description: string,
labels: Label[],
favorite: boolean,
collection: ?Collection,
setFavorited: (id: number, favorited: boolean) => void,
onEntityClick: (entity: Entity) => void,
};

type ItemCreatedProps = {
created: string,
by: string,
};

const Item = ({
entity,
id,
Expand All @@ -37,7 +67,7 @@ const Item = ({
setArchived,
showCollectionName,
onEntityClick,
}) => (
}: ItemProps) => (
<div className={cx("hover-parent hover--visibility", S.item)}>
<div className="flex flex-full align-center">
<div
Expand Down Expand Up @@ -148,7 +178,7 @@ const ItemBody = pure(
collection,
setFavorited,
onEntityClick,
}) => (
}: ItemBodyProps) => (
<div className={S.itemBody}>
<div className={cx("flex", S.itemTitle)}>
<Link
Expand Down Expand Up @@ -203,7 +233,7 @@ ItemBody.propTypes = {
};

const ItemCreated = pure(
({ created, by }) =>
({ created, by }: ItemCreatedProps) =>
created || by ? (
<div className={S.itemSubtitle}>
{t`Created` + (created ? ` ${created}` : ``) + (by ? t` by ${by}` : ``)}
Expand Down
9 changes: 8 additions & 1 deletion frontend/src/metabase/questions/components/Labels.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* @flow */
/* eslint "react/prop-types": "warn" */
import React, { Component } from "react";
import PropTypes from "prop-types";
Expand All @@ -10,7 +11,9 @@ import EmojiIcon from "metabase/components/EmojiIcon.jsx";

import cx from "classnames";

const Labels = ({ labels }) => (
import type { Label as LabelType } from "metabase/meta/types/Label";

const Labels = ({ labels }: { labels: LabelType[] }) => (
<ul className={S.list}>
{labels.map(label => (
<li className={S.listItem} key={label.id}>
Expand All @@ -25,6 +28,10 @@ Labels.propTypes = {
};

class Label extends Component {
props: LabelType;
state: {
hovered: boolean,
};
constructor(props) {
super(props);
this.state = {
Expand Down
107 changes: 95 additions & 12 deletions frontend/src/metabase/questions/components/List.jsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,105 @@
/* @flow */
/* eslint "react/prop-types": "warn" */
import React from "react";
import PropTypes from "prop-types";

import Item from "./Item";

import S from "./List.css";
import pure from "recompose/pure";

import EntityItem from "../containers/EntityItem.jsx";
import { List as VirtalizedList, WindowScroller } from "react-virtualized";
import "react-virtualized/styles.css";

const HORIZONTAL_PADDING = 32;
const ROW_HEIGHT = 87;

import type { Item as ItemType, Entity } from "../types";

type Props = {
items: ItemType[],

const List = ({ entityIds, ...props }) => (
<ul className={S.list}>
{entityIds.map(entityId => (
<EntityItem key={entityId} entityId={entityId} {...props} />
))}
</ul>
);
editable: boolean,
showCollectionName: boolean,

List.propTypes = {
entityIds: PropTypes.array.isRequired,
setItemSelected: (selected: { [key: number]: boolean }) => void,
setFavorited: (id: number, favorited: boolean) => void,
setArchived: (id: number, archived: boolean, undoable: boolean) => void,
onEntityClick: (entity: Entity) => void,
};

export default pure(List);
type ReactVirtualizedRowRendererProps = {
index: number,
key: string,
style: { [key: string]: any },
};

export default class List extends React.Component {
props: Props;

_list: ?React.Element<VirtalizedList>;

static propTypes = {
items: PropTypes.array.isRequired,

editable: PropTypes.bool,
showCollectionName: PropTypes.bool.isRequired,

setItemSelected: PropTypes.func.isRequired,
setFavorited: PropTypes.func.isRequired,
setArchived: PropTypes.func.isRequired,
onEntityClick: PropTypes.func,
};

renderRow = ({ index, key, style }: ReactVirtualizedRowRendererProps) => {
const {
editable,
setItemSelected,
setFavorited,
setArchived,
onEntityClick,
showCollectionName,
items,
} = this.props;
const item = items[index];
return (
<div
key={key}
style={{ ...style, display: item.visible ? undefined : "none" }}
>
<Item
setItemSelected={editable ? setItemSelected : null}
setFavorited={editable ? setFavorited : null}
setArchived={editable ? setArchived : null}
onEntityClick={onEntityClick}
showCollectionName={showCollectionName}
{...item}
/>
</div>
);
};

render() {
let { items } = this.props;

return (
<WindowScroller>
{({ height, width, isScrolling, registerChild, scrollTop }) => (
<div ref={registerChild}>
<VirtalizedList
ref={l => (this._list = l)}
className={S.list}
autoHeight
height={height}
isScrolling={isScrolling}
rowCount={items.length}
rowHeight={ROW_HEIGHT}
rowRenderer={this.renderRow}
scrollTop={scrollTop}
width={width - HORIZONTAL_PADDING * 2}
/>
</div>
)}
</WindowScroller>
);
}
}
69 changes: 0 additions & 69 deletions frontend/src/metabase/questions/containers/EntityItem.jsx

This file was deleted.

Loading

0 comments on commit 369b43e

Please sign in to comment.