From ec630ee39b4431c756c6dcb5dcf41162e6cc65cc Mon Sep 17 00:00:00 2001 From: apanizo Date: Wed, 17 Oct 2018 17:23:22 +0200 Subject: [PATCH 01/68] Created TableHead component --- src/components/Table/TableHead.jsx | 65 ++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/components/Table/TableHead.jsx diff --git a/src/components/Table/TableHead.jsx b/src/components/Table/TableHead.jsx new file mode 100644 index 0000000000..cd02a4a9e2 --- /dev/null +++ b/src/components/Table/TableHead.jsx @@ -0,0 +1,65 @@ +// @flow +import * as React from 'react' +import { List } from 'immutable' +import TableCell from '@material-ui/core/TableCell' +import TableHead from '@material-ui/core/TableHead' +import TableRow from '@material-ui/core/TableRow' +import TableSortLabel from '@material-ui/core/TableSortLabel' +import Tooltip from '@material-ui/core/Tooltip' +import { type Order } from '~/components/Table/sorting' + +export type Column = { + id: string, + numeric: boolean, + disablePadding: boolean, + label: string, + tooltip?: string, +} + +type Props = { + columns: List, + orderBy: string, // id of one of the described columns + order: Order, + onSort: (property: string) => void, +} + +class GnoTableHead extends React.PureComponent { + changeSort = (property: string) => () => { + this.props.onSort(property) + } + + render() { + const { columns, order, orderBy } = this.props + + return ( + + + {columns.map((column: Column) => ( + + + + {column.label} + + + + ))} + + + ) + } +} + +export default GnoTableHead From ee8e16865795c08753eabce412610034f1bc981c Mon Sep 17 00:00:00 2001 From: apanizo Date: Wed, 17 Oct 2018 17:23:55 +0200 Subject: [PATCH 02/68] Added sorting helper functions for Table Header --- src/components/Table/sorting.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/components/Table/sorting.js diff --git a/src/components/Table/sorting.js b/src/components/Table/sorting.js new file mode 100644 index 0000000000..15efdaaf72 --- /dev/null +++ b/src/components/Table/sorting.js @@ -0,0 +1,30 @@ +// @flow +const desc = (a, b, orderBy) => { + if (b[orderBy] < a[orderBy]) { + return -1 + } + if (b[orderBy] > a[orderBy]) { + return 1 + } + return 0 +} + +export const stableSort = (array: any, cmp: any) => { + const stabilizedThis = array.map((el, index) => [el, index]) + + stabilizedThis.sort((a, b) => { + const order = cmp(a[0], b[0]) + if (order !== 0) { + return order + } + + return a[1] - b[1] + }) + + return stabilizedThis.map(el => el[0]) +} + +export type Order = 'asc' | 'desc' + +export const getSorting = (order: Order, orderBy: string) => + (order === 'desc' ? (a: any, b: any) => desc(a, b, orderBy) : (a: any, b: any) => -desc(a, b, orderBy)) From b9e6e247831b60bd43340e1e0c6b92d39404fc5c Mon Sep 17 00:00:00 2001 From: apanizo Date: Wed, 17 Oct 2018 17:24:30 +0200 Subject: [PATCH 03/68] Added colors to Heading component --- src/components/layout/Heading/index.jsx | 4 ++- src/components/layout/Heading/index.scss | 36 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/components/layout/Heading/index.jsx b/src/components/layout/Heading/index.jsx index 286e47e6f3..dd7de50d11 100644 --- a/src/components/layout/Heading/index.jsx +++ b/src/components/layout/Heading/index.jsx @@ -11,6 +11,7 @@ type HeadingTag = 'h1' | 'h2' | 'h3' | 'h4'; type Props = { align?: 'left' | 'center' | 'right', margin?: 'sm' | 'md' | 'lg' | 'xl', + color?: 'soft' | 'medium' | 'dark' | 'white' | 'fancy' | 'primary' | 'secondary' | 'warning' | 'disabled', tag: HeadingTag, truncate?: boolean, children: React$Node, @@ -19,7 +20,7 @@ type Props = { class Heading extends React.PureComponent { render() { const { - align, tag, truncate, margin, children, ...props + align, tag, truncate, margin, color, children, ...props } = this.props const className = cx( @@ -27,6 +28,7 @@ class Heading extends React.PureComponent { align, tag, margin ? capitalize(margin, 'margin') : undefined, + color, { truncate }, ) diff --git a/src/components/layout/Heading/index.scss b/src/components/layout/Heading/index.scss index 1f5c5315cd..6c3f3fa64a 100644 --- a/src/components/layout/Heading/index.scss +++ b/src/components/layout/Heading/index.scss @@ -63,3 +63,39 @@ .marginXl { margin: 0 0 $xl 0; } + +.soft { + color: #888888; +} + +.medium { + color: #686868; +} + +.dark { + color: black; +} + +.fancy { + color: $fancy; +} + +.warning { + color: $warning; +} + +.primary { + color: $fontColor; +} + +.secondary { + color: $secondary; +} + +.disabled { + color: $disabled; +} + +.white { + color: white; +} From 8c9971f19db736fadac63347a66338ec6490d0cb Mon Sep 17 00:00:00 2001 From: apanizo Date: Wed, 17 Oct 2018 17:25:09 +0200 Subject: [PATCH 04/68] Modified MuiTab component in mui theme --- src/theme/mui.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/theme/mui.js b/src/theme/mui.js index 731616c647..f6e61f713e 100644 --- a/src/theme/mui.js +++ b/src/theme/mui.js @@ -1,7 +1,7 @@ // @flow import red from '@material-ui/core/colors/red' import { createMuiTheme } from '@material-ui/core/styles' -import { largeFontSize, mediumFontSize, smallFontSize, disabled, primary, secondary, md, lg, background } from './variables' +import { largeFontSize, mediumFontSize, smallFontSize, disabled, primary, secondary, md, lg, background, bolder } from './variables' export type WithStyles = { classes: Object, @@ -125,6 +125,12 @@ export default createMuiTheme({ color: primary, }, }, + MuiTab: { + label: { + fontFamily: 'Roboto Mono, monospace', + fontWeight: bolder, + }, + }, }, palette, }) From 9b808669926e67564e46e8571c4417ca3e95b525 Mon Sep 17 00:00:00 2001 From: apanizo Date: Wed, 17 Oct 2018 17:25:47 +0200 Subject: [PATCH 05/68] Including network in safe route container as a prop --- src/routes/safe/container/index.jsx | 10 ++++++++-- src/routes/safe/container/selector.js | 4 +++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/routes/safe/container/index.jsx b/src/routes/safe/container/index.jsx index b980ec2a02..27925d0de6 100644 --- a/src/routes/safe/container/index.jsx +++ b/src/routes/safe/container/index.jsx @@ -47,13 +47,19 @@ class SafeView extends React.PureComponent { render() { const { - safe, provider, activeTokens, granted, userAddress, + safe, provider, activeTokens, granted, userAddress, network, } = this.props return ( { granted - ? + ? : } diff --git a/src/routes/safe/container/selector.js b/src/routes/safe/container/selector.js index 8c56566346..45e9d3af81 100644 --- a/src/routes/safe/container/selector.js +++ b/src/routes/safe/container/selector.js @@ -2,7 +2,7 @@ import { List } from 'immutable' import { createSelector, createStructuredSelector, type Selector } from 'reselect' import { safeSelector, type RouterProps, type SafeSelectorProps } from '~/routes/safe/store/selectors' -import { providerNameSelector, userAccountSelector } from '~/logic/wallets/store/selectors' +import { providerNameSelector, userAccountSelector, networkSelector } from '~/logic/wallets/store/selectors' import { type Safe } from '~/routes/safe/store/model/safe' import { type Owner } from '~/routes/safe/store/model/owner' import { type GlobalState } from '~/store' @@ -15,6 +15,7 @@ export type SelectorProps = { provider: string, activeTokens: List, userAddress: string, + network: string, } export const grantedSelector: Selector = createSelector( @@ -44,4 +45,5 @@ export default createStructuredSelector({ activeTokens: activeTokensSelector, granted: grantedSelector, userAddress: userAccountSelector, + network: networkSelector, }) From d00cf82bda0ca5fbca99dc0201faea5e50b26d8e Mon Sep 17 00:00:00 2001 From: apanizo Date: Wed, 17 Oct 2018 17:27:47 +0200 Subject: [PATCH 06/68] Creation of Table component including generic Row Type --- src/components/Table/index.jsx | 80 ++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 src/components/Table/index.jsx diff --git a/src/components/Table/index.jsx b/src/components/Table/index.jsx new file mode 100644 index 0000000000..4c937fc018 --- /dev/null +++ b/src/components/Table/index.jsx @@ -0,0 +1,80 @@ +// @flow +import * as React from 'react' +import { List } from 'immutable' +import Table from '@material-ui/core/Table' +import TableBody from '@material-ui/core/TableBody' +import TableRow from '@material-ui/core/TableRow' +import TableCell from '@material-ui/core/TableCell' +import TableHead, { type Column } from '~/components/Table/TableHead' +import { type Order, stableSort, getSorting } from '~/components/Table/sorting' + +type Props = { + label: string, + rowsPerPage?: number, + defaultOrderBy: string, + columns: List, + data: Array, +} + +type State = { + page: number, + order: Order, + orderBy: string, +} + +class GnoTable extends React.Component, State> { + state = { + page: 0, + order: 'desc', + orderBy: this.props.defaultOrderBy, + } + + onSort = (property: string) => { + const orderBy = property + let order = 'desc' + + if (this.state.orderBy === property && this.state.order === 'desc') { + order = 'asc' + } + + this.setState({ order, orderBy }) + } + + render() { + const { + data, label, columns, rowsPerPage = 5, + } = this.props + const { order, orderBy, page } = this.state + + return ( + + + + {stableSort(data, getSorting(order, orderBy)) + .slice(page * rowsPerPage, ((page * rowsPerPage) + rowsPerPage)) + .map((row: any) => ( + + { + columns.map((column: Column) => ( + + {row[column.id]} + + )) + } + + ))} + +
+ ) + } +} + +export default GnoTable From 3891f3c1a5e13ac6b52a8ef4b556e80a517b403d Mon Sep 17 00:00:00 2001 From: apanizo Date: Thu, 18 Oct 2018 12:19:08 +0200 Subject: [PATCH 07/68] Adapting sorting to accept custom fields in Table component --- src/components/Table/TableHead.jsx | 27 ++++++++++----------------- src/components/Table/index.jsx | 16 ++++++++++------ src/components/Table/sorting.js | 16 +++++++++++----- 3 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/components/Table/TableHead.jsx b/src/components/Table/TableHead.jsx index cd02a4a9e2..e3514a0899 100644 --- a/src/components/Table/TableHead.jsx +++ b/src/components/Table/TableHead.jsx @@ -5,27 +5,26 @@ import TableCell from '@material-ui/core/TableCell' import TableHead from '@material-ui/core/TableHead' import TableRow from '@material-ui/core/TableRow' import TableSortLabel from '@material-ui/core/TableSortLabel' -import Tooltip from '@material-ui/core/Tooltip' import { type Order } from '~/components/Table/sorting' export type Column = { id: string, numeric: boolean, + order: boolean, disablePadding: boolean, label: string, - tooltip?: string, } type Props = { columns: List, orderBy: string, // id of one of the described columns order: Order, - onSort: (property: string) => void, + onSort: (property: string, orderAttr: boolean) => void, } class GnoTableHead extends React.PureComponent { - changeSort = (property: string) => () => { - this.props.onSort(property) + changeSort = (property: string, orderAttr: boolean) => () => { + this.props.onSort(property, orderAttr) } render() { @@ -41,19 +40,13 @@ class GnoTableHead extends React.PureComponent { padding={column.disablePadding ? 'none' : 'default'} sortDirection={orderBy === column.id ? order : false} > - - - {column.label} - - + {column.label} + ))} diff --git a/src/components/Table/index.jsx b/src/components/Table/index.jsx index 4c937fc018..c1cfbcc734 100644 --- a/src/components/Table/index.jsx +++ b/src/components/Table/index.jsx @@ -20,6 +20,7 @@ type State = { page: number, order: Order, orderBy: string, + orderProp: boolean, } class GnoTable extends React.Component, State> { @@ -27,9 +28,10 @@ class GnoTable extends React.Component, State> { page: 0, order: 'desc', orderBy: this.props.defaultOrderBy, + orderProp: false, } - onSort = (property: string) => { + onSort = (property: string, orderProp: boolean) => { const orderBy = property let order = 'desc' @@ -37,14 +39,16 @@ class GnoTable extends React.Component, State> { order = 'asc' } - this.setState({ order, orderBy }) + this.setState({ order, orderBy, orderProp }) } render() { const { data, label, columns, rowsPerPage = 5, } = this.props - const { order, orderBy, page } = this.state + const { + order, orderBy, page, orderProp, + } = this.state return ( @@ -55,12 +59,12 @@ class GnoTable extends React.Component, State> { onSort={this.onSort} /> - {stableSort(data, getSorting(order, orderBy)) + {stableSort(data, getSorting(order, orderBy, orderProp)) .slice(page * rowsPerPage, ((page * rowsPerPage) + rowsPerPage)) - .map((row: any) => ( + .map((row: any, index: number) => ( { columns.map((column: Column) => ( diff --git a/src/components/Table/sorting.js b/src/components/Table/sorting.js index 15efdaaf72..75dc2255db 100644 --- a/src/components/Table/sorting.js +++ b/src/components/Table/sorting.js @@ -1,11 +1,17 @@ // @flow -const desc = (a, b, orderBy) => { - if (b[orderBy] < a[orderBy]) { + +export const buildOrderFieldFrom = (attr: string) => `${attr}Order` + +const desc = (a: Object, b: Object, orderBy: string, orderProp: boolean) => { + const order = orderProp ? buildOrderFieldFrom(orderBy) : orderBy + + if (b[order] < a[order]) { return -1 } - if (b[orderBy] > a[orderBy]) { + if (b[order] > a[order]) { return 1 } + return 0 } @@ -26,5 +32,5 @@ export const stableSort = (array: any, cmp: any) => { export type Order = 'asc' | 'desc' -export const getSorting = (order: Order, orderBy: string) => - (order === 'desc' ? (a: any, b: any) => desc(a, b, orderBy) : (a: any, b: any) => -desc(a, b, orderBy)) +export const getSorting = (order: Order, orderBy: string, orderProp: boolean) => + (order === 'desc' ? (a: any, b: any) => desc(a, b, orderBy, orderProp) : (a: any, b: any) => -desc(a, b, orderBy, orderProp)) From 1e59ef9bbd2b3f5f9e0543912c50d363380fb27a Mon Sep 17 00:00:00 2001 From: apanizo Date: Thu, 18 Oct 2018 12:20:02 +0200 Subject: [PATCH 08/68] Fix muiTheme bolder property --- src/theme/mui.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/theme/mui.js b/src/theme/mui.js index f6e61f713e..e150e1a72a 100644 --- a/src/theme/mui.js +++ b/src/theme/mui.js @@ -1,7 +1,7 @@ // @flow import red from '@material-ui/core/colors/red' import { createMuiTheme } from '@material-ui/core/styles' -import { largeFontSize, mediumFontSize, smallFontSize, disabled, primary, secondary, md, lg, background, bolder } from './variables' +import { largeFontSize, mediumFontSize, smallFontSize, disabled, primary, secondary, md, lg, background, bolderFont } from './variables' export type WithStyles = { classes: Object, @@ -128,7 +128,7 @@ export default createMuiTheme({ MuiTab: { label: { fontFamily: 'Roboto Mono, monospace', - fontWeight: bolder, + fontWeight: bolderFont, }, }, }, From 53b169bc42acc42a692ed5e8443578d3468d284d Mon Sep 17 00:00:00 2001 From: apanizo Date: Thu, 18 Oct 2018 13:49:12 +0200 Subject: [PATCH 09/68] Adding Pagination to Table component --- src/components/Table/index.jsx | 88 +++++++++++++++++++++++----------- src/theme/mui.js | 26 ++++++++++ 2 files changed, 86 insertions(+), 28 deletions(-) diff --git a/src/components/Table/index.jsx b/src/components/Table/index.jsx index c1cfbcc734..e4938a18b5 100644 --- a/src/components/Table/index.jsx +++ b/src/components/Table/index.jsx @@ -6,11 +6,11 @@ import TableBody from '@material-ui/core/TableBody' import TableRow from '@material-ui/core/TableRow' import TableCell from '@material-ui/core/TableCell' import TableHead, { type Column } from '~/components/Table/TableHead' +import TablePagination from '@material-ui/core/TablePagination' import { type Order, stableSort, getSorting } from '~/components/Table/sorting' type Props = { label: string, - rowsPerPage?: number, defaultOrderBy: string, columns: List, data: Array, @@ -21,6 +21,7 @@ type State = { order: Order, orderBy: string, orderProp: boolean, + rowsPerPage: number, } class GnoTable extends React.Component, State> { @@ -29,6 +30,7 @@ class GnoTable extends React.Component, State> { order: 'desc', orderBy: this.props.defaultOrderBy, orderProp: false, + rowsPerPage: 5, } onSort = (property: string, orderProp: boolean) => { @@ -42,41 +44,71 @@ class GnoTable extends React.Component, State> { this.setState({ order, orderBy, orderProp }) } + handleChangePage = (page: number) => { + this.setState({ page }) + } + + handleChangeRowsPerPage = (event: SyntheticInputEvent) => { + const rowsPerPage = Number(event.target.value) + this.setState({ rowsPerPage }) + } + render() { const { - data, label, columns, rowsPerPage = 5, + data, label, columns, } = this.props + const { - order, orderBy, page, orderProp, + order, orderBy, page, orderProp, rowsPerPage, } = this.state + const backProps = { + 'aria-label': 'Previous Page', + } + + const nextProps = { + 'aria-label': 'Next Page', + } + return ( -
- +
+ + + {stableSort(data, getSorting(order, orderBy, orderProp)) + .slice(page * rowsPerPage, ((page * rowsPerPage) + rowsPerPage)) + .map((row: any, index: number) => ( + + { + columns.map((column: Column) => ( + + {row[column.id]} + + )) + } + + ))} + +
+ - - {stableSort(data, getSorting(order, orderBy, orderProp)) - .slice(page * rowsPerPage, ((page * rowsPerPage) + rowsPerPage)) - .map((row: any, index: number) => ( - - { - columns.map((column: Column) => ( - - {row[column.id]} - - )) - } - - ))} - - + ) } } diff --git a/src/theme/mui.js b/src/theme/mui.js index e150e1a72a..d6ce5341dd 100644 --- a/src/theme/mui.js +++ b/src/theme/mui.js @@ -131,6 +131,32 @@ export default createMuiTheme({ fontWeight: bolderFont, }, }, + MuiTablePagination: { + toolbar: { + '& > span:nth-child(2)': { + order: 1, + }, + }, + selectIcon: { + height: '100%', + top: '0px', + }, + caption: { + fontFamily: 'Roboto Mono, monospace', + letterSpacing: '-0.5px', + order: 3, + color: disabled, + }, + input: { + order: 2, + width: '60px', + padding: `0 ${md} 0 0`, + }, + actions: { + order: 4, + color: disabled, + }, + }, }, palette, }) From 369045b75fb586d63c15a0be0e03d2be60cea3ff Mon Sep 17 00:00:00 2001 From: apanizo Date: Thu, 18 Oct 2018 16:56:21 +0200 Subject: [PATCH 10/68] Accepting color in Hairline component --- src/components/layout/Hairline/index.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/layout/Hairline/index.js b/src/components/layout/Hairline/index.js index 0dd0acb355..a0125b3043 100644 --- a/src/components/layout/Hairline/index.js +++ b/src/components/layout/Hairline/index.js @@ -3,19 +3,20 @@ import * as React from 'react' import { type Size, getSize } from '~/theme/size' import { border } from '~/theme/variables' -const calculateStyleFrom = (margin?: Size) => ({ +const calculateStyleFrom = (color?: string, margin?: Size) => ({ width: '100%', height: '1px', - backgroundColor: border, + backgroundColor: color || border, margin: `${getSize(margin)} 0px`, }) type Props = { margin?: Size, + color?: string, } -const Hairline = ({ margin }: Props) => { - const style = calculateStyleFrom(margin) +const Hairline = ({ margin, color }: Props) => { + const style = calculateStyleFrom(color, margin) return
} From ed258e91e1727d197ccbfd9ce688ea2bed7e8536 Mon Sep 17 00:00:00 2001 From: apanizo Date: Thu, 18 Oct 2018 16:56:56 +0200 Subject: [PATCH 11/68] Fixing label font-weight property on Table's header --- src/theme/mui.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/theme/mui.js b/src/theme/mui.js index d6ce5341dd..199b6818aa 100644 --- a/src/theme/mui.js +++ b/src/theme/mui.js @@ -126,8 +126,11 @@ export default createMuiTheme({ }, }, MuiTab: { - label: { + root: { fontFamily: 'Roboto Mono, monospace', + fontWeight: 'normal', + }, + selected: { fontWeight: bolderFont, }, }, From e907b7ce0c2e2da197069b4e7e232ea015b1335b Mon Sep 17 00:00:00 2001 From: apanizo Date: Thu, 18 Oct 2018 16:57:38 +0200 Subject: [PATCH 12/68] Initial layout on safe view with dummy token data --- src/routes/safe/component/Balances/index.jsx | 128 +++++++++++++++++++ src/routes/safe/component/Layout.jsx | 115 +++++++++++++++-- 2 files changed, 231 insertions(+), 12 deletions(-) create mode 100644 src/routes/safe/component/Balances/index.jsx diff --git a/src/routes/safe/component/Balances/index.jsx b/src/routes/safe/component/Balances/index.jsx new file mode 100644 index 0000000000..74443780a9 --- /dev/null +++ b/src/routes/safe/component/Balances/index.jsx @@ -0,0 +1,128 @@ +// @flow +import * as React from 'react' +import { List } from 'immutable' +import Row from '~/components/layout/Row' +import Checkbox from '@material-ui/core/Checkbox' +import { withStyles } from '@material-ui/core/styles' +import Paragraph from '~/components/layout/Paragraph' +import { type Column } from '~/components/Table/TableHead' +import Table from '~/components/Table' +import { buildOrderFieldFrom } from '~/components/Table/sorting' +import { sm } from '~/theme/variables' + +const BALANCE_TABLE_ASSET_ID = 'asset' +const BALANCE_TABLE_BALANCE_ID = 'balance' +const BALANCE_TABLE_VALUE_ID = 'value' + +const generateColumns = () => { + const assetRow: Column = { + id: BALANCE_TABLE_ASSET_ID, + order: false, + numeric: false, + disablePadding: false, + label: 'Asset', + } + + const balanceRow: Column = { + id: BALANCE_TABLE_BALANCE_ID, + order: true, + numeric: true, + disablePadding: false, + label: 'Balance', + } + + const valueRow: Column = { + id: BALANCE_TABLE_VALUE_ID, + order: true, + numeric: true, + disablePadding: false, + label: 'Value', + } + + return List([assetRow, balanceRow, valueRow]) +} + +type State = { + hideZero: boolean, +} + +const styles = { + root: { + width: '20px', + marginRight: sm, + }, + zero: { + letterSpacing: '-0.5px', + }, +} + +type Props = { + classes: Object, +} + +class Balances extends React.Component { + state = { + hideZero: false, + } + + handleChange = (e: SyntheticInputEvent) => { + const { checked } = e.target + + this.setState(() => ({ hideZero: checked })) + } + + render() { + const { hideZero } = this.state + const { classes } = this.props + + const columns = generateColumns() + const checkboxClasses = { + root: classes.root, + } + + return ( + + + + Hide zero balances + + + + ) + } +} + +export default withStyles(styles)(Balances) diff --git a/src/routes/safe/component/Layout.jsx b/src/routes/safe/component/Layout.jsx index 231731cf63..446a5e56f6 100644 --- a/src/routes/safe/component/Layout.jsx +++ b/src/routes/safe/component/Layout.jsx @@ -1,20 +1,111 @@ // @flow import * as React from 'react' +import OpenInNew from '@material-ui/icons/OpenInNew' +import Tabs from '@material-ui/core/Tabs' +import Tab from '@material-ui/core/Tab' +import Hairline from '~/components/layout/Hairline' +import Block from '~/components/layout/Block' +import Identicon from '~/components/Identicon' +import { withStyles } from '@material-ui/core/styles' +import Heading from '~/components/layout/Heading' +import Row from '~/components/layout/Row' +import Paragraph from '~/components/layout/Paragraph' import NoSafe from '~/components/NoSafe' import { type SelectorProps } from '~/routes/safe/container/selector' -import GnoSafe from './Safe' +import { openAddressInEtherScan } from '~/logic/wallets/getWeb3' +import { sm, secondary } from '~/theme/variables' +import Balances from './Balances' -type Props = SelectorProps +type Props = SelectorProps & { + classes: Object, +} -const Layout = ({ - safe, activeTokens, provider, userAddress, -}: Props) => ( - - { safe - ? - : +type State = { + value: number, +} + +const openIconStyle = { + height: '16px', + color: secondary, +} + +const styles = () => ({ + container: { + display: 'flex', + alignItems: 'center', + }, + name: { + marginLeft: sm, + textOverflow: 'ellipsis', + overflow: 'hidden', + whiteSpace: 'nowrap', + }, + user: { + justifyContent: 'left', + }, + open: { + paddingLeft: sm, + width: 'auto', + '&:hover': { + cursor: 'pointer', + }, + }, +}) + +class Layout extends React.Component { + state = { + value: 0, + } + + handleChange = (event, value) => { + this.setState({ value }) + } + + render() { + const { + safe, provider, network, classes, + } = this.props + const { value } = this.state + + if (!safe) { + return } - -) + // + const address = safe.get('address') + + return ( + + + + + {safe.get('name')} + + {address} + + + + + + + + + + + + + {value === 0 && } + + ) + } +} -export default Layout +export default withStyles(styles)(Layout) From 9fedcb74490a6469029f3f640ffcbc16fdd52c77 Mon Sep 17 00:00:00 2001 From: apanizo Date: Thu, 18 Oct 2018 17:18:22 +0200 Subject: [PATCH 13/68] Styling Table component --- src/components/Table/index.jsx | 37 +++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src/components/Table/index.jsx b/src/components/Table/index.jsx index e4938a18b5..ec3e5c2e8e 100644 --- a/src/components/Table/index.jsx +++ b/src/components/Table/index.jsx @@ -5,15 +5,17 @@ import Table from '@material-ui/core/Table' import TableBody from '@material-ui/core/TableBody' import TableRow from '@material-ui/core/TableRow' import TableCell from '@material-ui/core/TableCell' -import TableHead, { type Column } from '~/components/Table/TableHead' +import { withStyles } from '@material-ui/core/styles' import TablePagination from '@material-ui/core/TablePagination' import { type Order, stableSort, getSorting } from '~/components/Table/sorting' +import TableHead, { type Column } from '~/components/Table/TableHead' type Props = { label: string, defaultOrderBy: string, columns: List, data: Array, + classes: Object, } type State = { @@ -24,6 +26,24 @@ type State = { rowsPerPage: number, } +const styles = { + root: { + backgroundColor: 'white', + boxShadow: '0 -1px 5px 0 rgba(74, 85, 121, 0.5)', + }, + selectRoot: { + lineHeight: '40px', + backgroundColor: 'white', + }, + white: { + backgroundColor: 'white', + }, + paginationRoot: { + backgroundColor: 'white', + boxShadow: '0 2px 5px 0 rgba(74, 85, 121, 0.5)', + }, +} + class GnoTable extends React.Component, State> { state = { page: 0, @@ -55,7 +75,7 @@ class GnoTable extends React.Component, State> { render() { const { - data, label, columns, + data, label, columns, classes, } = this.props const { @@ -70,9 +90,15 @@ class GnoTable extends React.Component, State> { 'aria-label': 'Next Page', } + const paginationClasses = { + selectRoot: classes.selectRoot, + root: classes.paginationRoot, + input: classes.white, + } + return ( -
+
extends React.Component, State> { > { columns.map((column: Column) => ( - + {row[column.id]} )) @@ -107,10 +133,11 @@ class GnoTable extends React.Component, State> { nextIconButtonProps={nextProps} onChangePage={this.handleChangePage} onChangeRowsPerPage={this.handleChangeRowsPerPage} + classes={paginationClasses} /> ) } } -export default GnoTable +export default withStyles(styles)(GnoTable) From db8cfdb1749acc923443f8d3500cb2a9428241b8 Mon Sep 17 00:00:00 2001 From: apanizo Date: Thu, 18 Oct 2018 17:44:09 +0200 Subject: [PATCH 14/68] More Styling on Safe's balance view --- src/components/Table/index.jsx | 4 ++-- src/routes/safe/component/Balances/index.jsx | 5 ++++- src/theme/mui.js | 17 ++++++++++++++++- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/components/Table/index.jsx b/src/components/Table/index.jsx index ec3e5c2e8e..63fece67fb 100644 --- a/src/components/Table/index.jsx +++ b/src/components/Table/index.jsx @@ -29,7 +29,7 @@ type State = { const styles = { root: { backgroundColor: 'white', - boxShadow: '0 -1px 5px 0 rgba(74, 85, 121, 0.5)', + boxShadow: '0 -1px 4px 0 rgba(74, 85, 121, 0.5)', }, selectRoot: { lineHeight: '40px', @@ -40,7 +40,7 @@ const styles = { }, paginationRoot: { backgroundColor: 'white', - boxShadow: '0 2px 5px 0 rgba(74, 85, 121, 0.5)', + boxShadow: '0 2px 4px 0 rgba(74, 85, 121, 0.5)', }, } diff --git a/src/routes/safe/component/Balances/index.jsx b/src/routes/safe/component/Balances/index.jsx index 74443780a9..4421cc0f1f 100644 --- a/src/routes/safe/component/Balances/index.jsx +++ b/src/routes/safe/component/Balances/index.jsx @@ -54,6 +54,9 @@ const styles = { zero: { letterSpacing: '-0.5px', }, + message: { + margin: `${sm} 0`, + }, } type Props = { @@ -82,7 +85,7 @@ class Balances extends React.Component { return ( - + Date: Mon, 22 Oct 2018 11:15:13 +0200 Subject: [PATCH 15/68] Refactor of Table component, customizing cells using a renderProp --- src/components/Table/TableHead.jsx | 3 ++- src/components/Table/index.jsx | 25 +++++--------------- src/routes/safeList/store/selectors/index.js | 1 + 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/src/components/Table/TableHead.jsx b/src/components/Table/TableHead.jsx index e3514a0899..38d4de46a1 100644 --- a/src/components/Table/TableHead.jsx +++ b/src/components/Table/TableHead.jsx @@ -10,9 +10,10 @@ import { type Order } from '~/components/Table/sorting' export type Column = { id: string, numeric: boolean, - order: boolean, + order: boolean, // If data for sorting will be provided in a different attr disablePadding: boolean, label: string, + custom: boolean, // If content will be rendered by user manually } type Props = { diff --git a/src/components/Table/index.jsx b/src/components/Table/index.jsx index 63fece67fb..8882ba1f2b 100644 --- a/src/components/Table/index.jsx +++ b/src/components/Table/index.jsx @@ -3,8 +3,6 @@ import * as React from 'react' import { List } from 'immutable' import Table from '@material-ui/core/Table' import TableBody from '@material-ui/core/TableBody' -import TableRow from '@material-ui/core/TableRow' -import TableCell from '@material-ui/core/TableCell' import { withStyles } from '@material-ui/core/styles' import TablePagination from '@material-ui/core/TablePagination' import { type Order, stableSort, getSorting } from '~/components/Table/sorting' @@ -16,6 +14,7 @@ type Props = { columns: List, data: Array, classes: Object, + children: Function, } type State = { @@ -75,7 +74,7 @@ class GnoTable extends React.Component, State> { render() { const { - data, label, columns, classes, + data, label, columns, classes, children, } = this.props const { @@ -96,6 +95,9 @@ class GnoTable extends React.Component, State> { input: classes.white, } + const sortedData = stableSort(data, getSorting(order, orderBy, orderProp)) + .slice(page * rowsPerPage, ((page * rowsPerPage) + rowsPerPage)) + return (
@@ -106,22 +108,7 @@ class GnoTable extends React.Component, State> { onSort={this.onSort} /> - {stableSort(data, getSorting(order, orderBy, orderProp)) - .slice(page * rowsPerPage, ((page * rowsPerPage) + rowsPerPage)) - .map((row: any, index: number) => ( - - { - columns.map((column: Column) => ( - - {row[column.id]} - - )) - } - - ))} + { children(sortedData) }
=> state.safes + const safesListSelector: Selector> = createSelector( safesMapSelector, (safes: Map): List => safes.toList(), From 2438d20b3a7129f45f6f1dda5182a746c846a885 Mon Sep 17 00:00:00 2001 From: apanizo Date: Mon, 22 Oct 2018 11:15:36 +0200 Subject: [PATCH 16/68] Implementation of actions cell in Balance Table --- src/routes/safe/component/Balances/index.jsx | 82 ++++++++++++++++++-- 1 file changed, 76 insertions(+), 6 deletions(-) diff --git a/src/routes/safe/component/Balances/index.jsx b/src/routes/safe/component/Balances/index.jsx index 4421cc0f1f..7014aed73d 100644 --- a/src/routes/safe/component/Balances/index.jsx +++ b/src/routes/safe/component/Balances/index.jsx @@ -1,14 +1,20 @@ // @flow import * as React from 'react' import { List } from 'immutable' -import Row from '~/components/layout/Row' +import classNames from 'classnames/bind' +import CallMade from '@material-ui/icons/CallMade' +import CallReceived from '@material-ui/icons/CallReceived' +import Button from '@material-ui/core/Button' import Checkbox from '@material-ui/core/Checkbox' +import TableRow from '@material-ui/core/TableRow' +import TableCell from '@material-ui/core/TableCell' import { withStyles } from '@material-ui/core/styles' +import Row from '~/components/layout/Row' import Paragraph from '~/components/layout/Paragraph' import { type Column } from '~/components/Table/TableHead' import Table from '~/components/Table' import { buildOrderFieldFrom } from '~/components/Table/sorting' -import { sm } from '~/theme/variables' +import { sm, xs } from '~/theme/variables' const BALANCE_TABLE_ASSET_ID = 'asset' const BALANCE_TABLE_BALANCE_ID = 'balance' @@ -21,6 +27,7 @@ const generateColumns = () => { numeric: false, disablePadding: false, label: 'Asset', + custom: false, } const balanceRow: Column = { @@ -29,6 +36,7 @@ const generateColumns = () => { numeric: true, disablePadding: false, label: 'Balance', + custom: false, } const valueRow: Column = { @@ -37,16 +45,26 @@ const generateColumns = () => { numeric: true, disablePadding: false, label: 'Value', + custom: false, } - return List([assetRow, balanceRow, valueRow]) + const actions: Column = { + id: 'actions', + order: false, + numeric: false, + disablePadding: false, + label: '', + custom: true, + } + + return List([assetRow, balanceRow, valueRow, actions]) } type State = { hideZero: boolean, } -const styles = { +const styles = theme => ({ root: { width: '20px', marginRight: sm, @@ -57,12 +75,41 @@ const styles = { message: { margin: `${sm} 0`, }, -} + actionIcon: { + marginRight: theme.spacing.unit, + }, + iconSmall: { + fontSize: 16, + }, + actions: { + justifyContent: 'flex-end', + }, + send: { + minWidth: '0px', + marginRight: sm, + width: '70px', + }, + receive: { + minWidth: '0px', + width: '95px', + }, + leftIcon: { + marginRight: xs, + }, +}) type Props = { classes: Object, } +type BalanceRow = { + asset: string, + balance: string, + balanceOrder: number, + value: string, + valueOrder: number, +} + class Balances extends React.Component { state = { hideZero: false, @@ -79,6 +126,7 @@ class Balances extends React.Component { const { classes } = this.props const columns = generateColumns() + const autoColumns = columns.filter(c => !c.custom) const checkboxClasses = { root: classes.root, } @@ -122,7 +170,29 @@ class Balances extends React.Component { [buildOrderFieldFrom(BALANCE_TABLE_VALUE_ID)]: 2930.89, }, ]} - /> + > + {(sortedData: Array) => sortedData.map((row: any, index: number) => ( + + { autoColumns.map((column: Column) => ( + + {row[column.id]} + + )) } + + + + + + + + ))} +
) } From 519a55e283de8f418b898f4f66ea486c9a0e820c Mon Sep 17 00:00:00 2001 From: apanizo Date: Mon, 22 Oct 2018 14:45:24 +0200 Subject: [PATCH 17/68] Isolate fake data fetcher for balances --- .../safe/component/Balances/dataFetcher.js | 46 +++++++++++++++++++ src/routes/safe/component/Balances/index.jsx | 40 ++-------------- 2 files changed, 50 insertions(+), 36 deletions(-) create mode 100644 src/routes/safe/component/Balances/dataFetcher.js diff --git a/src/routes/safe/component/Balances/dataFetcher.js b/src/routes/safe/component/Balances/dataFetcher.js new file mode 100644 index 0000000000..6ae4dc9425 --- /dev/null +++ b/src/routes/safe/component/Balances/dataFetcher.js @@ -0,0 +1,46 @@ +// @flow +import { buildOrderFieldFrom } from '~/components/Table/sorting' + +export const BALANCE_TABLE_ASSET_ID = 'asset' +export const BALANCE_TABLE_BALANCE_ID = 'balance' +export const BALANCE_TABLE_VALUE_ID = 'value' + +export type BalanceRow = { + asset: string, + balance: string, + value: string, +} + +export const getBalanceData = (): Array => [ + { + [BALANCE_TABLE_ASSET_ID]: 'Ethereum', + [BALANCE_TABLE_BALANCE_ID]: '9.394 ETH', + [buildOrderFieldFrom(BALANCE_TABLE_BALANCE_ID)]: 9.394, + [BALANCE_TABLE_VALUE_ID]: '$539.45', + [buildOrderFieldFrom(BALANCE_TABLE_VALUE_ID)]: 539.45, + }, + { + [BALANCE_TABLE_ASSET_ID]: 'Gnosis', + [BALANCE_TABLE_BALANCE_ID]: '0.599 GNO', + [buildOrderFieldFrom(BALANCE_TABLE_BALANCE_ID)]: 0.559, + [BALANCE_TABLE_VALUE_ID]: '$23.11', + [buildOrderFieldFrom(BALANCE_TABLE_VALUE_ID)]: 23.11, + }, + { + [BALANCE_TABLE_ASSET_ID]: 'OmiseGO', + [BALANCE_TABLE_BALANCE_ID]: '39.922 OMG', + [buildOrderFieldFrom(BALANCE_TABLE_BALANCE_ID)]: 39.922, + [BALANCE_TABLE_VALUE_ID]: '$2930.89', + [buildOrderFieldFrom(BALANCE_TABLE_VALUE_ID)]: 2930.89, + }, + { + [BALANCE_TABLE_ASSET_ID]: 'Moe Feo', + [BALANCE_TABLE_BALANCE_ID]: '0 MOE', + [buildOrderFieldFrom(BALANCE_TABLE_BALANCE_ID)]: 0, + [BALANCE_TABLE_VALUE_ID]: '$0', + [buildOrderFieldFrom(BALANCE_TABLE_VALUE_ID)]: 0, + }, +] + +export const filterByZero = (data: Array, hideZero: boolean): Array => + data.filter((row: BalanceRow) => (hideZero ? row[buildOrderFieldFrom(BALANCE_TABLE_BALANCE_ID)] !== 0 : true)) diff --git a/src/routes/safe/component/Balances/index.jsx b/src/routes/safe/component/Balances/index.jsx index 7014aed73d..13a9f31fab 100644 --- a/src/routes/safe/component/Balances/index.jsx +++ b/src/routes/safe/component/Balances/index.jsx @@ -13,12 +13,8 @@ import Row from '~/components/layout/Row' import Paragraph from '~/components/layout/Paragraph' import { type Column } from '~/components/Table/TableHead' import Table from '~/components/Table' -import { buildOrderFieldFrom } from '~/components/Table/sorting' import { sm, xs } from '~/theme/variables' - -const BALANCE_TABLE_ASSET_ID = 'asset' -const BALANCE_TABLE_BALANCE_ID = 'balance' -const BALANCE_TABLE_VALUE_ID = 'value' +import { getBalanceData, BALANCE_TABLE_ASSET_ID, BALANCE_TABLE_BALANCE_ID, BALANCE_TABLE_VALUE_ID, type BalanceRow, filterByZero } from './dataFetcher' const generateColumns = () => { const assetRow: Column = { @@ -102,14 +98,6 @@ type Props = { classes: Object, } -type BalanceRow = { - asset: string, - balance: string, - balanceOrder: number, - value: string, - valueOrder: number, -} - class Balances extends React.Component { state = { hideZero: false, @@ -131,6 +119,8 @@ class Balances extends React.Component { root: classes.root, } + const filteredData = filterByZero(getBalanceData(), hideZero) + return ( @@ -147,29 +137,7 @@ class Balances extends React.Component { label="Balances" defaultOrderBy={BALANCE_TABLE_ASSET_ID} columns={columns} - data={[ - { - [BALANCE_TABLE_ASSET_ID]: 'Ethereum', - [BALANCE_TABLE_BALANCE_ID]: '9.394 ETH', - [buildOrderFieldFrom(BALANCE_TABLE_BALANCE_ID)]: 9.394, - [BALANCE_TABLE_VALUE_ID]: '$539.45', - [buildOrderFieldFrom(BALANCE_TABLE_VALUE_ID)]: 539.45, - }, - { - [BALANCE_TABLE_ASSET_ID]: 'Gnosis', - [BALANCE_TABLE_BALANCE_ID]: '0.599 GNO', - [buildOrderFieldFrom(BALANCE_TABLE_BALANCE_ID)]: 0.559, - [BALANCE_TABLE_VALUE_ID]: '$23.11', - [buildOrderFieldFrom(BALANCE_TABLE_VALUE_ID)]: 23.11, - }, - { - [BALANCE_TABLE_ASSET_ID]: 'OmiseGO', - [BALANCE_TABLE_BALANCE_ID]: '39.922 OMG', - [buildOrderFieldFrom(BALANCE_TABLE_BALANCE_ID)]: 39.922, - [BALANCE_TABLE_VALUE_ID]: '$2930.89', - [buildOrderFieldFrom(BALANCE_TABLE_VALUE_ID)]: 2930.89, - }, - ]} + data={filteredData} > {(sortedData: Array) => sortedData.map((row: any, index: number) => ( From 2326dcdf153b5cf216d529b25dd263327a942de3 Mon Sep 17 00:00:00 2001 From: apanizo Date: Mon, 22 Oct 2018 15:47:21 +0200 Subject: [PATCH 18/68] Implementing hover row section on Balance Table --- src/routes/safe/component/Balances/index.jsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/routes/safe/component/Balances/index.jsx b/src/routes/safe/component/Balances/index.jsx index 13a9f31fab..cca31aaf93 100644 --- a/src/routes/safe/component/Balances/index.jsx +++ b/src/routes/safe/component/Balances/index.jsx @@ -77,8 +77,17 @@ const styles = theme => ({ iconSmall: { fontSize: 16, }, + hide: { + '&:hover': { + backgroundColor: '#fff3e2', + }, + '&:hover $actions': { + visibility: 'initial', + }, + }, actions: { justifyContent: 'flex-end', + visibility: 'hidden', }, send: { minWidth: '0px', @@ -140,7 +149,7 @@ class Balances extends React.Component { data={filteredData} > {(sortedData: Array) => sortedData.map((row: any, index: number) => ( - + { autoColumns.map((column: Column) => ( {row[column.id]} From d41a7f7d091880df9f7e63f29071396dbc4be90e Mon Sep 17 00:00:00 2001 From: apanizo Date: Mon, 22 Oct 2018 16:47:19 +0200 Subject: [PATCH 19/68] Adapt Safe's Balance view to show Tokens Modal component --- src/routes/safe/component/Balances/index.jsx | 51 ++++++++++++++++---- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/src/routes/safe/component/Balances/index.jsx b/src/routes/safe/component/Balances/index.jsx index cca31aaf93..a459d13497 100644 --- a/src/routes/safe/component/Balances/index.jsx +++ b/src/routes/safe/component/Balances/index.jsx @@ -9,8 +9,10 @@ import Checkbox from '@material-ui/core/Checkbox' import TableRow from '@material-ui/core/TableRow' import TableCell from '@material-ui/core/TableCell' import { withStyles } from '@material-ui/core/styles' +import Col from '~/components/layout/Col' import Row from '~/components/layout/Row' import Paragraph from '~/components/layout/Paragraph' +import Modal from '~/components/Modal' import { type Column } from '~/components/Table/TableHead' import Table from '~/components/Table' import { sm, xs } from '~/theme/variables' @@ -58,6 +60,7 @@ const generateColumns = () => { type State = { hideZero: boolean, + showToken: boolean, } const styles = theme => ({ @@ -101,6 +104,12 @@ const styles = theme => ({ leftIcon: { marginRight: xs, }, + links: { + textDecoration: 'underline', + '&:hover': { + cursor: 'pointer', + }, + }, }) type Props = { @@ -110,6 +119,15 @@ type Props = { class Balances extends React.Component { state = { hideZero: false, + showToken: false, + } + + onShowToken = () => { + this.setState(() => ({ showToken: true })) + } + + onHideToken = () => { + this.setState(() => ({ showToken: false })) } handleChange = (e: SyntheticInputEvent) => { @@ -119,7 +137,7 @@ class Balances extends React.Component { } render() { - const { hideZero } = this.state + const { hideZero, showToken } = this.state const { classes } = this.props const columns = generateColumns() @@ -133,14 +151,29 @@ class Balances extends React.Component { return ( - - Hide zero balances + + + Hide zero balances + + + + Manage Tokens + + + List of tokens will show here + + Date: Mon, 22 Oct 2018 16:47:45 +0200 Subject: [PATCH 20/68] Creation of Gno Modal component --- src/components/Modal/index.jsx | 46 ++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/components/Modal/index.jsx diff --git a/src/components/Modal/index.jsx b/src/components/Modal/index.jsx new file mode 100644 index 0000000000..f2c46b09fc --- /dev/null +++ b/src/components/Modal/index.jsx @@ -0,0 +1,46 @@ +// @flow +import * as React from 'react' +import Modal from '@material-ui/core/Modal' +import { withStyles } from '@material-ui/core/styles' + +type Props = { + title: string, + description: string, + open: boolean, + handleClose: Function, + children: React$Node, + classes: Object, +} + +const styles = theme => ({ + root: { + alignItems: 'center', + justifyContent: 'center', + display: 'flex', + }, + paper: { + position: 'absolute', + width: theme.spacing.unit * 50, + backgroundColor: theme.palette.background.paper, + boxShadow: theme.shadows[5], + padding: theme.spacing.unit * 4, + }, +}) + +const GnoModal = ({ + title, description, open, children, handleClose, classes, +}: Props) => ( + +
+ { children } +
+
+) + +export default withStyles(styles)(GnoModal) From ebcfb2b30b633be866f134e40b64a5f34f8f9878 Mon Sep 17 00:00:00 2001 From: apanizo Date: Tue, 23 Oct 2018 10:04:18 +0200 Subject: [PATCH 21/68] Styling Modal custom component --- src/components/Modal/index.jsx | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/components/Modal/index.jsx b/src/components/Modal/index.jsx index f2c46b09fc..ce941c6289 100644 --- a/src/components/Modal/index.jsx +++ b/src/components/Modal/index.jsx @@ -12,7 +12,7 @@ type Props = { classes: Object, } -const styles = theme => ({ +const styles = () => ({ root: { alignItems: 'center', justifyContent: 'center', @@ -20,10 +20,15 @@ const styles = theme => ({ }, paper: { position: 'absolute', - width: theme.spacing.unit * 50, - backgroundColor: theme.palette.background.paper, - boxShadow: theme.shadows[5], - padding: theme.spacing.unit * 4, + top: '120px', + width: '500px', + height: '530px', + borderRadius: '3px', + backgroundColor: '#ffffff', + boxShadow: '0 0 5px 0 rgba(74, 85, 121, 0.5)', + '&:focus': { + outline: 'none', + }, }, }) From 019be0d12a5d869903d2e91ee973df65f42cc2d8 Mon Sep 17 00:00:00 2001 From: apanizo Date: Tue, 23 Oct 2018 10:05:09 +0200 Subject: [PATCH 22/68] Refactor Balance component. Moving columns generator to helper class --- src/routes/safe/component/Balances/Tokens.jsx | 10 ++++ .../safe/component/Balances/dataFetcher.js | 42 +++++++++++++++++ src/routes/safe/component/Balances/index.jsx | 46 ++----------------- src/theme/mui.js | 6 +++ 4 files changed, 61 insertions(+), 43 deletions(-) create mode 100644 src/routes/safe/component/Balances/Tokens.jsx diff --git a/src/routes/safe/component/Balances/Tokens.jsx b/src/routes/safe/component/Balances/Tokens.jsx new file mode 100644 index 0000000000..e5c95fe20b --- /dev/null +++ b/src/routes/safe/component/Balances/Tokens.jsx @@ -0,0 +1,10 @@ +// @flow +import * as React from 'react' + +const Tokens = () => ( + + Manage Tokens + +) + +export default Tokens diff --git a/src/routes/safe/component/Balances/dataFetcher.js b/src/routes/safe/component/Balances/dataFetcher.js index 6ae4dc9425..598f8e7877 100644 --- a/src/routes/safe/component/Balances/dataFetcher.js +++ b/src/routes/safe/component/Balances/dataFetcher.js @@ -1,5 +1,7 @@ // @flow +import { List } from 'immutable' import { buildOrderFieldFrom } from '~/components/Table/sorting' +import { type Column } from '~/components/Table/TableHead' export const BALANCE_TABLE_ASSET_ID = 'asset' export const BALANCE_TABLE_BALANCE_ID = 'balance' @@ -42,5 +44,45 @@ export const getBalanceData = (): Array => [ }, ] +export const generateColumns = () => { + const assetRow: Column = { + id: BALANCE_TABLE_ASSET_ID, + order: false, + numeric: false, + disablePadding: false, + label: 'Asset', + custom: false, + } + + const balanceRow: Column = { + id: BALANCE_TABLE_BALANCE_ID, + order: true, + numeric: true, + disablePadding: false, + label: 'Balance', + custom: false, + } + + const valueRow: Column = { + id: BALANCE_TABLE_VALUE_ID, + order: true, + numeric: true, + disablePadding: false, + label: 'Value', + custom: false, + } + + const actions: Column = { + id: 'actions', + order: false, + numeric: false, + disablePadding: false, + label: '', + custom: true, + } + + return List([assetRow, balanceRow, valueRow, actions]) +} + export const filterByZero = (data: Array, hideZero: boolean): Array => data.filter((row: BalanceRow) => (hideZero ? row[buildOrderFieldFrom(BALANCE_TABLE_BALANCE_ID)] !== 0 : true)) diff --git a/src/routes/safe/component/Balances/index.jsx b/src/routes/safe/component/Balances/index.jsx index a459d13497..c10fb7c2cf 100644 --- a/src/routes/safe/component/Balances/index.jsx +++ b/src/routes/safe/component/Balances/index.jsx @@ -1,6 +1,5 @@ // @flow import * as React from 'react' -import { List } from 'immutable' import classNames from 'classnames/bind' import CallMade from '@material-ui/icons/CallMade' import CallReceived from '@material-ui/icons/CallReceived' @@ -16,47 +15,8 @@ import Modal from '~/components/Modal' import { type Column } from '~/components/Table/TableHead' import Table from '~/components/Table' import { sm, xs } from '~/theme/variables' -import { getBalanceData, BALANCE_TABLE_ASSET_ID, BALANCE_TABLE_BALANCE_ID, BALANCE_TABLE_VALUE_ID, type BalanceRow, filterByZero } from './dataFetcher' - -const generateColumns = () => { - const assetRow: Column = { - id: BALANCE_TABLE_ASSET_ID, - order: false, - numeric: false, - disablePadding: false, - label: 'Asset', - custom: false, - } - - const balanceRow: Column = { - id: BALANCE_TABLE_BALANCE_ID, - order: true, - numeric: true, - disablePadding: false, - label: 'Balance', - custom: false, - } - - const valueRow: Column = { - id: BALANCE_TABLE_VALUE_ID, - order: true, - numeric: true, - disablePadding: false, - label: 'Value', - custom: false, - } - - const actions: Column = { - id: 'actions', - order: false, - numeric: false, - disablePadding: false, - label: '', - custom: true, - } - - return List([assetRow, balanceRow, valueRow, actions]) -} +import { getBalanceData, generateColumns, BALANCE_TABLE_ASSET_ID, type BalanceRow, filterByZero } from './dataFetcher' +import Tokens from './Tokens' type State = { hideZero: boolean, @@ -171,7 +131,7 @@ class Balances extends React.Component { handleClose={this.onHideToken} open={showToken} > - List of tokens will show here + diff --git a/src/theme/mui.js b/src/theme/mui.js index df7e32e4c1..a3961908f8 100644 --- a/src/theme/mui.js +++ b/src/theme/mui.js @@ -175,6 +175,12 @@ export default createMuiTheme({ fontWeight: 'normal', }, }, + MuiBackdrop: { + root: { + backdropFilter: 'blur(1px)', + backgroundColor: 'rgba(228, 232, 241, 0.75)', + }, + }, }, palette, }) From b79da026c365eb05cc0a57337fa7b53dbcc9bdae Mon Sep 17 00:00:00 2001 From: apanizo Date: Tue, 23 Oct 2018 16:44:20 +0200 Subject: [PATCH 23/68] Adding material-ui-search-bar library --- package.json | 1 + yarn.lock | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/package.json b/package.json index c3c4d7322d..b5e02792a7 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "immutable": "^4.0.0-rc.9", "jest": "^22.4.2", "json-loader": "^0.5.7", + "material-ui-search-bar": "^1.0.0-beta.13", "postcss-loader": "^2.1.1", "postcss-mixins": "^6.2.0", "postcss-simple-vars": "^4.1.0", diff --git a/yarn.lock b/yarn.lock index af0f87710c..9d04dcadfb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7975,6 +7975,13 @@ material-colors@^1.2.1: version "1.2.6" resolved "https://registry.yarnpkg.com/material-colors/-/material-colors-1.2.6.tgz#6d1958871126992ceecc72f4bcc4d8f010865f46" +material-ui-search-bar@^1.0.0-beta.13: + version "1.0.0-beta.13" + resolved "https://registry.yarnpkg.com/material-ui-search-bar/-/material-ui-search-bar-1.0.0-beta.13.tgz#08c246431666f91c3ca52df78987b86352783ee1" + dependencies: + classnames "^2.2.5" + prop-types "^15.5.8" + math-expression-evaluator@^1.2.14: version "1.2.17" resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac" From ac28119f13c30b7d2e8cc206d77e7667d45502e7 Mon Sep 17 00:00:00 2001 From: apanizo Date: Tue, 23 Oct 2018 16:47:32 +0200 Subject: [PATCH 24/68] Basic layout of Manage Token Modal --- src/routes/safe/component/Balances/Tokens.jsx | 10 -- .../safe/component/Balances/Tokens/index.jsx | 127 ++++++++++++++++++ src/routes/safe/component/Balances/index.jsx | 2 +- 3 files changed, 128 insertions(+), 11 deletions(-) delete mode 100644 src/routes/safe/component/Balances/Tokens.jsx create mode 100644 src/routes/safe/component/Balances/Tokens/index.jsx diff --git a/src/routes/safe/component/Balances/Tokens.jsx b/src/routes/safe/component/Balances/Tokens.jsx deleted file mode 100644 index e5c95fe20b..0000000000 --- a/src/routes/safe/component/Balances/Tokens.jsx +++ /dev/null @@ -1,10 +0,0 @@ -// @flow -import * as React from 'react' - -const Tokens = () => ( - - Manage Tokens - -) - -export default Tokens diff --git a/src/routes/safe/component/Balances/Tokens/index.jsx b/src/routes/safe/component/Balances/Tokens/index.jsx new file mode 100644 index 0000000000..6fb9f683ad --- /dev/null +++ b/src/routes/safe/component/Balances/Tokens/index.jsx @@ -0,0 +1,127 @@ +// @flow +import * as React from 'react' +import classNames from 'classnames/bind' +import SearchBar from 'material-ui-search-bar' +import { withStyles } from '@material-ui/core/styles' +import Close from '@material-ui/icons/Close' +import Search from '@material-ui/icons/Search' +import IconButton from '@material-ui/core/IconButton' +import Paragraph from '~/components/layout/Paragraph' +import Button from '~/components/layout/Button' +import Divider from '~/components/layout/Divider' +import Hairline from '~/components/layout/Hairline' +import Spacer from '~/components/Spacer' +import Row from '~/components/layout/Row' +import { lg, md, sm, xs, mediumFontSize } from '~/theme/variables' + +const styles = () => ({ + heading: { + padding: `${md} ${lg}`, + justifyContent: 'space-between', + }, + manage: { + fontSize: '24px', + }, + actions: { + height: '50px', + }, + close: { + height: '35px', + width: '35px', + }, + search: { + color: '#a2a8ba', + paddingLeft: sm, + }, + padding: { + padding: `0 ${md}`, + }, + add: { + fontWeight: 'normal', + paddingRight: md, + paddingLeft: md, + }, + searchInput: { + backgroundColor: 'transparent', + lineHeight: 'initial', + fontSize: mediumFontSize, + padding: 0, + '& > input::placeholder': { + letterSpacing: '-0.5px', + fontSize: mediumFontSize, + color: 'black', + }, + '& > input': { + letterSpacing: '-0.5px', + }, + }, + searchContainer: { + width: '180px', + marginLeft: xs, + marginRight: xs, + }, + searchRoot: { + letterSpacing: '-0.5px', + fontFamily: 'Roboto Mono, monospace', + fontSize: mediumFontSize, + border: 'none', + boxShadow: 'none', + }, + searchIcon: { + '&:hover': { + backgroundColor: 'transparent !important', + }, + }, +}) + +type Props = { + onClose: () => void, + classes: Object, +} + +class Tokens extends React.Component { + requestSearch = () => { + // eslint-disable-next-line + console.log("Filtering by name or symbol...") + } + + render() { + const { onClose, classes } = this.props + const searchClasses = { + input: classes.searchInput, + root: classes.searchRoot, + iconButton: classes.searchIcon, + searchContainer: classes.searchContainer, + } + + return ( + + + Manage Tokens + + + + + + + + } + /> + + + + + + + + ) + } +} + +export default withStyles(styles)(Tokens) diff --git a/src/routes/safe/component/Balances/index.jsx b/src/routes/safe/component/Balances/index.jsx index c10fb7c2cf..6db1c9927f 100644 --- a/src/routes/safe/component/Balances/index.jsx +++ b/src/routes/safe/component/Balances/index.jsx @@ -79,7 +79,7 @@ type Props = { class Balances extends React.Component { state = { hideZero: false, - showToken: false, + showToken: true, } onShowToken = () => { From 659215bb7ef0a333ddaa6e0268349ea2d6b587b9 Mon Sep 17 00:00:00 2001 From: apanizo Date: Wed, 24 Oct 2018 10:03:40 +0200 Subject: [PATCH 25/68] Creating Send and Receive empty components --- .../safe/component/Balances/Receive/index.jsx | 40 +++++++++++++++++++ .../safe/component/Balances/Send/index.jsx | 40 +++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 src/routes/safe/component/Balances/Receive/index.jsx create mode 100644 src/routes/safe/component/Balances/Send/index.jsx diff --git a/src/routes/safe/component/Balances/Receive/index.jsx b/src/routes/safe/component/Balances/Receive/index.jsx new file mode 100644 index 0000000000..62d2342049 --- /dev/null +++ b/src/routes/safe/component/Balances/Receive/index.jsx @@ -0,0 +1,40 @@ +// @flow +import * as React from 'react' +import { withStyles } from '@material-ui/core/styles' +import Close from '@material-ui/icons/Close' +import IconButton from '@material-ui/core/IconButton' +import Paragraph from '~/components/layout/Paragraph' +import Row from '~/components/layout/Row' +import { lg, md } from '~/theme/variables' + +const styles = () => ({ + heading: { + padding: `${md} ${lg}`, + justifyContent: 'space-between', + }, + manage: { + fontSize: '24px', + }, + close: { + height: '35px', + width: '35px', + }, +}) + +type Props = { + onClose: () => void, + classes: Object, +} + +const Send = ({ classes, onClose }: Props) => ( + + + Receive Funds + + + + + +) + +export default withStyles(styles)(Send) diff --git a/src/routes/safe/component/Balances/Send/index.jsx b/src/routes/safe/component/Balances/Send/index.jsx new file mode 100644 index 0000000000..4e89cc3c45 --- /dev/null +++ b/src/routes/safe/component/Balances/Send/index.jsx @@ -0,0 +1,40 @@ +// @flow +import * as React from 'react' +import { withStyles } from '@material-ui/core/styles' +import Close from '@material-ui/icons/Close' +import IconButton from '@material-ui/core/IconButton' +import Paragraph from '~/components/layout/Paragraph' +import Row from '~/components/layout/Row' +import { lg, md } from '~/theme/variables' + +const styles = () => ({ + heading: { + padding: `${md} ${lg}`, + justifyContent: 'space-between', + }, + manage: { + fontSize: '24px', + }, + close: { + height: '35px', + width: '35px', + }, +}) + +type Props = { + onClose: () => void, + classes: Object, +} + +const Send = ({ classes, onClose }: Props) => ( + + + Send Funds + + + + + +) + +export default withStyles(styles)(Send) From de8031a2468ce4c2475fa0b59e5b9e8a2615959b Mon Sep 17 00:00:00 2001 From: apanizo Date: Wed, 24 Oct 2018 10:17:13 +0200 Subject: [PATCH 26/68] #73 Using Modal for wrapping Send and Receive Tokens components --- src/routes/safe/component/Balances/index.jsx | 48 ++++++++++++++++++-- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/src/routes/safe/component/Balances/index.jsx b/src/routes/safe/component/Balances/index.jsx index 6db1c9927f..c4d9895179 100644 --- a/src/routes/safe/component/Balances/index.jsx +++ b/src/routes/safe/component/Balances/index.jsx @@ -17,6 +17,8 @@ import Table from '~/components/Table' import { sm, xs } from '~/theme/variables' import { getBalanceData, generateColumns, BALANCE_TABLE_ASSET_ID, type BalanceRow, filterByZero } from './dataFetcher' import Tokens from './Tokens' +import Send from './Send' +import Receive from './Receive' type State = { hideZero: boolean, @@ -79,7 +81,9 @@ type Props = { class Balances extends React.Component { state = { hideZero: false, - showToken: true, + showToken: false, + showSend: false, + showReceive: false, } onShowToken = () => { @@ -90,6 +94,22 @@ class Balances extends React.Component { this.setState(() => ({ showToken: false })) } + onShowSend = () => { + this.setState(() => ({ showSend: true })) + } + + onHideSend = () => { + this.setState(() => ({ showSend: false })) + } + + onShowReceive = () => { + this.setState(() => ({ showReceive: true })) + } + + onHideReceive = () => { + this.setState(() => ({ showReceive: false })) + } + handleChange = (e: SyntheticInputEvent) => { const { checked } = e.target @@ -97,7 +117,9 @@ class Balances extends React.Component { } render() { - const { hideZero, showToken } = this.state + const { + hideZero, showToken, showReceive, showSend, + } = this.state const { classes } = this.props const columns = generateColumns() @@ -131,7 +153,7 @@ class Balances extends React.Component { handleClose={this.onHideToken} open={showToken} > - + @@ -150,11 +172,11 @@ class Balances extends React.Component { )) } - - @@ -163,6 +185,22 @@ class Balances extends React.Component { ))}
+ + + + + +
) } From 70dd3767b473aba4a6f1b10015922dea98c47b34 Mon Sep 17 00:00:00 2001 From: apanizo Date: Wed, 24 Oct 2018 11:52:50 +0200 Subject: [PATCH 27/68] Applying option to fixed elements on top of table when sorting --- src/components/Table/index.jsx | 17 +++++++++++------ src/components/Table/sorting.js | 13 +++++++++++-- .../safe/component/Balances/dataFetcher.js | 12 ++++++++++-- src/routes/safe/component/Balances/index.jsx | 2 ++ 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/components/Table/index.jsx b/src/components/Table/index.jsx index 8882ba1f2b..d3b5c23183 100644 --- a/src/components/Table/index.jsx +++ b/src/components/Table/index.jsx @@ -15,6 +15,8 @@ type Props = { data: Array, classes: Object, children: Function, + size: number, + defaultFixed?: boolean, } type State = { @@ -46,8 +48,9 @@ const styles = { class GnoTable extends React.Component, State> { state = { page: 0, - order: 'desc', + order: 'asc', orderBy: this.props.defaultOrderBy, + fixed: !!this.props.defaultFixed, orderProp: false, rowsPerPage: 5, } @@ -60,7 +63,9 @@ class GnoTable extends React.Component, State> { order = 'asc' } - this.setState({ order, orderBy, orderProp }) + this.setState(() => ({ + order, orderBy, orderProp, fixed: false, + })) } handleChangePage = (page: number) => { @@ -74,11 +79,11 @@ class GnoTable extends React.Component, State> { render() { const { - data, label, columns, classes, children, + data, label, columns, classes, children, size, } = this.props const { - order, orderBy, page, orderProp, rowsPerPage, + order, orderBy, page, orderProp, rowsPerPage, fixed, } = this.state const backProps = { @@ -95,7 +100,7 @@ class GnoTable extends React.Component, State> { input: classes.white, } - const sortedData = stableSort(data, getSorting(order, orderBy, orderProp)) + const sortedData = stableSort(data, getSorting(order, orderBy, orderProp), fixed) .slice(page * rowsPerPage, ((page * rowsPerPage) + rowsPerPage)) return ( @@ -113,7 +118,7 @@ class GnoTable extends React.Component, State> { `${attr}Order` + const desc = (a: Object, b: Object, orderBy: string, orderProp: boolean) => { const order = orderProp ? buildOrderFieldFrom(orderBy) : orderBy @@ -15,7 +21,8 @@ const desc = (a: Object, b: Object, orderBy: string, orderProp: boolean) => { return 0 } -export const stableSort = (array: any, cmp: any) => { +export const stableSort = (array: any, cmp: any, fixed: boolean) => { + const fixedElems = fixed ? array.filter(elem => elem[FIXED]) : [] const stabilizedThis = array.map((el, index) => [el, index]) stabilizedThis.sort((a, b) => { @@ -27,7 +34,9 @@ export const stableSort = (array: any, cmp: any) => { return a[1] - b[1] }) - return stabilizedThis.map(el => el[0]) + const sortedElems = stabilizedThis.map(el => el[0]) + + return fixedElems.concat(sortedElems) } export type Order = 'asc' | 'desc' diff --git a/src/routes/safe/component/Balances/dataFetcher.js b/src/routes/safe/component/Balances/dataFetcher.js index 598f8e7877..3bbd84ff02 100644 --- a/src/routes/safe/component/Balances/dataFetcher.js +++ b/src/routes/safe/component/Balances/dataFetcher.js @@ -1,25 +1,33 @@ // @flow import { List } from 'immutable' -import { buildOrderFieldFrom } from '~/components/Table/sorting' +import { buildOrderFieldFrom, FIXED, type SortRow } from '~/components/Table/sorting' import { type Column } from '~/components/Table/TableHead' export const BALANCE_TABLE_ASSET_ID = 'asset' export const BALANCE_TABLE_BALANCE_ID = 'balance' export const BALANCE_TABLE_VALUE_ID = 'value' -export type BalanceRow = { +export type BalanceRow = SortRow & { asset: string, balance: string, value: string, } export const getBalanceData = (): Array => [ + { + [BALANCE_TABLE_ASSET_ID]: 'ABC Periodico', + [BALANCE_TABLE_BALANCE_ID]: '1.394 ABC', + [buildOrderFieldFrom(BALANCE_TABLE_BALANCE_ID)]: 1.394, + [BALANCE_TABLE_VALUE_ID]: '$3.1', + [buildOrderFieldFrom(BALANCE_TABLE_VALUE_ID)]: 3.1, + }, { [BALANCE_TABLE_ASSET_ID]: 'Ethereum', [BALANCE_TABLE_BALANCE_ID]: '9.394 ETH', [buildOrderFieldFrom(BALANCE_TABLE_BALANCE_ID)]: 9.394, [BALANCE_TABLE_VALUE_ID]: '$539.45', [buildOrderFieldFrom(BALANCE_TABLE_VALUE_ID)]: 539.45, + [FIXED]: true, }, { [BALANCE_TABLE_ASSET_ID]: 'Gnosis', diff --git a/src/routes/safe/component/Balances/index.jsx b/src/routes/safe/component/Balances/index.jsx index c4d9895179..2b243e0777 100644 --- a/src/routes/safe/component/Balances/index.jsx +++ b/src/routes/safe/component/Balances/index.jsx @@ -162,6 +162,8 @@ class Balances extends React.Component { defaultOrderBy={BALANCE_TABLE_ASSET_ID} columns={columns} data={filteredData} + size={filteredData.length} + defaultFixed > {(sortedData: Array) => sortedData.map((row: any, index: number) => ( From 20d9ca92f928b75c462917217e55a683c117fdb0 Mon Sep 17 00:00:00 2001 From: apanizo Date: Wed, 24 Oct 2018 12:14:48 +0200 Subject: [PATCH 28/68] Fix duplicated values when fixed sorting --- src/components/Table/sorting.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/Table/sorting.js b/src/components/Table/sorting.js index 65bd28f5cf..dbb5152af7 100644 --- a/src/components/Table/sorting.js +++ b/src/components/Table/sorting.js @@ -23,7 +23,8 @@ const desc = (a: Object, b: Object, orderBy: string, orderProp: boolean) => { export const stableSort = (array: any, cmp: any, fixed: boolean) => { const fixedElems = fixed ? array.filter(elem => elem[FIXED]) : [] - const stabilizedThis = array.map((el, index) => [el, index]) + const data = fixed ? array.filter(elem => !elem[FIXED]) : array + const stabilizedThis = data.map((el, index) => [el, index]) stabilizedThis.sort((a, b) => { const order = cmp(a[0], b[0]) From 31d0d941caad640f9ced199f78cdeba127180547 Mon Sep 17 00:00:00 2001 From: apanizo Date: Wed, 24 Oct 2018 12:15:23 +0200 Subject: [PATCH 29/68] Add empty space when Table's page is not fullfilled --- src/components/Table/index.jsx | 21 ++++++++++++++++++- .../safe/component/Balances/dataFetcher.js | 7 +++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/components/Table/index.jsx b/src/components/Table/index.jsx index d3b5c23183..6c85880db4 100644 --- a/src/components/Table/index.jsx +++ b/src/components/Table/index.jsx @@ -3,10 +3,13 @@ import * as React from 'react' import { List } from 'immutable' import Table from '@material-ui/core/Table' import TableBody from '@material-ui/core/TableBody' +import TableRow from '@material-ui/core/TableRow' +import TableCell from '@material-ui/core/TableCell' import { withStyles } from '@material-ui/core/styles' import TablePagination from '@material-ui/core/TablePagination' import { type Order, stableSort, getSorting } from '~/components/Table/sorting' import TableHead, { type Column } from '~/components/Table/TableHead' +import { xl } from '~/theme/variables' type Props = { label: string, @@ -42,9 +45,15 @@ const styles = { paginationRoot: { backgroundColor: 'white', boxShadow: '0 2px 4px 0 rgba(74, 85, 121, 0.5)', + marginBottom: xl, + }, + empty: { + }, } +const FIXED_HEIGHT = 49 + class GnoTable extends React.Component, State> { state = { page: 0, @@ -68,7 +77,7 @@ class GnoTable extends React.Component, State> { })) } - handleChangePage = (page: number) => { + handleChangePage = (e: SyntheticInputEvent, page: number) => { this.setState({ page }) } @@ -103,6 +112,11 @@ class GnoTable extends React.Component, State> { const sortedData = stableSort(data, getSorting(order, orderBy, orderProp), fixed) .slice(page * rowsPerPage, ((page * rowsPerPage) + rowsPerPage)) + const emptyRows = rowsPerPage - Math.min(rowsPerPage, data.length - (page * rowsPerPage)) + const emptyStyle = { + height: FIXED_HEIGHT * emptyRows, + } + return ( @@ -114,6 +128,11 @@ class GnoTable extends React.Component, State> { /> { children(sortedData) } + { emptyRows > 0 && + + + + }
=> [ + { + [BALANCE_TABLE_ASSET_ID]: 'CVL Journalism', + [BALANCE_TABLE_BALANCE_ID]: '234 CVL', + [buildOrderFieldFrom(BALANCE_TABLE_BALANCE_ID)]: 234, + [BALANCE_TABLE_VALUE_ID]: '$6700', + [buildOrderFieldFrom(BALANCE_TABLE_VALUE_ID)]: 6700, + }, { [BALANCE_TABLE_ASSET_ID]: 'ABC Periodico', [BALANCE_TABLE_BALANCE_ID]: '1.394 ABC', From deac8528fc3af26df2f9f4fcafea3c6e05f02f60 Mon Sep 17 00:00:00 2001 From: apanizo Date: Wed, 24 Oct 2018 12:25:18 +0200 Subject: [PATCH 30/68] Refactor Balance onShow onHide actions --- src/routes/safe/component/Balances/index.jsx | 44 +++++++------------- 1 file changed, 15 insertions(+), 29 deletions(-) diff --git a/src/routes/safe/component/Balances/index.jsx b/src/routes/safe/component/Balances/index.jsx index 2b243e0777..0bf62e2441 100644 --- a/src/routes/safe/component/Balances/index.jsx +++ b/src/routes/safe/component/Balances/index.jsx @@ -78,6 +78,8 @@ type Props = { classes: Object, } +type Action = 'Token' | 'Send' | 'Receive' + class Balances extends React.Component { state = { hideZero: false, @@ -86,28 +88,12 @@ class Balances extends React.Component { showReceive: false, } - onShowToken = () => { - this.setState(() => ({ showToken: true })) - } - - onHideToken = () => { - this.setState(() => ({ showToken: false })) - } - - onShowSend = () => { - this.setState(() => ({ showSend: true })) - } - - onHideSend = () => { - this.setState(() => ({ showSend: false })) - } - - onShowReceive = () => { - this.setState(() => ({ showReceive: true })) + onShow = (action: Action) => () => { + this.setState(() => ({ [`show${action}`]: true })) } - onHideReceive = () => { - this.setState(() => ({ showReceive: false })) + onHide = (action: Action) => () => { + this.setState(() => ({ [`show${action}`]: false })) } handleChange = (e: SyntheticInputEvent) => { @@ -144,16 +130,16 @@ class Balances extends React.Component { Hide zero balances - + Manage Tokens - +
@@ -174,11 +160,11 @@ class Balances extends React.Component { )) } - - @@ -190,18 +176,18 @@ class Balances extends React.Component { - + - +
) From 76c7907accccc2819c23697c89e8973263023d27 Mon Sep 17 00:00:00 2001 From: apanizo Date: Wed, 24 Oct 2018 13:05:48 +0200 Subject: [PATCH 31/68] Implement readonly on safe overview --- src/routes/safe/component/Balances/index.jsx | 27 +++++++------------ src/routes/safe/component/Layout.jsx | 28 +++++++++++++++++--- src/routes/safe/container/index.jsx | 19 ++++++------- 3 files changed, 42 insertions(+), 32 deletions(-) diff --git a/src/routes/safe/component/Balances/index.jsx b/src/routes/safe/component/Balances/index.jsx index 0bf62e2441..53b75bae9d 100644 --- a/src/routes/safe/component/Balances/index.jsx +++ b/src/routes/safe/component/Balances/index.jsx @@ -76,6 +76,7 @@ const styles = theme => ({ type Props = { classes: Object, + granted: boolean, } type Action = 'Token' | 'Send' | 'Receive' @@ -106,7 +107,7 @@ class Balances extends React.Component { const { hideZero, showToken, showReceive, showSend, } = this.state - const { classes } = this.props + const { classes, granted } = this.props const columns = generateColumns() const autoColumns = columns.filter(c => !c.custom) @@ -160,10 +161,12 @@ class Balances extends React.Component { )) } - + { granted && + + } + + {tokens.map((token: Token) => ( + + + {token.get('name')} + + + + + + + ))} + ) } diff --git a/src/routes/safe/component/Balances/index.jsx b/src/routes/safe/component/Balances/index.jsx index 29e8d58246..70ed19fb6e 100644 --- a/src/routes/safe/component/Balances/index.jsx +++ b/src/routes/safe/component/Balances/index.jsx @@ -16,11 +16,11 @@ import Paragraph from '~/components/layout/Paragraph' import Modal from '~/components/Modal' import { type Column, cellWidth } from '~/components/Table/TableHead' import Table from '~/components/Table' -import { sm, xs } from '~/theme/variables' import { getBalanceData, generateColumns, BALANCE_TABLE_ASSET_ID, type BalanceRow, filterByZero } from './dataFetcher' import Tokens from './Tokens' import Send from './Send' import Receive from './Receive' +import { styles } from './style' type State = { hideZero: boolean, @@ -29,55 +29,6 @@ type State = { showSend: boolean, } -const styles = theme => ({ - root: { - width: '20px', - marginRight: sm, - }, - zero: { - letterSpacing: '-0.5px', - }, - message: { - margin: `${sm} 0`, - }, - actionIcon: { - marginRight: theme.spacing.unit, - }, - iconSmall: { - fontSize: 16, - }, - hide: { - '&:hover': { - backgroundColor: '#fff3e2', - }, - '&:hover $actions': { - visibility: 'initial', - }, - }, - actions: { - justifyContent: 'flex-end', - visibility: 'hidden', - }, - send: { - minWidth: '0px', - marginRight: sm, - width: '70px', - }, - receive: { - minWidth: '0px', - width: '95px', - }, - leftIcon: { - marginRight: xs, - }, - links: { - textDecoration: 'underline', - '&:hover': { - cursor: 'pointer', - }, - }, -}) - type Props = { classes: Object, granted: boolean, @@ -89,7 +40,7 @@ type Action = 'Token' | 'Send' | 'Receive' class Balances extends React.Component { state = { hideZero: false, - showToken: false, + showToken: true, showSend: false, showReceive: false, } diff --git a/src/routes/safe/component/Balances/style.js b/src/routes/safe/component/Balances/style.js new file mode 100644 index 0000000000..ff0739212c --- /dev/null +++ b/src/routes/safe/component/Balances/style.js @@ -0,0 +1,51 @@ +// @flow +import { sm, xs } from '~/theme/variables' + +export const styles = (theme: Object) => ({ + root: { + width: '20px', + marginRight: sm, + }, + zero: { + letterSpacing: '-0.5px', + }, + message: { + margin: `${sm} 0`, + }, + actionIcon: { + marginRight: theme.spacing.unit, + }, + iconSmall: { + fontSize: 16, + }, + hide: { + '&:hover': { + backgroundColor: '#fff3e2', + }, + '&:hover $actions': { + visibility: 'initial', + }, + }, + actions: { + justifyContent: 'flex-end', + visibility: 'hidden', + }, + send: { + minWidth: '0px', + marginRight: sm, + width: '70px', + }, + receive: { + minWidth: '0px', + width: '95px', + }, + leftIcon: { + marginRight: xs, + }, + links: { + textDecoration: 'underline', + '&:hover': { + cursor: 'pointer', + }, + }, +}) diff --git a/src/theme/mui.js b/src/theme/mui.js index a3961908f8..7456c41a7a 100644 --- a/src/theme/mui.js +++ b/src/theme/mui.js @@ -181,6 +181,19 @@ export default createMuiTheme({ backgroundColor: 'rgba(228, 232, 241, 0.75)', }, }, + MuiListItemText: { + primary: { + fontFamily: 'Roboto Mono, monospace', + fontSize: mediumFontSize, + fontWeight: bolderFont, + color: primary, + }, + secondary: { + fontFamily: 'Roboto Mono, monospace', + fontSize: smallFontSize, + color: disabled, + }, + }, }, palette, }) From 7444963fec5f7614282b95ca2660432e29280721 Mon Sep 17 00:00:00 2001 From: apanizo Date: Wed, 31 Oct 2018 12:08:43 +0100 Subject: [PATCH 44/68] Auto height while list is loading #73 --- src/components/Modal/index.jsx | 3 +- .../safe/component/Balances/Tokens/index.jsx | 53 +++++++++++-------- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/components/Modal/index.jsx b/src/components/Modal/index.jsx index 0602ea75ed..6e82e33e9a 100644 --- a/src/components/Modal/index.jsx +++ b/src/components/Modal/index.jsx @@ -29,7 +29,8 @@ const styles = () => ({ '&:focus': { outline: 'none', }, - display: 'grid', + display: 'flex', + flexDirection: 'column', }, }) diff --git a/src/routes/safe/component/Balances/Tokens/index.jsx b/src/routes/safe/component/Balances/Tokens/index.jsx index 3e1e6f096a..32316156cd 100644 --- a/src/routes/safe/component/Balances/Tokens/index.jsx +++ b/src/routes/safe/component/Balances/Tokens/index.jsx @@ -6,6 +6,7 @@ import SearchBar from 'material-ui-search-bar' import { withStyles } from '@material-ui/core/styles' import MuiList from '@material-ui/core/List' import Img from '~/components/layout/Img' +import Block from '~/components/layout/Block' import ListItem from '@material-ui/core/ListItem' import ListItemIcon from '@material-ui/core/ListItemIcon' import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction' @@ -24,6 +25,9 @@ import { lg, md, sm, xs, mediumFontSize, border } from '~/theme/variables' import { type Token } from '~/routes/tokens/store/model/token' const styles = () => ({ + root: { + minHeight: '132px', + }, heading: { padding: `${md} ${lg}`, justifyContent: 'space-between', @@ -53,6 +57,7 @@ const styles = () => ({ list: { overflow: 'hidden', overflowY: 'scroll', + padding: 0, }, token: { minHeight: '50px', @@ -114,29 +119,31 @@ class Tokens extends React.Component { return ( - - Manage Tokens - - - - - - - - } - /> - - - - - - + + + Manage Tokens + + + + + + + + } + /> + + + + + + + {tokens.map((token: Token) => ( From a655d3657b5c307e50935e3ab8a5e171453d9b10 Mon Sep 17 00:00:00 2001 From: apanizo Date: Wed, 31 Oct 2018 12:45:37 +0100 Subject: [PATCH 45/68] Displaying tokens ordered ascending by symbol --- src/routes/safe/container/selector.js | 4 ++-- src/routes/tokens/store/selectors/index.js | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/routes/safe/container/selector.js b/src/routes/safe/container/selector.js index ad8adeae96..d58bc51263 100644 --- a/src/routes/safe/container/selector.js +++ b/src/routes/safe/container/selector.js @@ -7,7 +7,7 @@ import { type Safe } from '~/routes/safe/store/model/safe' import { type Owner } from '~/routes/safe/store/model/owner' import { type GlobalState } from '~/store' import { sameAddress } from '~/logic/wallets/ethAddresses' -import { activeTokensSelector, tokenListSelector } from '~/routes/tokens/store/selectors' +import { activeTokensSelector, orderedTokenListSelector } from '~/routes/tokens/store/selectors' import { type Token } from '~/routes/tokens/store/model/token' import { safeParamAddressSelector } from '../store/selectors' @@ -45,7 +45,7 @@ export const grantedSelector: Selector = crea export default createStructuredSelector({ safe: safeSelector, provider: providerNameSelector, - tokens: tokenListSelector, + tokens: orderedTokenListSelector, activeTokens: activeTokensSelector, granted: grantedSelector, userAddress: userAccountSelector, diff --git a/src/routes/tokens/store/selectors/index.js b/src/routes/tokens/store/selectors/index.js index 2339dcb51e..3a31a652e5 100644 --- a/src/routes/tokens/store/selectors/index.js +++ b/src/routes/tokens/store/selectors/index.js @@ -30,6 +30,11 @@ export const activeTokensSelector = createSelector( (tokens: List) => tokens.filter((token: Token) => token.get('status')), ) +export const orderedTokenListSelector = createSelector( + tokenListSelector, + (tokens: List) => tokens.sortBy((token: Token) => token.get('symbol')), +) + export const tokenAddressesSelector = createSelector( tokenListSelector, (balances: List) => { From ad0211fda0c86b08ff4184f3b1a8c1e4d5bde00e Mon Sep 17 00:00:00 2001 From: apanizo Date: Wed, 31 Oct 2018 12:50:28 +0100 Subject: [PATCH 46/68] Implementing Search Filter by Token --- .../safe/component/Balances/Tokens/index.jsx | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/routes/safe/component/Balances/Tokens/index.jsx b/src/routes/safe/component/Balances/Tokens/index.jsx index 32316156cd..0b4c30c475 100644 --- a/src/routes/safe/component/Balances/Tokens/index.jsx +++ b/src/routes/safe/component/Balances/Tokens/index.jsx @@ -102,10 +102,24 @@ type Props = { tokens: List, } -class Tokens extends React.Component { - requestSearch = () => { - // eslint-disable-next-line - console.log("Filtering by name or symbol...") +type State = { + filter: string, +} + +const filterBy = (filter: string, tokens: List): List => + tokens.filter((token: Token) => !filter || token.get('symbol').toLowerCase().startsWith(filter.toLowerCase())) + +class Tokens extends React.Component { + state = { + filter: '', + } + + onCancelSearch = () => { + this.setState(() => ({ filter: '' })) + } + + onChangeSearchBar = (value) => { + this.setState(() => ({ filter: value })) } render() { @@ -117,6 +131,8 @@ class Tokens extends React.Component { searchContainer: classes.searchContainer, } + const filteredTokens = filterBy(this.state.filter, tokens) + return ( @@ -132,20 +148,21 @@ class Tokens extends React.Component { } + onChange={this.onChangeSearchBar} + onCancelSearch={this.onCancelSearch} /> - - {tokens.map((token: Token) => ( + {filteredTokens.map((token: Token) => ( {token.get('name')} From fba1b9cbcdd45d5f257d99fed47043ea0cbf47b0 Mon Sep 17 00:00:00 2001 From: apanizo Date: Wed, 31 Oct 2018 13:16:07 +0100 Subject: [PATCH 47/68] Enabling and disabling Tokens logic --- .../safe/component/Balances/Tokens/actions.js | 13 +++++++++ .../safe/component/Balances/Tokens/index.jsx | 27 ++++++++++++++++--- src/routes/safe/component/Balances/index.jsx | 7 +++-- src/routes/safe/component/Layout.jsx | 8 +++++- 4 files changed, 48 insertions(+), 7 deletions(-) create mode 100644 src/routes/safe/component/Balances/Tokens/actions.js diff --git a/src/routes/safe/component/Balances/Tokens/actions.js b/src/routes/safe/component/Balances/Tokens/actions.js new file mode 100644 index 0000000000..5184fdcccb --- /dev/null +++ b/src/routes/safe/component/Balances/Tokens/actions.js @@ -0,0 +1,13 @@ +// @flow +import enableToken from '~/routes/tokens/store/actions/enableToken' +import disableToken from '~/routes/tokens/store/actions/disableToken' + +export type Actions = { + enableToken: typeof enableToken, + disableToken: typeof disableToken, +} + +export default { + enableToken, + disableToken, +} diff --git a/src/routes/safe/component/Balances/Tokens/index.jsx b/src/routes/safe/component/Balances/Tokens/index.jsx index 0b4c30c475..24b9cbfe56 100644 --- a/src/routes/safe/component/Balances/Tokens/index.jsx +++ b/src/routes/safe/component/Balances/Tokens/index.jsx @@ -1,5 +1,6 @@ // @flow import * as React from 'react' +import { connect } from 'react-redux' import { List } from 'immutable' import classNames from 'classnames/bind' import SearchBar from 'material-ui-search-bar' @@ -23,6 +24,7 @@ import Spacer from '~/components/Spacer' import Row from '~/components/layout/Row' import { lg, md, sm, xs, mediumFontSize, border } from '~/theme/variables' import { type Token } from '~/routes/tokens/store/model/token' +import actions, { type Actions } from './actions' const styles = () => ({ root: { @@ -96,10 +98,11 @@ const styles = () => ({ }, }) -type Props = { +type Props = Actions & { onClose: () => void, classes: Object, tokens: List, + safeAddress: string, } type State = { @@ -122,6 +125,19 @@ class Tokens extends React.Component { this.setState(() => ({ filter: value })) } + onSwitch = (token: Token) => (e: SyntheticInputEvent) => { + const { checked } = e.target + const { safeAddress, enableToken, disableToken } = this.props + + if (checked) { + enableToken(safeAddress, token) + + return + } + + disableToken(safeAddress, token) + } + render() { const { onClose, classes, tokens } = this.props const searchClasses = { @@ -170,8 +186,8 @@ class Tokens extends React.Component { @@ -182,4 +198,7 @@ class Tokens extends React.Component { } } -export default withStyles(styles)(Tokens) +const TokenComponent = withStyles(styles)(Tokens) + +export default connect(undefined, actions)(TokenComponent) + diff --git a/src/routes/safe/component/Balances/index.jsx b/src/routes/safe/component/Balances/index.jsx index 70ed19fb6e..977b7b368f 100644 --- a/src/routes/safe/component/Balances/index.jsx +++ b/src/routes/safe/component/Balances/index.jsx @@ -33,6 +33,7 @@ type Props = { classes: Object, granted: boolean, tokens: List, + safeAddress: string, } type Action = 'Token' | 'Send' | 'Receive' @@ -63,7 +64,9 @@ class Balances extends React.Component { const { hideZero, showToken, showReceive, showSend, } = this.state - const { classes, granted, tokens } = this.props + const { + classes, granted, tokens, safeAddress, + } = this.props const columns = generateColumns() const autoColumns = columns.filter(c => !c.custom) @@ -96,7 +99,7 @@ class Balances extends React.Component { handleClose={this.onHide('Token')} open={showToken} > - + diff --git a/src/routes/safe/component/Layout.jsx b/src/routes/safe/component/Layout.jsx index b8c2ca534f..d2c048213c 100644 --- a/src/routes/safe/component/Layout.jsx +++ b/src/routes/safe/component/Layout.jsx @@ -122,7 +122,13 @@ class Layout extends React.Component { - {value === 0 && } + {value === 0 && + } ) } From 4e019af2a48a3f81da1876947b0595d7f64fb73d Mon Sep 17 00:00:00 2001 From: apanizo Date: Wed, 31 Oct 2018 13:21:13 +0100 Subject: [PATCH 48/68] Refactor: Moving Token styles to separate file #73 --- .../safe/component/Balances/Tokens/index.jsx | 74 +------------------ .../safe/component/Balances/Tokens/style.js | 74 +++++++++++++++++++ src/routes/safe/component/Balances/index.jsx | 2 +- 3 files changed, 76 insertions(+), 74 deletions(-) create mode 100644 src/routes/safe/component/Balances/Tokens/style.js diff --git a/src/routes/safe/component/Balances/Tokens/index.jsx b/src/routes/safe/component/Balances/Tokens/index.jsx index 24b9cbfe56..51a3c65eb4 100644 --- a/src/routes/safe/component/Balances/Tokens/index.jsx +++ b/src/routes/safe/component/Balances/Tokens/index.jsx @@ -22,81 +22,9 @@ import Divider from '~/components/layout/Divider' import Hairline from '~/components/layout/Hairline' import Spacer from '~/components/Spacer' import Row from '~/components/layout/Row' -import { lg, md, sm, xs, mediumFontSize, border } from '~/theme/variables' import { type Token } from '~/routes/tokens/store/model/token' import actions, { type Actions } from './actions' - -const styles = () => ({ - root: { - minHeight: '132px', - }, - heading: { - padding: `${md} ${lg}`, - justifyContent: 'space-between', - }, - manage: { - fontSize: '24px', - }, - actions: { - height: '50px', - }, - close: { - height: '35px', - width: '35px', - }, - search: { - color: '#a2a8ba', - paddingLeft: sm, - }, - padding: { - padding: `0 ${md}`, - }, - add: { - fontWeight: 'normal', - paddingRight: md, - paddingLeft: md, - }, - list: { - overflow: 'hidden', - overflowY: 'scroll', - padding: 0, - }, - token: { - minHeight: '50px', - borderBottom: `1px solid ${border}`, - }, - searchInput: { - backgroundColor: 'transparent', - lineHeight: 'initial', - fontSize: mediumFontSize, - padding: 0, - '& > input::placeholder': { - letterSpacing: '-0.5px', - fontSize: mediumFontSize, - color: 'black', - }, - '& > input': { - letterSpacing: '-0.5px', - }, - }, - searchContainer: { - width: '180px', - marginLeft: xs, - marginRight: xs, - }, - searchRoot: { - letterSpacing: '-0.5px', - fontFamily: 'Roboto Mono, monospace', - fontSize: mediumFontSize, - border: 'none', - boxShadow: 'none', - }, - searchIcon: { - '&:hover': { - backgroundColor: 'transparent !important', - }, - }, -}) +import { styles } from './style' type Props = Actions & { onClose: () => void, diff --git a/src/routes/safe/component/Balances/Tokens/style.js b/src/routes/safe/component/Balances/Tokens/style.js new file mode 100644 index 0000000000..1d3d5c61d8 --- /dev/null +++ b/src/routes/safe/component/Balances/Tokens/style.js @@ -0,0 +1,74 @@ +// @flow +import { lg, md, sm, xs, mediumFontSize, border } from '~/theme/variables' + +export const styles = () => ({ + root: { + minHeight: '132px', + }, + heading: { + padding: `${md} ${lg}`, + justifyContent: 'space-between', + }, + manage: { + fontSize: '24px', + }, + actions: { + height: '50px', + }, + close: { + height: '35px', + width: '35px', + }, + search: { + color: '#a2a8ba', + paddingLeft: sm, + }, + padding: { + padding: `0 ${md}`, + }, + add: { + fontWeight: 'normal', + paddingRight: md, + paddingLeft: md, + }, + list: { + overflow: 'hidden', + overflowY: 'scroll', + padding: 0, + }, + token: { + minHeight: '50px', + borderBottom: `1px solid ${border}`, + }, + searchInput: { + backgroundColor: 'transparent', + lineHeight: 'initial', + fontSize: mediumFontSize, + padding: 0, + '& > input::placeholder': { + letterSpacing: '-0.5px', + fontSize: mediumFontSize, + color: 'black', + }, + '& > input': { + letterSpacing: '-0.5px', + }, + }, + searchContainer: { + width: '180px', + marginLeft: xs, + marginRight: xs, + }, + searchRoot: { + letterSpacing: '-0.5px', + fontFamily: 'Roboto Mono, monospace', + fontSize: mediumFontSize, + border: 'none', + boxShadow: 'none', + }, + searchIcon: { + '&:hover': { + backgroundColor: 'transparent !important', + }, + }, +}) diff --git a/src/routes/safe/component/Balances/index.jsx b/src/routes/safe/component/Balances/index.jsx index 977b7b368f..df15dfd66f 100644 --- a/src/routes/safe/component/Balances/index.jsx +++ b/src/routes/safe/component/Balances/index.jsx @@ -41,7 +41,7 @@ type Action = 'Token' | 'Send' | 'Receive' class Balances extends React.Component { state = { hideZero: false, - showToken: true, + showToken: false, showSend: false, showReceive: false, } From 24dfd80122de9998a0df1879a1e44da2d9476043 Mon Sep 17 00:00:00 2001 From: apanizo Date: Mon, 5 Nov 2018 09:44:15 +0100 Subject: [PATCH 49/68] Fetching active Tokens and showing them in Balances' Tab #73 --- .../safe/component/Balances/dataFetcher.js | 45 +++++-------------- src/routes/safe/component/Balances/index.jsx | 5 ++- 2 files changed, 15 insertions(+), 35 deletions(-) diff --git a/src/routes/safe/component/Balances/dataFetcher.js b/src/routes/safe/component/Balances/dataFetcher.js index 0ad3f4057f..940982256b 100644 --- a/src/routes/safe/component/Balances/dataFetcher.js +++ b/src/routes/safe/component/Balances/dataFetcher.js @@ -1,5 +1,6 @@ // @flow import { List } from 'immutable' +import { type Token } from '~/routes/tokens/store/model/token' import { buildOrderFieldFrom, FIXED, type SortRow } from '~/components/Table/sorting' import { type Column } from '~/components/Table/TableHead' @@ -14,39 +15,17 @@ type BalanceData = { export type BalanceRow = SortRow -export const getBalanceData = (): Array => [ - { - [BALANCE_TABLE_ASSET_ID]: 'CVL Journalism', - [BALANCE_TABLE_BALANCE_ID]: '234 CVL', - [buildOrderFieldFrom(BALANCE_TABLE_BALANCE_ID)]: 234, - }, - { - [BALANCE_TABLE_ASSET_ID]: 'ABC Periodico', - [BALANCE_TABLE_BALANCE_ID]: '1.394 ABC', - [buildOrderFieldFrom(BALANCE_TABLE_BALANCE_ID)]: 1.394, - }, - { - [BALANCE_TABLE_ASSET_ID]: 'Ethereum', - [BALANCE_TABLE_BALANCE_ID]: '9.394 ETH', - [buildOrderFieldFrom(BALANCE_TABLE_BALANCE_ID)]: 9.394, - [FIXED]: true, - }, - { - [BALANCE_TABLE_ASSET_ID]: 'Gnosis', - [BALANCE_TABLE_BALANCE_ID]: '0.599 GNO', - [buildOrderFieldFrom(BALANCE_TABLE_BALANCE_ID)]: 0.559, - }, - { - [BALANCE_TABLE_ASSET_ID]: 'OmiseGO', - [BALANCE_TABLE_BALANCE_ID]: '39.922 OMG', - [buildOrderFieldFrom(BALANCE_TABLE_BALANCE_ID)]: 39.922, - }, - { - [BALANCE_TABLE_ASSET_ID]: 'Moe Feo', - [BALANCE_TABLE_BALANCE_ID]: '0 MOE', - [buildOrderFieldFrom(BALANCE_TABLE_BALANCE_ID)]: 0, - }, -] +export const getBalanceData = (activeTokens: List): Array => { + const rows = activeTokens.map((token: Token) => ({ + [BALANCE_TABLE_ASSET_ID]: token.get('name'), + [BALANCE_TABLE_BALANCE_ID]: `${token.get('funds')} ${token.get('symbol')}`, + [buildOrderFieldFrom(BALANCE_TABLE_BALANCE_ID)]: Number(token.get('funds')), + [FIXED]: token.get('symbol') === 'ETH', + })) + + return Array.from(rows) +} + export const generateColumns = () => { const assetRow: Column = { diff --git a/src/routes/safe/component/Balances/index.jsx b/src/routes/safe/component/Balances/index.jsx index df15dfd66f..c63312f4a0 100644 --- a/src/routes/safe/component/Balances/index.jsx +++ b/src/routes/safe/component/Balances/index.jsx @@ -33,6 +33,7 @@ type Props = { classes: Object, granted: boolean, tokens: List, + activeTokens: List, safeAddress: string, } @@ -65,7 +66,7 @@ class Balances extends React.Component { hideZero, showToken, showReceive, showSend, } = this.state const { - classes, granted, tokens, safeAddress, + classes, granted, tokens, safeAddress, activeTokens, } = this.props const columns = generateColumns() @@ -74,7 +75,7 @@ class Balances extends React.Component { root: classes.root, } - const filteredData = filterByZero(getBalanceData(), hideZero) + const filteredData = filterByZero(getBalanceData(activeTokens), hideZero) return ( From 99b3eb8f04eeee4f9edcb93313fe2e14b97c72e6 Mon Sep 17 00:00:00 2001 From: apanizo Date: Mon, 5 Nov 2018 09:45:40 +0100 Subject: [PATCH 50/68] Fix style showing spinner and empty table while it is fetching token's info --- src/components/Table/index.jsx | 56 +++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/src/components/Table/index.jsx b/src/components/Table/index.jsx index 66785a9dbe..bd75c82f80 100644 --- a/src/components/Table/index.jsx +++ b/src/components/Table/index.jsx @@ -1,11 +1,14 @@ // @flow import * as React from 'react' +import classNames from 'classnames' import { List } from 'immutable' +import Row from '~/components/layout/Row' import Table from '@material-ui/core/Table' import TableBody from '@material-ui/core/TableBody' import TableRow from '@material-ui/core/TableRow' import TableCell from '@material-ui/core/TableCell' import { withStyles } from '@material-ui/core/styles' +import CircularProgress from '@material-ui/core/CircularProgress' import TablePagination from '@material-ui/core/TablePagination' import { type Order, stableSort, getSorting } from '~/components/Table/sorting' import TableHead, { type Column } from '~/components/Table/TableHead' @@ -48,8 +51,10 @@ const styles = { boxShadow: '0 2px 4px 0 rgba(74, 85, 121, 0.5)', marginBottom: xl, }, - empty: { - + loader: { + alignItems: 'center', + justifyContent: 'center', + backgroundColor: 'white', }, } @@ -78,6 +83,10 @@ class GnoTable extends React.Component, State> { })) } + getEmptyStyle = (emptyRows: number) => ({ + height: FIXED_HEIGHT * emptyRows, + }) + handleChangePage = (e: SyntheticInputEvent, page: number) => { this.setState({ page }) } @@ -114,28 +123,33 @@ class GnoTable extends React.Component, State> { .slice(page * rowsPerPage, ((page * rowsPerPage) + rowsPerPage)) const emptyRows = rowsPerPage - Math.min(rowsPerPage, data.length - (page * rowsPerPage)) - const emptyStyle = { - height: FIXED_HEIGHT * emptyRows, - } + const isEmpty = size === 0 return ( - - - - { children(sortedData) } - { emptyRows > 0 && - - - - } - -
+ { !isEmpty && + + + + { children(sortedData) } + { emptyRows > 0 && + + + + } + +
+ } + { isEmpty && + + + + } Date: Mon, 5 Nov 2018 21:55:53 +0100 Subject: [PATCH 51/68] Enabling search by name in Token List --- src/routes/safe/component/Balances/Tokens/index.jsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/routes/safe/component/Balances/Tokens/index.jsx b/src/routes/safe/component/Balances/Tokens/index.jsx index 51a3c65eb4..2060f6578b 100644 --- a/src/routes/safe/component/Balances/Tokens/index.jsx +++ b/src/routes/safe/component/Balances/Tokens/index.jsx @@ -38,7 +38,10 @@ type State = { } const filterBy = (filter: string, tokens: List): List => - tokens.filter((token: Token) => !filter || token.get('symbol').toLowerCase().startsWith(filter.toLowerCase())) + tokens.filter((token: Token) => !filter || + token.get('symbol').toLowerCase().includes(filter.toLowerCase()) || + token.get('name').toLowerCase().includes(filter.toLowerCase())) + class Tokens extends React.Component { state = { From 0e31239dcb1d586515d51719ffd3f31ecdf80363 Mon Sep 17 00:00:00 2001 From: Adolfo Panizo Date: Mon, 5 Nov 2018 22:04:31 +0100 Subject: [PATCH 52/68] Safe not found message --- src/routes/safe/component/Layout.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/safe/component/Layout.jsx b/src/routes/safe/component/Layout.jsx index d2c048213c..7945a2ab94 100644 --- a/src/routes/safe/component/Layout.jsx +++ b/src/routes/safe/component/Layout.jsx @@ -81,7 +81,7 @@ class Layout extends React.Component { const { value } = this.state if (!safe) { - return + return } // const address = safe.get('address') From cbc42e775fbbd47cf3ca9e35e0015c21a112903c Mon Sep 17 00:00:00 2001 From: apanizo Date: Tue, 6 Nov 2018 12:13:13 +0100 Subject: [PATCH 53/68] Adapting fonts sizes #72 --- .storybook/preview-head.html | 4 ++-- public/index.html | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.storybook/preview-head.html b/.storybook/preview-head.html index 52da703295..9d984b585e 100644 --- a/.storybook/preview-head.html +++ b/.storybook/preview-head.html @@ -1,3 +1,3 @@ - - + + \ No newline at end of file diff --git a/public/index.html b/public/index.html index 9e3064f416..56a506080e 100644 --- a/public/index.html +++ b/public/index.html @@ -4,8 +4,8 @@ - - + + Multisig Safe From b4f4e3fdf05d90490820fca8b95e1bb4929bbed4 Mon Sep 17 00:00:00 2001 From: apanizo Date: Tue, 6 Nov 2018 12:13:40 +0100 Subject: [PATCH 54/68] Fix welcome view ui details #72 --- src/components/Header/component/Layout.jsx | 4 ++-- src/components/layout/Heading/index.scss | 3 +-- src/index.scss | 3 +++ src/routes/welcome/components/Layout.jsx | 12 +++++------- src/theme/mui.js | 10 +++++++--- src/theme/variables.js | 5 ++++- 6 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/components/Header/component/Layout.jsx b/src/components/Header/component/Layout.jsx index ed1ff217dc..df166bd86d 100644 --- a/src/components/Header/component/Layout.jsx +++ b/src/components/Header/component/Layout.jsx @@ -31,9 +31,9 @@ const styles = () => ({ left: '4px', }, summary: { - borderBottom: `solid 2px ${border}`, + borderBottom: `solid 1px ${border}`, alignItems: 'center', - height: '52px', + height: '53px', backgroundColor: 'white', }, logo: { diff --git a/src/components/layout/Heading/index.scss b/src/components/layout/Heading/index.scss index 6c3f3fa64a..e3c38b5000 100644 --- a/src/components/layout/Heading/index.scss +++ b/src/components/layout/Heading/index.scss @@ -6,7 +6,7 @@ .h1 { line-height: 36px; - font-weight: 500; + font-weight: $bolderFont; letter-spacing: -1px; font-size: $(fontSizeHeadingLg)px; } @@ -29,7 +29,6 @@ .h4 { line-height: 21px; - letter-spacing: -0.5px; font-family: 'Roboto Mono', monospace; font-size: $(fontSizeHeadingXs)px; } diff --git a/src/index.scss b/src/index.scss index 2948797dc7..ce1b0fcd41 100644 --- a/src/index.scss +++ b/src/index.scss @@ -15,6 +15,9 @@ body { font-size: $mediumFontSize; margin: 0; background-color: $background; + text-rendering: geometricPrecision; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } body>div:first-child { diff --git a/src/routes/welcome/components/Layout.jsx b/src/routes/welcome/components/Layout.jsx index 7766d5f317..10985fb905 100644 --- a/src/routes/welcome/components/Layout.jsx +++ b/src/routes/welcome/components/Layout.jsx @@ -6,7 +6,7 @@ import Img from '~/components/layout/Img' import Button from '~/components/layout/Button' import Link from '~/components/layout/Link' import { OPEN_ADDRESS } from '~/routes/routes' -import { sm } from '~/theme/variables' +import { marginButtonImg } from '~/theme/variables' import styles from './Layout.scss' const safe = require('../assets/safe.svg') @@ -22,7 +22,7 @@ type SafeProps = { } const buttonStyle = { - marginLeft: sm, + marginLeft: marginButtonImg, } export const CreateSafe = ({ size, provider }: SafeProps) => ( @@ -35,7 +35,7 @@ export const CreateSafe = ({ size, provider }: SafeProps) => ( disabled={!provider} minWidth={240} > - Safe + Safe
Create new Safe
) @@ -50,7 +50,7 @@ export const LoadSafe = ({ size, provider }: SafeProps) => ( disabled={!provider} minWidth={240} > - Safe + Safe
Load existing Safe
) @@ -58,10 +58,8 @@ export const LoadSafe = ({ size, provider }: SafeProps) => ( const Welcome = ({ provider }: Props) => ( - - Welcome to the Gnosis - + Welcome to the Gnosis
Safe Team Edition
diff --git a/src/theme/mui.js b/src/theme/mui.js index 7456c41a7a..3253bc1265 100644 --- a/src/theme/mui.js +++ b/src/theme/mui.js @@ -1,7 +1,7 @@ // @flow import red from '@material-ui/core/colors/red' import { createMuiTheme } from '@material-ui/core/styles' -import { largeFontSize, mediumFontSize, smallFontSize, disabled, primary, secondary, md, lg, background, bolderFont, boldFont } from './variables' +import { largeFontSize, mediumFontSize, smallFontSize, disabled, primary, secondary, md, lg, background, bolderFont, boldFont, buttonLargeFontSize } from './variables' export type WithStyles = { classes: Object, @@ -29,7 +29,7 @@ export default createMuiTheme({ MuiButton: { root: { fontFamily: 'Roboto Mono, monospace', - letterSpacing: '1px', + letterSpacing: '0.9px', '&:disabled': { color: disabled, }, @@ -38,13 +38,17 @@ export default createMuiTheme({ disabled: { cursor: 'pointer', }, + contained: { + boxShadow: 'none', + }, containedPrimary: { backgroundColor: secondary, }, sizeLarge: { padding: `${md} ${lg}`, minHeight: '52px', - fontSize: mediumFontSize, + fontSize: buttonLargeFontSize, + fontWeight: boldFont, }, sizeSmall: { minWidth: '130px', diff --git a/src/theme/variables.js b/src/theme/variables.js index b8bcdb42d3..7c6ff8fb3c 100644 --- a/src/theme/variables.js +++ b/src/theme/variables.js @@ -1,5 +1,5 @@ // @flow -const border = '#eaebef' +const border = '#e4e8f1' const background = '#f4f4f9' const primary = '#4a5579' const secondary = '#467ee5' // '#13222b' @@ -14,6 +14,7 @@ const md = '16px' const lg = '24px' const xl = '32px' const xxl = '40px' +const marginButtonImg = '12px' module.exports = Object.assign({}, { primary, @@ -31,10 +32,12 @@ module.exports = Object.assign({}, { xl, xxl, border, + marginButtonImg, fontSizeHeadingXs: 13, fontSizeHeadingSm: 18, fontSizeHeadingMd: 21, fontSizeHeadingLg: 32, + buttonLargeFontSize: '12px', lightFont: 300, regularFont: 400, bolderFont: 500, From f6e0fcb57b6bcfc99811a0445bbe26bbee35941d Mon Sep 17 00:00:00 2001 From: apanizo Date: Tue, 6 Nov 2018 12:25:52 +0100 Subject: [PATCH 55/68] Header Provider info CSS fix #72 --- src/components/Header/component/ProviderInfo/index.jsx | 2 +- src/components/layout/Divider/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Header/component/ProviderInfo/index.jsx b/src/components/Header/component/ProviderInfo/index.jsx index fa00ea9e69..c654b713c1 100644 --- a/src/components/Header/component/ProviderInfo/index.jsx +++ b/src/components/Header/component/ProviderInfo/index.jsx @@ -54,7 +54,7 @@ const ProviderInfo = ({ Connection status - {providerText} + {providerText} {cutAddress}
diff --git a/src/components/layout/Divider/index.js b/src/components/layout/Divider/index.js index 7962d5694a..3a73eae83e 100644 --- a/src/components/layout/Divider/index.js +++ b/src/components/layout/Divider/index.js @@ -4,7 +4,7 @@ import { border } from '~/theme/variables' const style = { height: '100%', - border: `solid 1px ${border}`, + borderRight: `solid 1px ${border}`, } const Divider = () => ( From 51a807be29e0f1dd3c7b9c792021480250f034ce Mon Sep 17 00:00:00 2001 From: apanizo Date: Tue, 6 Nov 2018 16:25:01 +0100 Subject: [PATCH 56/68] Fix Header Provider info statusses dots --- src/components/Header/assets/key.svg | 3 ++ .../component/ProviderDisconnected/index.jsx | 33 ++++++++++++++++--- .../Header/component/ProviderInfo/index.jsx | 28 +++++++++++----- 3 files changed, 52 insertions(+), 12 deletions(-) create mode 100644 src/components/Header/assets/key.svg diff --git a/src/components/Header/assets/key.svg b/src/components/Header/assets/key.svg new file mode 100644 index 0000000000..a1378604da --- /dev/null +++ b/src/components/Header/assets/key.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/Header/component/ProviderDisconnected/index.jsx b/src/components/Header/component/ProviderDisconnected/index.jsx index 9c3bc71534..f59aee2b74 100644 --- a/src/components/Header/component/ProviderDisconnected/index.jsx +++ b/src/components/Header/component/ProviderDisconnected/index.jsx @@ -1,13 +1,15 @@ // @flow import * as React from 'react' import { withStyles } from '@material-ui/core/styles' +import Dot from '@material-ui/icons/FiberManualRecord' import Paragraph from '~/components/layout/Paragraph' +import Block from '~/components/layout/Block' import Col from '~/components/layout/Col' import Img from '~/components/layout/Img' import { type Open } from '~/components/hoc/OpenHoc' -import { md } from '~/theme/variables' +import { sm, fancy } from '~/theme/variables' -const connectWallet = require('../../assets/connect-wallet.svg') +const connectWallet = require('../../assets/key.svg') type Props = Open & { classes: Object, @@ -19,20 +21,43 @@ const styles = () => ({ fontFamily: 'Montserrat, sans-serif', }, account: { - padding: `0 ${md}`, + paddingRight: sm, display: 'flex', flexDirection: 'column', justifyContent: 'center', + alignItems: 'start', flexGrow: 1, }, connect: { letterSpacing: '-0.5px', }, + logo: { + height: '15px', + width: '15px', + top: '12px', + position: 'relative', + right: '10px', + backgroundColor: '#ffffff', + borderRadius: '15px', + color: fancy, + }, + key: { + width: '38px', + height: '35px', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + backgroundColor: '#f4f4f9', + borderRadius: '20px', + }, }) const ProviderDesconnected = ({ classes }: Props) => ( - Status connected + + Status disconnected + + Not Connected Connect Wallet diff --git a/src/components/Header/component/ProviderInfo/index.jsx b/src/components/Header/component/ProviderInfo/index.jsx index c654b713c1..e5f51d9f12 100644 --- a/src/components/Header/component/ProviderInfo/index.jsx +++ b/src/components/Header/component/ProviderInfo/index.jsx @@ -1,15 +1,16 @@ // @flow import * as React from 'react' +import classNames from 'classnames' import { withStyles } from '@material-ui/core/styles' import Paragraph from '~/components/layout/Paragraph' import Col from '~/components/layout/Col' -import Img from '~/components/layout/Img' +import Dot from '@material-ui/icons/FiberManualRecord' import { sm } from '~/theme/variables' import Identicon from '~/components/Identicon' import { shortVersionOf } from '~/logic/wallets/ethAddresses' -const connectedLogo = require('../../assets/connected.svg') -const connectedWarning = require('../../assets/connected-error.svg') +const connectedBg = '#00c4c4' +const warningBg = '#ffc05f' type Props = { provider: string, @@ -24,15 +25,26 @@ const styles = () => ({ fontFamily: 'Montserrat, sans-serif', }, logo: { - top: '10px', + height: '15px', + width: '15px', + top: '12px', position: 'relative', - right: '13px', + right: '10px', + backgroundColor: '#ffffff', + borderRadius: '15px', + }, + connected: { + color: connectedBg, + }, + warning: { + color: warningBg, }, account: { paddingRight: sm, display: 'flex', flexDirection: 'column', - justifyContent: 'center', + justifyContent: 'left', + alignItems: 'start', flexGrow: 1, }, address: { @@ -46,13 +58,13 @@ const ProviderInfo = ({ const providerText = `${provider} [${network}]` const cutAddress = connected ? shortVersionOf(userAddress, 6) : 'Connection Error' const color = connected ? 'primary' : 'warning' - const logo = connected ? connectedLogo : connectedWarning + const logo = connected ? classes.connected : classes.warning const identiconAddress = userAddress || 'random' return ( - Connection status + {providerText} {cutAddress} From f2e88fca881b7ab33405146d8163c7021f0c5945 Mon Sep 17 00:00:00 2001 From: apanizo Date: Tue, 6 Nov 2018 16:39:13 +0100 Subject: [PATCH 57/68] Fix disconnected dot in Provider modal --- .../Header/assets/connect-wallet.svg | 15 ---------- .../ProviderDisconnected/ConnectDetails.jsx | 30 +++++++++++++++++-- .../component/ProviderDisconnected/index.jsx | 2 +- 3 files changed, 28 insertions(+), 19 deletions(-) delete mode 100644 src/components/Header/assets/connect-wallet.svg diff --git a/src/components/Header/assets/connect-wallet.svg b/src/components/Header/assets/connect-wallet.svg deleted file mode 100644 index a04fe2bd69..0000000000 --- a/src/components/Header/assets/connect-wallet.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/src/components/Header/component/ProviderDisconnected/ConnectDetails.jsx b/src/components/Header/component/ProviderDisconnected/ConnectDetails.jsx index f885f162ac..0aca41c9d3 100644 --- a/src/components/Header/component/ProviderDisconnected/ConnectDetails.jsx +++ b/src/components/Header/component/ProviderDisconnected/ConnectDetails.jsx @@ -3,11 +3,13 @@ import * as React from 'react' import { withStyles } from '@material-ui/core/styles' import Paragraph from '~/components/layout/Paragraph' import Button from '~/components/layout/Button' +import Dot from '@material-ui/icons/FiberManualRecord' +import Block from '~/components/layout/Block' import Img from '~/components/layout/Img' import Row from '~/components/layout/Row' -import { md, lg } from '~/theme/variables' +import { md, lg, fancy } from '~/theme/variables' -const connectedLogo = require('../../assets/connect-wallet.svg') +const connectedLogo = require('../../assets/key.svg') type Props = { classes: Object, @@ -35,6 +37,25 @@ const styles = () => ({ img: { margin: '0px 2px', }, + status: { + height: '25px', + width: '25px', + borderRadius: '20px', + bottom: '93px', + position: 'absolute', + right: '98px', + backgroundColor: '#ffffff', + color: fancy, + }, + key: { + width: '75px', + height: '75px', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + backgroundColor: '#e4e8f1', + borderRadius: '40px', + }, }) const ConnectDetails = ({ classes, onConnect }: Props) => ( @@ -45,7 +66,10 @@ const ConnectDetails = ({ classes, onConnect }: Props) => (
- Connect a Wallet + + Status disconnected + + From 4512388493692c76279048f1132848da090d91a7 Mon Sep 17 00:00:00 2001 From: apanizo Date: Wed, 7 Nov 2018 16:16:11 +0100 Subject: [PATCH 65/68] Fix batch of CSS improvements on OpenSafe page 1 --- src/components/Stepper/Controls/index.jsx | 8 ++++++- src/components/Stepper/OpenPaper/index.jsx | 1 + .../open/components/SafeNameForm/index.jsx | 2 +- src/theme/mui.js | 24 +++++++++++++------ 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/components/Stepper/Controls/index.jsx b/src/components/Stepper/Controls/index.jsx index c2bb76e72b..58f6c3ec68 100644 --- a/src/components/Stepper/Controls/index.jsx +++ b/src/components/Stepper/Controls/index.jsx @@ -3,7 +3,7 @@ import * as React from 'react' import Button from '~/components/layout/Button' import Col from '~/components/layout/Col' import Row from '~/components/layout/Row' -import { sm } from '~/theme/variables' +import { sm, boldFont } from '~/theme/variables' const controlStyle = { backgroundColor: 'white', @@ -12,6 +12,11 @@ const controlStyle = { const firstButtonStyle = { marginRight: sm, + fontWeight: boldFont, +} + +const secondButtonStyle = { + fontWeight: boldFont, } type Props = { @@ -41,6 +46,7 @@ const Controls = ({ {back} diff --git a/src/theme/mui.js b/src/theme/mui.js index cb686677ee..3334d66362 100644 --- a/src/theme/mui.js +++ b/src/theme/mui.js @@ -55,6 +55,11 @@ export default createMuiTheme({ minWidth: '130px', fontSize: smallFontSize, }, + textSecondary: { + '&:hover': { + borderRadius: '3px', + }, + }, }, MuiStepper: { root: { @@ -64,12 +69,19 @@ export default createMuiTheme({ MuiStepIcon: { root: { fontSize: '22px', + color: '#A2A8BA !important', }, completed: { color: `${secondary} !important`, }, active: { color: `${secondary} !important`, + fontWeight: boldFont, + }, + }, + MuiStepContent: { + root: { + borderLeft: '1px solid #A2A8BA', }, }, MuiTypography: { @@ -130,6 +142,10 @@ export default createMuiTheme({ MuiStepLabel: { label: { textAlign: 'left', + color: '#A2A8BA', + '&$active': { + color: primary, + }, }, }, MuiSnackbarContent: { From c21d70ab86a878948835f7fbdc33a3b85d2f94ba Mon Sep 17 00:00:00 2001 From: apanizo Date: Wed, 7 Nov 2018 16:46:59 +0100 Subject: [PATCH 67/68] CSS improvement on Review's Open Safe page --- src/routes/open/components/ReviewInformation/index.jsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/routes/open/components/ReviewInformation/index.jsx b/src/routes/open/components/ReviewInformation/index.jsx index 9eeca46118..047dc9a27c 100644 --- a/src/routes/open/components/ReviewInformation/index.jsx +++ b/src/routes/open/components/ReviewInformation/index.jsx @@ -1,5 +1,6 @@ // @flow import * as React from 'react' +import classNames from 'classnames' import { getNamesFrom, getAccountsFrom } from '~/routes/open/utils/safeDataExtractor' import Block from '~/components/layout/Block' import { withStyles } from '@material-ui/core/styles' @@ -41,6 +42,8 @@ const styles = () => ({ name: { textOverflow: 'ellipsis', overflow: 'hidden', + }, + userName: { whiteSpace: 'nowrap', }, owner: { @@ -115,7 +118,7 @@ const ReviewComponent = ({ values, classes, network }: Props) => { - + {name} {addresses[index]} From eea8cc681edab41a26f0df251ddd4bc19af24519 Mon Sep 17 00:00:00 2001 From: apanizo Date: Thu, 8 Nov 2018 09:56:01 +0100 Subject: [PATCH 68/68] Adding custom trash icon when remvoing owners #73 --- src/routes/open/assets/trash.svg | 1 + .../open/components/SafeOwnersForm/index.jsx | 20 ++++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) create mode 100644 src/routes/open/assets/trash.svg diff --git a/src/routes/open/assets/trash.svg b/src/routes/open/assets/trash.svg new file mode 100644 index 0000000000..46b95b5941 --- /dev/null +++ b/src/routes/open/assets/trash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/routes/open/components/SafeOwnersForm/index.jsx b/src/routes/open/components/SafeOwnersForm/index.jsx index a8dc027fcd..297327e447 100644 --- a/src/routes/open/components/SafeOwnersForm/index.jsx +++ b/src/routes/open/components/SafeOwnersForm/index.jsx @@ -7,9 +7,8 @@ import { required, composeValidators, uniqueAddress, mustBeEthereumAddress } fro import Block from '~/components/layout/Block' import Button from '~/components/layout/Button' import Row from '~/components/layout/Row' +import Img from '~/components/layout/Img' import Col from '~/components/layout/Col' -import IconButton from '@material-ui/core/IconButton' -import Delete from '@material-ui/icons/Delete' import InputAdornment from '@material-ui/core/InputAdornment' import CheckCircle from '@material-ui/icons/CheckCircle' import { getOwnerNameBy, getOwnerAddressBy } from '~/routes/open/components/fields' @@ -19,6 +18,8 @@ import { getAccountsFrom } from '~/routes/open/utils/safeDataExtractor' import Hairline from '~/components/layout/Hairline' import { md, lg, sm } from '~/theme/variables' +const trash = require('../../assets/trash.svg') + type Props = { classes: Object, otherAccounts: string[], @@ -57,6 +58,14 @@ const styles = () => ({ color: '#03AE60', height: '20px', }, + remove: { + height: '56px', + marginTop: '12px', + maxWidth: '50px', + '&:hover': { + cursor: 'pointer', + }, + }, }) const getAddressValidators = (addresses: string[], position: number) => { @@ -159,12 +168,9 @@ class SafeOwners extends React.Component { text="Owner Address" /> - + { index > 0 && - - - {/* Network */} - + Delete }