Browse Source

Merge pull request #114 from meriadec/master

Create dropdown component and use it in TopBar and Dashboard
master
Loëck Vézien 7 years ago
committed by GitHub
parent
commit
5b9e0ec489
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 58
      src/components/DashboardPage/index.js
  2. 29
      src/components/SettingsPage/Display.js
  3. 10
      src/components/SettingsPage/index.js
  4. 10
      src/components/TopBar.js
  5. 101
      src/components/base/DropDown/index.js
  6. 6
      static/i18n/en/translation.yml
  7. 6
      static/i18n/fr/translation.yml

58
src/components/DashboardPage/index.js

@ -13,32 +13,44 @@ import sortBy from 'lodash/sortBy'
import takeRight from 'lodash/takeRight'
import type { MapStateToProps } from 'react-redux'
import type { Accounts } from 'types/common'
import type { Accounts, T } from 'types/common'
import { space } from 'styles/theme'
import { getVisibleAccounts } from 'reducers/accounts'
import { getOrderAccounts } from 'reducers/settings'
import { updateOrderAccounts } from 'actions/accounts'
import { saveSettings } from 'actions/settings'
import { AreaChart } from 'components/base/Chart'
import Box, { Card } from 'components/base/Box'
import Pills from 'components/base/Pills'
import Text from 'components/base/Text'
import TransactionsList from 'components/TransactionsList'
import DropDown from 'components/base/DropDown'
import AccountCard from './AccountCard'
import BalanceInfos from './BalanceInfos'
const mapStateToProps: MapStateToProps<*, *, *> = state => ({
accounts: getVisibleAccounts(state),
orderAccounts: getOrderAccounts(state),
})
const mapDispatchToProps = {
push,
updateOrderAccounts,
saveSettings,
}
type Props = {
accounts: Accounts,
push: Function,
t: T,
updateOrderAccounts: Function,
saveSettings: Function,
orderAccounts: string,
}
type State = {
@ -108,6 +120,12 @@ class DashboardPage extends PureComponent<Props, State> {
return chunk(listAccounts, ACCOUNTS_BY_LINE)
}
setAccountOrder = order => {
const { updateOrderAccounts, saveSettings } = this.props
updateOrderAccounts(order)
saveSettings({ orderAccounts: order })
}
generateFakeDatas() {
const { accounts } = this.props
return accounts.map(() => [...Array(25).keys()].map(v => generateFakeData(v + 1)))
@ -136,11 +154,26 @@ class DashboardPage extends PureComponent<Props, State> {
_timeout = undefined
render() {
const { push, accounts } = this.props
const { push, accounts, t, orderAccounts } = this.props
const { selectedTime, fakeDatas } = this.state
const totalAccounts = accounts.length
const sortItems = [
{
key: 'name',
label: t('orderAccounts.name'),
},
{
key: 'balance',
label: t('orderAccounts.balance'),
},
{
key: 'type',
label: t('orderAccounts.type'),
},
]
return (
<Box flow={7}>
<Box horizontal align="flex-end">
@ -195,9 +228,24 @@ class DashboardPage extends PureComponent<Props, State> {
</Box>
</Card>
<Box flow={4}>
<Text color="dark" ff="Museo Sans" fontSize={6}>
{'Accounts'}
</Text>
<Box horizontal align="flex-end">
<Text color="dark" ff="Museo Sans" fontSize={6}>
{'Accounts'}
</Text>
<Box ml="auto" horizontal flow={1}>
<Text ff="Open Sans|SemiBold" fontSize={4}>
{'Sort by'}
</Text>
<DropDown
onChange={item => this.setAccountOrder(item.key)}
items={sortItems}
ff="Open Sans|SemiBold"
fontSize={4}
>
<Text color="dark">{t(`orderAccounts.${orderAccounts}`)}</Text>
</DropDown>
</Box>
</Box>
<Box flow={5}>
{this.getAccountsChunk().map((accountsByLine, i) => (
<Box

29
src/components/SettingsPage/Display.js

@ -17,6 +17,7 @@ type Props = {
settings: SettingsDisplay,
onSaveSettings: Function,
}
type State = {
inputValue: InputValue,
}
@ -25,7 +26,7 @@ class TabProfile extends PureComponent<Props, State> {
state = {
inputValue: {
language: this.props.settings.language,
orderAccounts: this.props.settings.orderAccounts,
orderAccounts: '',
},
}
@ -43,20 +44,6 @@ class TabProfile extends PureComponent<Props, State> {
name: t('language.fr'),
},
],
orderAccounts: [
{
key: 'name',
name: t('orderAccounts.name'),
},
{
key: 'balance',
name: t('orderAccounts.balance'),
},
{
key: 'type',
name: t('orderAccounts.type'),
},
],
}
}
@ -83,10 +70,9 @@ class TabProfile extends PureComponent<Props, State> {
const { t } = this.props
const { inputValue } = this.state
const { languages, orderAccounts } = this.getDatas()
const { languages } = this.getDatas()
const currentLanguage = languages.find(l => l.key === inputValue.language)
const currentOrderAccounts = orderAccounts.find(l => l.key === inputValue.orderAccounts)
return (
<form onSubmit={this.handleSubmit}>
@ -100,15 +86,6 @@ class TabProfile extends PureComponent<Props, State> {
items={languages}
/>
</Box>
<Box flow={1}>
<Label>{t('settings.display.orderAccounts')}</Label>
<Select
onChange={item => this.handleChangeInput('orderAccounts')(item.key)}
renderSelected={item => item && item.name}
value={currentOrderAccounts}
items={orderAccounts}
/>
</Box>
<Box horizontal justify="flex-end">
<Button primary type="submit">
Save

10
src/components/SettingsPage/index.js

@ -8,9 +8,7 @@ import { translate } from 'react-i18next'
import type { MapStateToProps } from 'react-redux'
import type { Settings, T } from 'types/common'
import type { SaveSettings } from 'actions/settings'
import type { UpdateOrderAccounts } from 'actions/accounts'
import { updateOrderAccounts } from 'actions/accounts'
import { saveSettings } from 'actions/settings'
import Box from 'components/base/Box'
@ -26,7 +24,6 @@ const mapStateToProps: MapStateToProps<*, *, *> = state => ({
const mapDispatchToProps = {
saveSettings,
updateOrderAccounts,
}
type Props = {
@ -34,7 +31,6 @@ type Props = {
saveSettings: SaveSettings,
settings: Settings,
t: T,
updateOrderAccounts: UpdateOrderAccounts,
}
type State = {
@ -49,16 +45,12 @@ class SettingsPage extends PureComponent<Props, State> {
handleChangeTab = (tab: number) => this.setState({ tab })
handleSaveSettings = newSettings => {
const { saveSettings, i18n, settings, updateOrderAccounts } = this.props
const { saveSettings, i18n, settings } = this.props
if (newSettings.language !== settings.language) {
i18n.changeLanguage(newSettings.language)
}
if (newSettings.orderAccounts !== settings.orderAccounts) {
updateOrderAccounts(newSettings.orderAccounts)
}
saveSettings(newSettings)
}

10
src/components/TopBar.js

@ -15,6 +15,7 @@ import { hasPassword } from 'reducers/settings'
import IconDevices from 'icons/Devices'
import IconActivity from 'icons/Activity'
import DropDown from 'components/base/DropDown'
import Box from 'components/base/Box'
import GlobalSearch from 'components/GlobalSearch'
@ -23,7 +24,6 @@ const Container = styled(Box).attrs({
})`
height: ${p => p.theme.sizes.topBarHeight}px;
position: absolute;
overflow: hidden;
left: 0;
right: 0;
top: 0;
@ -142,9 +142,13 @@ class TopBar extends PureComponent<Props, State> {
</Box>
</Box>
<Box horizontal noShrink>
<Box justify="center" px={4} ff="Open Sans|SemiBold" fontSize={4}>
<DropDown
items={[{ key: 'empty', label: 'Nothing here yet' }]}
ff="Open Sans|SemiBold"
fontSize={4}
>
{'Khalil Benihoud'}
</Box>
</DropDown>
</Box>
</Inner>
</Container>

101
src/components/base/DropDown/index.js

@ -0,0 +1,101 @@
// @flow
import React, { PureComponent } from 'react'
import styled from 'styled-components'
import noop from 'lodash/noop'
import Downshift from 'downshift'
import Box from 'components/base/Box'
type ItemType = {
key: string,
label: any,
}
type Props = {
children: any,
items: Array<ItemType>,
value?: ItemType | null,
onChange?: ItemType => void,
}
const Trigger = styled(Box)`
outline: none;
cursor: pointer;
`
const Drop = styled(Box).attrs({
bg: 'white',
boxShadow: 0,
})`
position: absolute;
top: 100%;
right: 0;
`
const Item = styled(Box).attrs({
py: 2,
px: 4,
bg: p => (p.isHighlighted ? 'pearl' : ''),
})`
white-space: nowrap;
`
function itemToString(item) {
return item ? item.label : ''
}
class DropDown extends PureComponent<Props> {
static defaultProps = {
value: null,
onChange: noop,
}
renderItems = (items: Array<ItemType>, selectedItem: ItemType, downshiftProps: Object) => {
const { getItemProps, highlightedIndex } = downshiftProps
return (
<Drop>
{items.map((item, i) => (
<Item isHighlighted={highlightedIndex === i} key={item.key} {...getItemProps({ item })}>
{item.label}
</Item>
))}
</Drop>
)
}
render() {
const { children, items, value, onChange, ...props } = this.props
return (
<Downshift
onChange={onChange}
itemToString={itemToString}
selectedItem={value}
render={({
getButtonProps,
getRootProps,
isOpen,
openMenu,
selectedItem,
...downshiftProps
}) => (
<Box
{...getRootProps({ refKey: 'innerRef' })}
horizontal
align="center"
relative
{...props}
>
<Trigger {...getButtonProps()} tabIndex={0}>
{children}
</Trigger>
{isOpen && this.renderItems(items, selectedItem, downshiftProps)}
</Box>
)}
/>
)
}
}
export default DropDown

6
static/i18n/en/translation.yml

@ -9,9 +9,9 @@ language:
fr: French
orderAccounts:
name: By name
balance: By balance
type: By type
name: Name
balance: Balance
type: Type
sidebar:
menu: Menu

6
static/i18n/fr/translation.yml

@ -9,9 +9,9 @@ language:
fr: Français
orderAccounts:
name: Par nom
balance: Par solde
type: Par type
name: Nom
balance: Solde
type: Type
sidebar:
menu: Menu

Loading…
Cancel
Save