Merge pull request #2 from AntlerEngineering/tables

Tables
This commit is contained in:
shamsmosowi
2019-09-13 10:59:34 +10:00
committed by GitHub
14 changed files with 501 additions and 100 deletions

View File

@@ -4,45 +4,47 @@
### Initial fields:
- checkbox(boolean)
- simple text(string)
- email(string)
- phone(string)
- url(string)
- Number(number)
- checkbox(boolean)
- simple text(string)
- email(string)
- phone(string)
- url(string)
- Number(number)
- long text(string)
### Functionality:
- Create Tables (Primary collections)
- Create columns (fields)
- Create rows(documents)
- Create Tables (Primary collections)
- Create columns (fields)
- Create rows(documents)
- Edit cells ✅
- Authenicate ✅
- Delete rows ✅
## MVP
### additional fields:
- tags(array of strings)
- single select(string)
- [https://material-ui.com/components/chips/#chip-array] Multiple select(array of strings)
- date(Firebase timestamp)
- time(Firebase timestamp)
- index(number)
- file(firebase storage url string)
- [https://material-ui.com/components/chips/#chip-array]Multiple select(array of strings)
- image(firebase storage url string)
- reference(DocRefrence)
- [https://material-ui.com/components/rating/]rating(number)
- single select reference(DocRefrence)
- mulit select reference(DocRefrence)
- [https://material-ui.com/components/rating/] rating(number)
### Functionality:
- Hide/show columns
- Delete columns
- Delete rows
- Edit columns
- Delete tables
- Filters:
- equals to
- Starts with
- contains
- Edit tables
- Hide tables
- Fixed column
- keyboard Navigation: ability to use tab and arrow keys to move focus between cells
## V1
@@ -60,3 +62,18 @@
- Subcollection tables
- Permissions
- Duplicate columns
- Filters:
- equals to
- Starts with
- contains
- Export tables to csv
# V+
### Additional Fields:
- index(number)
### Functionality:
- import csv to table

View File

@@ -3,9 +3,11 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@date-io/date-fns": "^1.3.11",
"@material-ui/core": "^4.4.0",
"@material-ui/icons": "^4.4.1",
"@material-ui/lab": "^4.0.0-alpha.26",
"@material-ui/pickers": "^3.2.5",
"@types/jest": "24.0.18",
"@types/lodash": "^4.14.138",
"@types/node": "12.7.4",
@@ -16,6 +18,7 @@
"@types/react-sortable-hoc": "^0.6.5",
"@types/react-virtualized": "^9.21.4",
"array-move": "^2.1.0",
"date-fns": "^2.0.0-beta.5",
"firebase": "^6.6.0",
"lodash": "^4.17.15",
"ramda": "^0.26.1",

View File

@@ -4,6 +4,7 @@ import { createMuiTheme } from "@material-ui/core";
import AuthView from "./views/AuthView";
import TableView from "./views/TableView";
import TablesView from "./views/TablesView";
import { BrowserRouter as Router, Route } from "react-router-dom";
import { AuthProvider } from "./AuthProvider";
@@ -26,6 +27,7 @@ const App: React.FC = () => {
<CustomBrowserRouter>
<div>
<Route exact path="/auth" component={AuthView} />
<PrivateRoute exact path="/" component={TablesView} />
<PrivateRoute path="/table/" component={TableView} />
</div>
</CustomBrowserRouter>

View File

@@ -4,6 +4,11 @@ import CheckBoxIcon from "@material-ui/icons/CheckBox";
import SimpleTextIcon from "@material-ui/icons/TextFormat";
import LongTextIcon from "@material-ui/icons/Notes";
import PhoneIcon from "@material-ui/icons/Phone";
import DateIcon from "@material-ui/icons/CalendarToday";
import TimeIcon from "@material-ui/icons/AccessTime";
import RatingIcon from "@material-ui/icons/StarHalf";
import URLIcon from "@material-ui/icons/Explore";
import NumberIcon from "@material-ui/icons/Looks3";
import propEq from "ramda/es/propEq";
import find from "ramda/es/find";
export enum FieldType {
@@ -11,7 +16,13 @@ export enum FieldType {
longText = "LONG_TEXT",
email = "EMAIL",
PhoneNumber = "PHONE_NUMBER",
checkBox = "CHECK_BOX"
checkBox = "CHECK_BOX",
date = "DATE",
time = "TIME",
dateTime = "DATE_TIME",
number = "NUMBER",
url = "URL",
rating = "RATING"
}
export const FIELDS = [
@@ -19,7 +30,12 @@ export const FIELDS = [
{ icon: <LongTextIcon />, name: "Long Text", type: FieldType.longText },
{ icon: <MailIcon />, name: "Email", type: FieldType.email },
{ icon: <PhoneIcon />, name: "Phone", type: FieldType.PhoneNumber },
{ icon: <CheckBoxIcon />, name: "Check Box", type: FieldType.checkBox }
{ icon: <CheckBoxIcon />, name: "Check Box", type: FieldType.checkBox },
{ icon: <NumberIcon />, name: "Number", type: FieldType.number },
{ icon: <DateIcon />, name: "Date", type: FieldType.date },
{ icon: <TimeIcon />, name: "Time", type: FieldType.time },
{ icon: <URLIcon />, name: "URL", type: FieldType.url },
{ icon: <RatingIcon />, name: "Rating", type: FieldType.rating }
];
export const getFieldIcon = (type: FieldType) => {

View File

@@ -51,7 +51,7 @@ const useStyles = makeStyles((theme: Theme) =>
})
);
export const Navigation = (props: any) => {
const Navigation = (props: any) => {
const router = useRouter();
const classes = useStyles();
const [settings, createTable] = useSettings();
@@ -121,3 +121,4 @@ export const Navigation = (props: any) => {
</React.Fragment>
);
};
export default Navigation;

View File

@@ -6,7 +6,7 @@ import {
withStyles,
WithStyles
} from "@material-ui/core/styles";
import TableCell from "@material-ui/core/TableCell";
import { TableCell as MuiTableCell } from "@material-ui/core";
import Paper from "@material-ui/core/Paper";
import {
AutoSizer,
@@ -17,11 +17,11 @@ import {
} from "react-virtualized";
import Button from "@material-ui/core/Button";
// import { TextField } from "@material-ui/core";
import { FieldType, getFieldIcon } from "../Fields";
import ColumnDrawer from "./ColumnDrawer";
import IconButton from "@material-ui/core/IconButton";
import DeleteIcon from "@material-ui/icons/Delete";
import TableCell from "../components/TableCell";
import useCell, { Cell } from "../hooks/useCell";
const styles = (theme: Theme) =>
createStyles({
flexContainer: {
@@ -59,6 +59,8 @@ interface Row {
interface MuiVirtualizedTableProps extends WithStyles<typeof styles> {
columns: ColumnData[];
focusedCell: Cell | null;
cellActions: any;
headerHeight?: number;
onRowClick?: () => void;
rowCount: number;
@@ -91,42 +93,32 @@ class MuiVirtualizedTable extends React.PureComponent<
rowData,
rowIndex
}) => {
const { columns, classes, rowHeight, onRowClick } = this.props;
const {
columns,
classes,
rowHeight,
onRowClick,
cellActions,
focusedCell
} = this.props;
const fieldType = columnData.fieldType;
if (fieldType === "DELETE")
return (
<IconButton
aria-label="delete"
onClick={() => {
columnData.actions.deleteRow(rowIndex, rowData.id);
}}
>
<DeleteIcon />
</IconButton>
);
return (
<TableCell
component="div"
className={clsx(classes.tableCell, classes.flexContainer, {
[classes.noClick]: onRowClick == null
})}
variant="body"
onClick={() => {
console.log(rowIndex, rowData.id, columnData.fieldName);
}}
style={{ height: rowHeight }}
align={
(columnIndex != null && columns[columnIndex].numeric) || false
? "right"
: "left"
}
>
{cellData} {}
</TableCell>
fieldType={fieldType}
rowIndex={rowIndex}
rowData={rowData}
columnData={columnData}
classes={classes}
cellActions={cellActions}
cellData={cellData}
onRowClick={onRowClick}
rowHeight={rowHeight}
columnIndex={columnIndex}
columns={columns}
focusedCell={focusedCell}
/>
);
};
headerRenderer = ({
label,
columnData,
@@ -136,7 +128,7 @@ class MuiVirtualizedTable extends React.PureComponent<
const { headerHeight, columns, classes } = this.props;
return (
<TableCell
<MuiTableCell
component="div"
className={clsx(
classes.tableCell,
@@ -154,7 +146,7 @@ class MuiVirtualizedTable extends React.PureComponent<
{getFieldIcon(columnData.fieldType)} {label}
</Button>
)}
</TableCell>
</MuiTableCell>
);
};
@@ -169,34 +161,36 @@ class MuiVirtualizedTable extends React.PureComponent<
return (
<AutoSizer>
{({ height, width }) => (
<MuiTable
height={height}
width={width}
rowHeight={rowHeight!}
headerHeight={headerHeight!}
{...tableProps}
rowClassName={this.getRowClassName}
>
{[
...columns.map(({ dataKey, ...other }, index) => {
return (
<Column
key={dataKey}
headerRenderer={headerProps =>
this.headerRenderer({
...headerProps,
columnIndex: index
})
}
className={classes.flexContainer}
cellRenderer={this.cellRenderer}
dataKey={dataKey}
{...other}
/>
);
})
]}
</MuiTable>
<>
<MuiTable
height={height}
width={width}
rowHeight={rowHeight!}
headerHeight={headerHeight!}
{...tableProps}
rowClassName={this.getRowClassName}
>
{[
...columns.map(({ dataKey, ...other }, index) => {
return (
<Column
key={dataKey}
headerRenderer={headerProps =>
this.headerRenderer({
...headerProps,
columnIndex: index
})
}
className={classes.flexContainer}
cellRenderer={this.cellRenderer}
dataKey={dataKey}
{...other}
/>
);
})
]}
</MuiTable>
</>
)}
</AutoSizer>
);
@@ -206,12 +200,15 @@ class MuiVirtualizedTable extends React.PureComponent<
const VirtualizedTable = withStyles(styles)(MuiVirtualizedTable);
export default function Table(props: any) {
const { columns, rows, addColumn, deleteRow } = props;
const [focus, setFocus] = useState(false);
const { columns, rows, addColumn, tableActions } = props;
const [cell, cellActions] = useCell({ updateCell: tableActions.updateCell });
if (columns)
return (
<Paper style={{ height: 400, width: "100%" }}>
<VirtualizedTable
focusedCell={cell}
cellActions={cellActions}
rowCount={rows.length}
rowGetter={({ index }) => rows[index]}
columns={[
@@ -237,7 +234,10 @@ export default function Table(props: any) {
dataKey: "add",
columnData: {
fieldType: "DELETE",
actions: { addColumn, deleteRow }
actions: {
addColumn: addColumn,
deleteRow: tableActions.deleteRow
}
}
}
]}

View File

@@ -0,0 +1,157 @@
import React, { useState } from "react";
import { TableCell as MuiTableCell, Switch } from "@material-ui/core";
import clsx from "clsx";
import { FieldType } from "../Fields";
import {
createStyles,
Theme,
withStyles,
WithStyles
} from "@material-ui/core/styles";
import Rating from "@material-ui/lab/Rating";
import IconButton from "@material-ui/core/IconButton";
import DeleteIcon from "@material-ui/icons/Delete";
import AddIcon from "@material-ui/icons/AddCircle";
import Checkbox, { CheckboxProps } from "@material-ui/core/Checkbox";
import TextField from "@material-ui/core/TextField";
import CheckBoxIcon from "@material-ui/icons/CheckBox";
import CheckBoxOutlineIcon from "@material-ui/icons/CheckBoxOutlineBlank";
import DateFnsUtils from "@date-io/date-fns";
import {
MuiPickersUtilsProvider,
KeyboardTimePicker,
KeyboardDatePicker
} from "@material-ui/pickers";
const TableCell = (props: any) => {
const {
fieldType,
rowIndex,
rowData,
columnData,
classes,
cellActions,
cellData,
onRowClick,
rowHeight,
columnIndex,
columns,
focusedCell
} = props;
const [state, setState] = useState(cellData);
const inputRenderer = () => {
switch (fieldType) {
case FieldType.checkBox:
return (
<Checkbox
checked={state}
onChange={e => {
setState(!state);
cellActions.updateValue(!state);
}}
/>
);
case FieldType.number:
return (
<TextField
id="number"
defaultValue={cellData}
onChange={e => {
cellActions.updateValue(e.target.value);
}}
type="number"
className={classes.textField}
InputLabelProps={{
shrink: true
}}
margin="normal"
/>
);
case FieldType.date:
return (
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<KeyboardDatePicker
autoFocus
margin="normal"
id="date-picker-dialog"
label="Date picker dialog"
format="MM/dd/yyyy"
value={new Date("2014-08-18T21:11:54")}
onChange={date => {
console.log(date);
//cellActions.updateValue(e.target.value);
}}
KeyboardButtonProps={{
"aria-label": "change date"
}}
/>
</MuiPickersUtilsProvider>
);
case FieldType.rating:
return <Rating name="pristine" value={null} />;
default:
return (
<TextField
autoFocus
defaultValue={cellData}
onChange={e => {
cellActions.updateValue(e.target.value);
}}
/>
);
}
};
const valueRenderer = () => {
switch (fieldType) {
case FieldType.checkBox:
return cellData === true ? <CheckBoxIcon /> : <CheckBoxOutlineIcon />;
default:
return cellData;
break;
}
};
if (fieldType === "DELETE")
return (
<IconButton
aria-label="delete"
onClick={() => {
columnData.actions.deleteRow(rowIndex, rowData.id);
}}
>
<DeleteIcon />
</IconButton>
);
return (
<MuiTableCell
component="div"
className={clsx(classes.tableCell, classes.flexContainer, {
[classes.noClick]: onRowClick == null
})}
variant="body"
onClick={() => {
cellActions.setCell({
rowIndex,
docId: rowData.id,
fieldName: columnData.fieldName,
value: cellData
});
}}
style={{ height: rowHeight }}
align={
(columnIndex != null && columns[columnIndex].numeric) || false
? "right"
: "left"
}
>
{focusedCell &&
focusedCell.fieldName === columnData.fieldName &&
focusedCell.rowIndex === rowIndex
? inputRenderer()
: valueRenderer()}
</MuiTableCell>
);
};
export default TableCell;

50
src/hooks/useCell.ts Normal file
View File

@@ -0,0 +1,50 @@
import { db } from "../firebase";
import { useEffect, useReducer } from "react";
import equals from "ramda/es/equals";
export type Cell = {
fieldName: string;
rowIndex: number;
docId: string;
value: any;
};
const cellReducer = (prevState: any, newProps: any) => {
return { ...prevState, ...newProps };
};
const cellIntialState = {
prevCell: null,
cell: null
};
const useCell = (intialOverrides: any) => {
const [cellState, cellDispatch] = useReducer(cellReducer, {
...cellIntialState,
...intialOverrides
});
useEffect(() => {
const { prevCell, value, updateCell, updatedValue } = cellState;
// check for change
if (
updatedValue !== null &&
updatedValue !== undefined &&
prevCell &&
prevCell.value !== updatedValue
) {
updateCell({ ...prevCell, value: updatedValue });
cellDispatch({ updatedValue: null });
}
}, [cellState.cell]);
const setCell = (cell: Cell) => {
cellDispatch({ prevCell: cellState.cell, cell });
};
const updateValue = (value: any) => {
cellDispatch({ updatedValue: value });
};
const actions = { setCell, updateValue };
return [cellState.cell, actions];
};
export default useCell;

21
src/hooks/useFiretable.ts Normal file
View File

@@ -0,0 +1,21 @@
//TODO: consolidate useTable, useTableConfig, useCell into useFiretable
import { useEffect } from "react";
import useTable from "./useTable";
import useTableConfig from "./useTable";
import useCell from "./useCell";
const useFiretable = (collectionName: string) => {
const [tableConfig, configActions] = useTableConfig(collectionName);
const [table, tableActions] = useTable({
path: collectionName
});
const setTable = (collectionName: string) => {
configActions.setTable(collectionName);
tableActions.setTable(collectionName);
};
const actions = { setTable: tableActions.setTable };
return [table, actions];
};
export default useFiretable;

View File

@@ -1,6 +1,9 @@
import { db } from "../firebase";
import { useEffect, useReducer } from "react";
import equals from "ramda/es/equals";
import { Cell } from "./useCell";
import firebase from "firebase/app";
const CAP = 500;
const tableReducer = (prevState: any, newProps: any) => {
@@ -27,6 +30,7 @@ const tableIntialState = {
prevLimit: 0,
limit: 20,
loading: true,
sort: { field: "createdAt", direction: "asc" },
cap: CAP
};
@@ -131,8 +135,23 @@ const useTable = (intialOverrides: any) => {
const setTable = (tableCollection: string) => {
tableDispatch({ path: tableCollection });
};
const updateCell = (cell: Cell) => {
console.log("updateCell:", cell);
// TODO: update row locally
// tableState.rows[cell.rowIndex][cell.fieldName] = cell.value;
// tableDispatch({ rows: tableState.rows });
const tableActions = { deleteRow, setTable };
// update document
db.collection(tableState.path)
.doc(cell.docId)
.update({ [cell.fieldName]: cell.value });
};
const addRow = () => {
db.collection(tableState.path).add({
createdAt: firebase.firestore.FieldValue.serverTimestamp()
});
};
const tableActions = { deleteRow, setTable, updateCell, addRow };
return [tableState, tableActions];
};

View File

@@ -7,6 +7,7 @@ import Button from "@material-ui/core/Button";
import Typography from "@material-ui/core/Typography";
import { maxWidth } from "@material-ui/system";
import { googleProvider, auth } from "../firebase";
import useRouter from "../hooks/useRouter";
const useStyles = makeStyles({
card: {
@@ -22,13 +23,15 @@ const useStyles = makeStyles({
}
});
googleProvider.addScope("https://www.googleapis.com/auth/contacts.readonly");
function handleAuth() {
auth.signInWithPopup(googleProvider);
}
// googleProvider.addScope("https://www.googleapis.com/auth/contacts.readonly");
export default function AuthView() {
const classes = useStyles();
const router = useRouter();
const handleAuth = async () => {
await auth.signInWithPopup(googleProvider);
router.history.replace("/");
};
return (
<Card className={classes.card}>
<CardContent>

View File

@@ -1,11 +1,12 @@
import React, { useEffect } from "react";
import { makeStyles } from "@material-ui/core/styles";
import { Navigation } from "../components/Navigation";
import Navigation from "../components/Navigation";
import useTable from "../hooks/useTable";
import Table from "../components/Table";
import useRouter from "../hooks/useRouter";
import useTableConfig from "../hooks/useTableConfig";
import Button from "@material-ui/core/Button";
const useStyles = makeStyles({});
export default function AuthView() {
@@ -27,8 +28,9 @@ export default function AuthView() {
columns={tableConfig.columns}
rows={table.rows}
addColumn={configActions.addColumn}
deleteRow={tableActions.deleteRow}
tableActions={tableActions}
/>
<Button onClick={tableActions.addRow}>Add Row</Button>
</Navigation>
);
}

67
src/views/TablesView.tsx Normal file
View File

@@ -0,0 +1,67 @@
import React from "react";
import useSettings from "../hooks/useSettings";
import { makeStyles } from "@material-ui/core/styles";
import Card from "@material-ui/core/Card";
import CardActions from "@material-ui/core/CardActions";
import CardContent from "@material-ui/core/CardContent";
import Button from "@material-ui/core/Button";
import Typography from "@material-ui/core/Typography";
import Grid from "@material-ui/core/Grid";
import useRouter from "../hooks/useRouter";
const useStyles = makeStyles({
card: {
minWidth: 275
},
bullet: {
display: "inline-block",
margin: "0 2px",
transform: "scale(0.8)"
},
title: {
fontSize: 14
},
pos: {
marginBottom: 12
}
});
const TablesView = (props: any) => {
const [settings, createTable] = useSettings();
const tables = settings.tables;
const classes = useStyles();
const router = useRouter();
return (
<Grid container>
{tables
? tables.map((table: any) => (
<Card className={classes.card}>
<CardContent>
<Typography variant="h5" component="h2">
{table.name}
</Typography>
<Typography className={classes.pos} color="textSecondary">
primary
</Typography>
<Typography variant="body2" component="p">
Table summery use
</Typography>
</CardContent>
<CardActions>
<Button
size="small"
onClick={() => {
router.history.push(`table/${table.collection}`);
}}
>
open{" "}
</Button>
</CardActions>
</Card>
))
: "TODO: card skeleton"}
</Grid>
);
};
export default TablesView;

View File

@@ -851,7 +851,7 @@
dependencies:
regenerator-runtime "^0.13.2"
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5":
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5":
version "7.6.0"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.0.tgz#4fc1d642a9fd0299754e8b5de62c631cf5568205"
integrity sha512-89eSBLJsxNxOERC0Op4vd+0Bqm6wRMqMbFtV3i0/fbaWw/mJ8Q3eBvgX0G4SyrOOLCtbu98HspF8o09MRT+KzQ==
@@ -909,6 +909,18 @@
resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-9.0.1.tgz#c27b391d8457d1e893f1eddeaf5e5412d12ffbb5"
integrity sha512-6It2EVfGskxZCQhuykrfnALg7oVeiI6KclWSmGDqB0AiInVrTGB9Jp9i4/Ad21u9Jde/voVQz6eFX/eSg/UsPA==
"@date-io/core@^1.3.11":
version "1.3.11"
resolved "https://registry.yarnpkg.com/@date-io/core/-/core-1.3.11.tgz#98e3c366794dfff571e39227e5d718ac7f26b729"
integrity sha512-Yxf2ei0vjU38Fizswr/Uwub5QeRiLOHiTRiHUuTdg+biVB+1EUk+h5szas9SEWA2pZDlSo73F5TPuu+zKqOIBQ==
"@date-io/date-fns@^1.3.11":
version "1.3.11"
resolved "https://registry.yarnpkg.com/@date-io/date-fns/-/date-fns-1.3.11.tgz#f0b320b9c5993b9914e3b4d71155ea40814a8d75"
integrity sha512-6Pvk4gwCU4L19XYzDUrro861JCQjZkJQjugxAA+M8wsDTW75A5rmSZGa6g2rQQXfg6ox4B7HBx9p6JYDsSPX0g==
dependencies:
"@date-io/core" "^1.3.11"
"@emotion/hash@^0.7.1":
version "0.7.2"
resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.7.2.tgz#53211e564604beb9befa7a4400ebf8147473eeef"
@@ -1307,6 +1319,18 @@
prop-types "^15.7.2"
warning "^4.0.3"
"@material-ui/pickers@^3.2.5":
version "3.2.5"
resolved "https://registry.yarnpkg.com/@material-ui/pickers/-/pickers-3.2.5.tgz#e5c9a56c8b57ceb8bca50c4fd7b7a03cb3c918e1"
integrity sha512-UV5UKslOcmcP4cB2wwOg1SFoXS6RTRRvCNkDclHtOa+Ni+gyZLEt3WcSQWH7oDx8A94gmkiZTpfweNFV7sC4sw==
dependencies:
"@babel/runtime" "^7.2.0"
"@types/styled-jsx" "^2.2.8"
clsx "^1.0.2"
react-transition-group "^4.0.0"
rifm "^0.7.0"
tslib "^1.9.3"
"@material-ui/styles@^4.4.1":
version "4.4.1"
resolved "https://registry.yarnpkg.com/@material-ui/styles/-/styles-4.4.1.tgz#a53fb39e373636bd2c296a78c54afecb80f68446"
@@ -1710,6 +1734,13 @@
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==
"@types/styled-jsx@^2.2.8":
version "2.2.8"
resolved "https://registry.yarnpkg.com/@types/styled-jsx/-/styled-jsx-2.2.8.tgz#b50d13d8a3c34036282d65194554cf186bab7234"
integrity sha512-Yjye9VwMdYeXfS71ihueWRSxrruuXTwKCbzue4+5b2rjnQ//AtyM7myZ1BEhNhBQ/nL/RE7bdToUoLln2miKvg==
dependencies:
"@types/react" "*"
"@types/yargs-parser@*":
version "13.1.0"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228"
@@ -3570,6 +3601,11 @@ data-urls@^1.0.0, data-urls@^1.1.0:
whatwg-mimetype "^2.2.0"
whatwg-url "^7.0.0"
date-fns@^2.0.0-beta.5:
version "2.0.0-beta.5"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.0-beta.5.tgz#90885db3772802d55519cd12acd49de56aca1059"
integrity sha512-GS5yi964NDFNoja9yOdWFj9T97T67yLrUeJZgddHaVfc/6tHWtX7RXocuubmZkNzrZUZ9BqBOW7jTR5OoWjJ1w==
date-now@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
@@ -9328,6 +9364,13 @@ rgba-regex@^1.0.0:
resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3"
integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=
rifm@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/rifm/-/rifm-0.7.0.tgz#debe951a9c83549ca6b33e5919f716044c2230be"
integrity sha512-DSOJTWHD67860I5ojetXdEQRIBvF6YcpNe53j0vn1vp9EUb9N80EiZTxgP+FkDKorWC8PZw052kTF4C1GOivCQ==
dependencies:
"@babel/runtime" "^7.3.1"
rimraf@2.6.3:
version "2.6.3"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
@@ -10279,7 +10322,7 @@ ts-toolbelt@^3.8.4:
resolved "https://registry.yarnpkg.com/ts-toolbelt/-/ts-toolbelt-3.8.72.tgz#647ba67a3bd55f1e5a8057c1a7621c38b2e418a5"
integrity sha512-rVwnPRczAamCTIs/9iUgWW12YMscmDG79M0xiUmcmWgTk8lkjxrrwzUys72wsIxNohtiNQaOhbkgQPIxqIdwmA==
tslib@1.10.0, tslib@^1.8.1, tslib@^1.9.0:
tslib@1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
version "1.10.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==