feat(create-instance): revised feedback changes

This commit is contained in:
Sara Vieira 2017-11-20 11:33:50 +00:00 committed by Sérgio Ramos
parent 42b4c6230e
commit 0be8553e29
12 changed files with 383 additions and 175 deletions

View File

@ -173,7 +173,7 @@ const style = css`
`}; `};
${is('bold')` ${is('bold')`
font-weight: bold; font-weight: 500;
`}; `};
`; `;

View File

@ -134,6 +134,7 @@ export {
export { export {
default as Table, default as Table,
Thead as TableThead, Thead as TableThead,
ThFooter as TableThFooter,
Tr as TableTr, Tr as TableTr,
Th as TableTh, Th as TableTh,
Tbody as TableTbody, Tbody as TableTbody,

View File

@ -2,7 +2,7 @@ import React from 'react';
import { Broadcast, Subscriber } from 'joy-react-broadcast'; import { Broadcast, Subscriber } from 'joy-react-broadcast';
import isBoolean from 'lodash.isboolean'; import isBoolean from 'lodash.isboolean';
import styled, { css } from 'styled-components'; import styled, { css } from 'styled-components';
import is from 'styled-is'; import is, { isNot } from 'styled-is';
import remcalc from 'remcalc'; import remcalc from 'remcalc';
import Baseline from '../baseline'; import Baseline from '../baseline';
@ -45,7 +45,7 @@ const Column = css`
white-space: nowrap; white-space: nowrap;
box-sizing: border-box; box-sizing: border-box;
padding: 0 ${remcalc(18)}; padding: 0 ${remcalc(24)};
height: ${remcalc(60)}; height: ${remcalc(60)};
${handleBreakpoint('xs')}; ${handleBreakpoint('xs')};
@ -124,9 +124,39 @@ const BaseTable = styled.table`
max-width: 100%; max-width: 100%;
`; `;
const BaseThFooter = styled.tfoot`
width: 100%;
th:first-child {
border-bottom-left-radius: ${remcalc(4)};
}
th:last-child {
border-bottom-right-radius: ${remcalc(4)};
}
th {
border-top-width: 0;
}
`;
const BaseThead = styled.thead` const BaseThead = styled.thead`
width: 100%; width: 100%;
${is('footer')`
th:first-child {
border-bottom-left-radius: ${remcalc(4)};
}
th:last-child {
border-bottom-right-radius: ${remcalc(4)};
}
th {
border-top-width: 0;
}
`};
${isNot('footer')`
th:first-child { th:first-child {
border-top-left-radius: ${remcalc(4)}; border-top-left-radius: ${remcalc(4)};
} }
@ -138,6 +168,7 @@ const BaseThead = styled.thead`
th { th {
border-bottom-width: 0; border-bottom-width: 0;
} }
`};
`; `;
const BaseTbody = styled.tbody` const BaseTbody = styled.tbody`
@ -167,6 +198,7 @@ const BaseTh = styled.th`
${is('selected')` ${is('selected')`
color: ${props => props.theme.text}; color: ${props => props.theme.text};
font-weight: bold;
`}; `};
&:not(:first-child) { &:not(:first-child) {
@ -186,7 +218,6 @@ const BaseTh = styled.th`
const BaseTd = styled.td` const BaseTd = styled.td`
${Column}; ${Column};
transition: all 200ms ease;
border-bottom-width: 0; border-bottom-width: 0;
vertical-align: middle; vertical-align: middle;
@ -279,6 +310,16 @@ export const Thead = Baseline(({ children, ...rest }) => (
</Propagate> </Propagate>
)); ));
export const ThFooter = Baseline(({ children, ...rest }) => (
<Propagate {...rest} header={true}>
{value => (
<BaseThFooter {...value} name="thfoot">
{children}
</BaseThFooter>
)}
</Propagate>
));
export const Tr = Baseline(({ children, ...rest }) => ( export const Tr = Baseline(({ children, ...rest }) => (
<Propagate {...rest}> <Propagate {...rest}>
{value => ( {value => (

View File

@ -184,10 +184,7 @@ class Affinity extends Component {
<Button secondary onClick={this.toggleForm}> <Button secondary onClick={this.toggleForm}>
Cancel Cancel
</Button> </Button>
<Button <Button onClick={this.submit} disabled={!this.state.rule.value}>
onClick={this.submit}
disabled={!this.state.rule.value}
>
Create Create
</Button> </Button>
</div> </div>

View File

@ -17,8 +17,7 @@ import {
Label, Label,
H2, H2,
H4, H4,
P, P
ViewContainer
} from 'joyent-ui-toolkit'; } from 'joyent-ui-toolkit';
const FullWidth = styled(Margin)` const FullWidth = styled(Margin)`
@ -38,7 +37,8 @@ class Filters extends Component {
ram, ram,
cpu, cpu,
disk, disk,
cost cost,
reset: 0
}; };
} }
@ -56,7 +56,8 @@ class Filters extends Component {
ram, ram,
cpu, cpu,
disk, disk,
cost cost,
reset: this.state.reset + 1
}); });
}; };
@ -122,7 +123,8 @@ class Filters extends Component {
costChange={value => costChange(value)} costChange={value => costChange(value)}
filters={filters} filters={filters}
disabled={isEqual(filters, defaultState.filters)} disabled={isEqual(filters, defaultState.filters)}
onClick={this.handleResetClick} onResetClick={this.handleResetClick}
reset={this.state.reset}
/> />
</FullWidth> </FullWidth>
]; ];

View File

@ -1,5 +1,6 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import remcalc from 'remcalc';
import { import {
FormGroup, FormGroup,
FormLabel, FormLabel,
@ -9,52 +10,92 @@ import {
InputDropdown InputDropdown
} from 'joyent-ui-toolkit'; } from 'joyent-ui-toolkit';
import { Row, Col } from 'react-styled-flexboxgrid'; import { Row, Col } from 'react-styled-flexboxgrid';
import { Padding } from 'styled-components-spacing'; import { Padding, Margin } from 'styled-components-spacing';
const RowFullWidth = styled(Row)` const RowFullWidth = styled(Row)`
width: 100%; width: 100%;
`; `;
const InputDropdownBorder = styled(InputDropdown)`
border-right: 1px solid ${props => props.theme.grey}; const Divider = styled.div`
margin-right: 24px; width: ${remcalc(1)};
padding-right: 24px; background: ${props => props.theme.grey};
height: ${remcalc(66)};
margin: 0 ${remcalc(14)};
margin-bottom: ${remcalc(9)};
display: flex;
align-self: flex-end;
`; `;
const valuesToSend = (changed, target, value, name) => ({ const isToBeMultiplied = (name, state, target) =>
(name === 'ram' && state[name][`${target}Selected`] === 'MB') ||
(name === 'disk' && state[name][`${target}Selected`] === 'GB');
const valuesToSend = (changed, target, value) => ({
min: !isNaN(parseFloat(changed.min)) ? parseFloat(changed.min) : 0, min: !isNaN(parseFloat(changed.min)) ? parseFloat(changed.min) : 0,
max: !isNaN(parseFloat(changed.max)) ? parseFloat(changed.max) : 0, max: !isNaN(parseFloat(changed.max)) ? parseFloat(changed.max) : 0,
[target]: parseFloat(value) [target]: parseFloat(value)
}); });
class Inputs extends Component { const ramLogic = ram => ({
constructor(props) {
super(props);
const { filters: { cpu, cost, ram, disk } } = this.props;
this.state = {
ram: {
min: ram.min > 1 ? ram.min : ram.min * 1000, min: ram.min > 1 ? ram.min : ram.min * 1000,
minSelected: 'MB', minSelected: 'MB',
max: ram.max > 1 ? ram.max : ram.max * 1000, max: ram.max > 1 ? ram.max : ram.max * 1000,
maxSelected: 'GB' maxSelected: 'GB'
}, });
cpu,
disk: { const diskLogic = disk => ({
min: disk.min > 1 ? disk.min : disk.min * 1000, min: disk.min > 1 ? disk.min : disk.min * 1000,
minSelected: 'GB', minSelected: 'GB',
max: disk.max > 1 ? disk.max : disk.max * 1000, max: disk.max > 1 ? disk.max : disk.max * 1000,
maxSelected: 'TB' maxSelected: 'TB'
}, });
cost
class Inputs extends Component {
constructor(props) {
super(props);
const { filters: { cpu, cost, ram, disk }, reset } = this.props;
this.state = {
ram: ramLogic(ram),
cpu,
disk: diskLogic(disk),
cost,
reset
}; };
} }
componentWillReceiveProps = nextProps => {
const { filters: { cpu, cost, ram, disk }, reset } = nextProps;
if (reset !== this.state.reset) {
this.setState({
ram: ramLogic(ram),
cpu,
disk: diskLogic(disk),
cost,
reset
});
}
};
handleChange = (e, name, target) => { handleChange = (e, name, target) => {
const changed = this.state[name]; const changed = this.state[name];
const value = (e.target || {}).value; const value = (e.target || {}).value;
setTimeout(() => { setTimeout(() => {
this.props[`${name}Change`](valuesToSend(changed, target, value, name)); this.props[`${name}Change`](
valuesToSend(
{
min: isToBeMultiplied(name, this.state, 'min')
? changed.min / 1000
: changed.min,
max: isToBeMultiplied(name, this.state, 'max')
? changed.max / 1000
: changed.max
},
target,
isToBeMultiplied(name, this.state, target) ? value / 1000 : value
)
);
}, 1000); }, 1000);
this.setState({ this.setState({
@ -68,6 +109,8 @@ class Inputs extends Component {
handleSelectChange = (e, name, target, valueTarget) => { handleSelectChange = (e, name, target, valueTarget) => {
const value = (e.target || {}).value; const value = (e.target || {}).value;
const isToBeMultiplied =
(name === 'ram' && value === 'MB') || (name === 'disk' && value === 'GB');
this.setState({ this.setState({
...this.state, ...this.state,
[name]: { [name]: {
@ -75,13 +118,36 @@ class Inputs extends Component {
[target]: value [target]: value
} }
}); });
this.props[`${name}Change`](
valuesToSend(
this.state[name],
valueTarget,
isToBeMultiplied
? this.state[name][valueTarget] / 1000
: this.state[name][valueTarget]
)
);
}; };
handleBlur = (e, name, target) => { handleBlur = (e, name, target) => {
const changed = this.state[name]; const changed = this.state[name];
const value = (e.target || {}).value; const value = (e.target || {}).value;
this.props[`${name}Change`](valuesToSend(changed, target, value, name)); this.props[`${name}Change`](
valuesToSend(
{
min: isToBeMultiplied(name, this.state, 'min')
? changed.min / 1000
: changed.min,
max: isToBeMultiplied(name, this.state, 'max')
? changed.max / 1000
: changed.max
},
target,
isToBeMultiplied(name, this.state, target) ? value / 1000 : value
)
);
this.setState({ this.setState({
...this.state, ...this.state,
@ -94,7 +160,7 @@ class Inputs extends Component {
render() { render() {
const { cpu, cost, ram, disk } = this.state; const { cpu, cost, ram, disk } = this.state;
const { onClick, disabled } = this.props; const { onResetClick, disabled } = this.props;
return [ return [
<Row bottom="xs"> <Row bottom="xs">
@ -124,7 +190,7 @@ class Inputs extends Component {
</Select> </Select>
</InputDropdown> </InputDropdown>
<Padding horizontal={2}>to</Padding> <Padding horizontal={2}>to</Padding>
<InputDropdownBorder> <InputDropdown>
<Input <Input
wrapped wrapped
small small
@ -143,9 +209,10 @@ class Inputs extends Component {
<option value="MB">MB</option> <option value="MB">MB</option>
<option value="GB">GB</option> <option value="GB">GB</option>
</Select> </Select>
</InputDropdownBorder> </InputDropdown>
</FormGroup> </FormGroup>
</Col> </Col>
<Divider />
<Col> <Col>
<Padding top={1}> <Padding top={1}>
<FormLabel>Disk</FormLabel> <FormLabel>Disk</FormLabel>
@ -218,6 +285,7 @@ class Inputs extends Component {
/> />
</FormGroup> </FormGroup>
</Col> </Col>
<Divider />
<Col> <Col>
<Padding top={1}> <Padding top={1}>
<FormLabel>$/hour</FormLabel> <FormLabel>$/hour</FormLabel>
@ -243,9 +311,17 @@ class Inputs extends Component {
</RowFullWidth>, </RowFullWidth>,
<Row> <Row>
<Col xs={12}> <Col xs={12}>
<Button disabled={disabled} secondary small bold onClick={onClick}> <Margin vertical={2}>
<Button
disabled={disabled}
secondary
small
bold
onClick={onResetClick}
>
Reset All Filters Reset All Filters
</Button> </Button>
</Margin>
</Col> </Col>
</Row> </Row>
]; ];

View File

@ -9,7 +9,9 @@ import {
BreadcrumbItem, BreadcrumbItem,
Anchor, Anchor,
Button, Button,
Divider Divider,
MessageTitle,
MessageDescription
} from 'joyent-ui-toolkit'; } from 'joyent-ui-toolkit';
class Home extends Component { class Home extends Component {
@ -47,7 +49,6 @@ class Home extends Component {
selected: values[key] ? values[key] : false selected: values[key] ? values[key] : false
})); }));
console.table(groups);
onFilterChange({ onFilterChange({
...filters, ...filters,
groups groups
@ -60,9 +61,12 @@ class Home extends Component {
const { filters, onFilterReset, packages } = this.props; const { filters, onFilterReset, packages } = this.props;
const _msg = showMessage ? ( const _msg = showMessage ? (
<Message onCloseClick={this.closeMessage}> <Message onCloseClick={this.closeMessage}>
<MessageTitle>Choosing deployment data center</MessageTitle>
<MessageDescription>
Not all data centres have all configurations of instances available. Not all data centres have all configurations of instances available.
Make sure that you choose the data center that suits your requirements.{' '} Make sure that you choose the data center that suits your
<Anchor href="#">Learn More</Anchor> requirements. <Anchor href="#">Learn More</Anchor>
</MessageDescription>
</Message> </Message>
) : null; ) : null;
@ -103,10 +107,12 @@ class Home extends Component {
</Margin>, </Margin>,
<Row end="xs"> <Row end="xs">
<Col xs={12}> <Col xs={12}>
<Margin top={5}>
<Button>Next</Button> <Button>Next</Button>
</Margin>
</Col> </Col>
</Row>, </Row>,
<Margin top={2}> <Margin top={5}>
<AffinityHOC /> <AffinityHOC />
</Margin> </Margin>
]; ];

View File

@ -40,7 +40,7 @@ export const returnIcon = group => {
<IconWrapper> <IconWrapper>
<TooltipContainer hoverable> <TooltipContainer hoverable>
<TooltipTarget> <TooltipTarget>
<Margin right={1}> <Margin horizontal={1}>
<Flex>{icon}</Flex> <Flex>{icon}</Flex>
</Margin> </Margin>
</TooltipTarget> </TooltipTarget>

View File

@ -1,5 +1,7 @@
import React from 'react'; import React from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import styled from 'styled-components';
import remcalc from 'remcalc';
import { import {
Header, Header,
@ -11,11 +13,15 @@ import {
UserIconLight UserIconLight
} from 'joyent-ui-toolkit'; } from 'joyent-ui-toolkit';
const HeaderBrandStyled = styled(HeaderBrand)`
margin-top: ${remcalc(6)};
`;
const NavHeader = () => ( const NavHeader = () => (
<Header> <Header>
<HeaderBrand beta> <HeaderBrandStyled>
<TritonBetaIcon /> <TritonBetaIcon />
</HeaderBrand> </HeaderBrandStyled>
<HeaderNav> <HeaderNav>
<li> <li>
<Link className="active" to="/"> <Link className="active" to="/">

View File

@ -1,10 +1,18 @@
import React from 'react'; import React from 'react';
import { reduxForm } from 'redux-form'; import { reduxForm } from 'redux-form';
import styled from 'styled-components';
import remcalc from 'remcalc';
import { returnIcon } from '../icons'; import { returnIcon } from '../icons';
import { TableTr, TableTd, H4, Radio, FormGroup } from 'joyent-ui-toolkit'; import { TableTr, TableTd, H4, Radio, FormGroup } from 'joyent-ui-toolkit';
const FormGroupStyled = styled(FormGroup)`
float: left;
margin-right: ${remcalc(24)};
margin-top: ${remcalc(3)};
`;
const Package = ({ const Package = ({
pack: { price, memory, vcpus, disk, group, ssd, name }, pack: { price, memory, vcpus, disk, group, ssd, name },
selected, selected,
@ -12,20 +20,18 @@ const Package = ({
}) => ( }) => (
<TableTr selected={selected}> <TableTr selected={selected}>
<TableTd> <TableTd>
<FormGroup name={name}> <FormGroupStyled name={name}>
<Radio onClick={onClick} name={name} value={name} checked={selected} /> <Radio onClick={onClick} name={name} value={name} checked={selected} />
</FormGroup> </FormGroupStyled>
</TableTd>
<TableTd>
{returnIcon(group)} {returnIcon(group)}
<H4>{name}</H4> <H4>{name}</H4>
</TableTd> </TableTd>
<TableTd> <TableTd right>
{memory > 1 ? `${parseInt(memory, 10)} GB` : `${memory * 1000} MB`} {memory > 1 ? `${parseInt(memory, 10)} GB` : `${memory * 1000} MB`}
</TableTd> </TableTd>
<TableTd>{disk > 1 ? `${disk} TB` : `${disk * 1000} GB`}</TableTd> <TableTd right>{disk > 1 ? `${disk} TB` : `${disk * 1000} GB`}</TableTd>
<TableTd>{vcpus}</TableTd> <TableTd right>{vcpus}</TableTd>
<TableTd>{price.toFixed(3)}</TableTd> <TableTd right>{price.toFixed(3)}</TableTd>
</TableTr> </TableTr>
); );

View File

@ -12,6 +12,7 @@ import {
Table, Table,
TableThead, TableThead,
TableTbody, TableTbody,
TableThFooter,
TableTr, TableTr,
TableTh, TableTh,
ArrowIcon ArrowIcon
@ -21,18 +22,15 @@ const ArrowIconStyled = styled(ArrowIcon)`
margin-left: ${remcalc(6)}; margin-left: ${remcalc(6)};
cursor: pointer; cursor: pointer;
position: relative; position: relative;
top: ${remcalc(-1)}; top: ${remcalc(-3)};
transition: transform 200ms ease; transition: transform 200ms ease;
path { path {
fill: ${props => props.theme.grey}; fill: ${props => props.theme.text};
} }
${is('selected', 'down')` ${is('selected', 'down')`
transform: rotate(180deg); transform: rotate(180deg);
path {
fill: ${props => props.theme.text};
}
`}; `};
`; `;
@ -46,8 +44,10 @@ class Packages extends Component {
super(props); super(props);
this.state = { this.state = {
packages: props.packages, packages: props.packages.sort((a, b) => (a.price > b.price ? 1 : -1)),
selected: null selected: null,
price: true,
ordered: 'price'
}; };
} }
@ -84,56 +84,65 @@ class Packages extends Component {
<Table> <Table>
<TableThead> <TableThead>
<TableTr> <TableTr>
<TableTh xs="40" />
<TableTh selected={ordered === 'name'}> <TableTh selected={ordered === 'name'}>
<Span role="button" onClick={() => this.order('name')}> <Span role="button" onClick={() => this.order('name')}>
Name{' '} Name{' '}
</Span> </Span>
{ordered === 'name' && (
<ArrowIconStyled <ArrowIconStyled
selected={ordered === 'name'} selected
down={this.state.name} down={this.state.name}
onClick={() => this.order('name')} onClick={() => this.order('name')}
/> />
)}
</TableTh> </TableTh>
<TableTh right xs="100" selected={ordered === 'memory'}> <TableTh right xs="100" selected={ordered === 'memory'}>
<Span role="button" onClick={() => this.order('memory')}> <Span role="button" onClick={() => this.order('memory')}>
RAM{' '} RAM{' '}
</Span> </Span>
{ordered === 'memory' && (
<ArrowIconStyled <ArrowIconStyled
selected={ordered === 'memory'} selected
down={this.state.memory} down={this.state.memory}
onClick={() => this.order('memory')} onClick={() => this.order('memory')}
/> />
)}
</TableTh> </TableTh>
<TableTh right xs="100" selected={ordered === 'disk'}> <TableTh right xs="100" selected={ordered === 'disk'}>
<Span role="button" onClick={() => this.order('disk')}> <Span role="button" onClick={() => this.order('disk')}>
Disk{' '} Disk{' '}
</Span> </Span>
{ordered === 'disk' && (
<ArrowIconStyled <ArrowIconStyled
selected={ordered === 'disk'} selected
down={this.state.disk} down={this.state.disk}
onClick={() => this.order('disk')} onClick={() => this.order('disk')}
/> />
)}
</TableTh> </TableTh>
<TableTh right xs="100" selected={ordered === 'vcpus'}> <TableTh right xs="100" selected={ordered === 'vcpus'}>
<Span role="button" onClick={() => this.order('vcpus')}> <Span role="button" onClick={() => this.order('vcpus')}>
vCPU{' '} vCPU{' '}
</Span> </Span>
{ordered === 'vcpus' && (
<ArrowIconStyled <ArrowIconStyled
selected={ordered === 'vcpus'} selected
down={this.state.vcpus} down={this.state.vcpus}
onClick={() => this.order('vcpus')} onClick={() => this.order('vcpus')}
/> />
)}
</TableTh> </TableTh>
<TableTh right xs="100" selected={ordered === 'price'}> <TableTh right xs="100" selected={ordered === 'price'}>
<Span role="button" onClick={() => this.order('price')}> <Span role="button" onClick={() => this.order('price')}>
$/hour{' '} $/hour{' '}
</Span> </Span>
{ordered === 'price' && (
<ArrowIconStyled <ArrowIconStyled
selected={ordered === 'price'} selected={ordered === 'price'}
down={this.state.price} down={this.state.price}
onClick={() => this.order('price')} onClick={() => this.order('price')}
/> />
)}
</TableTh> </TableTh>
</TableTr> </TableTr>
</TableThead> </TableThead>
@ -147,12 +156,76 @@ class Packages extends Component {
/> />
))} ))}
</TableTbody> </TableTbody>
<TableThFooter>
<TableTr>
<TableTh selected={ordered === 'name'}>
<Span role="button" onClick={() => this.order('name')}>
Name{' '}
</Span>
{ordered === 'name' && (
<ArrowIconStyled
selected
down={this.state.name}
onClick={() => this.order('name')}
/>
)}
</TableTh>
<TableTh right xs="100" selected={ordered === 'memory'}>
<Span role="button" onClick={() => this.order('memory')}>
RAM{' '}
</Span>
{ordered === 'memory' && (
<ArrowIconStyled
selected
down={this.state.memory}
onClick={() => this.order('memory')}
/>
)}
</TableTh>
<TableTh right xs="100" selected={ordered === 'disk'}>
<Span role="button" onClick={() => this.order('disk')}>
Disk{' '}
</Span>
{ordered === 'disk' && (
<ArrowIconStyled
selected
down={this.state.disk}
onClick={() => this.order('disk')}
/>
)}
</TableTh>
<TableTh right xs="100" selected={ordered === 'vcpus'}>
<Span role="button" onClick={() => this.order('vcpus')}>
vCPU{' '}
</Span>
{ordered === 'vcpus' && (
<ArrowIconStyled
selected
down={this.state.vcpus}
onClick={() => this.order('vcpus')}
/>
)}
</TableTh>
<TableTh right xs="100" selected={ordered === 'price'}>
<Span role="button" onClick={() => this.order('price')}>
$/hour{' '}
</Span>
{ordered === 'price' && (
<ArrowIconStyled
selected={ordered === 'price'}
down={this.state.price}
onClick={() => this.order('price')}
/>
)}
</TableTh>
</TableTr>
</TableThFooter>
</Table> </Table>
</Col> </Col>
</Row> </Row>
) : ( ) : (
<Row> <Row>
<Col> <Col xs={12}>
<Empty /> <Empty />
</Col> </Col>
</Row> </Row>

View File

@ -50,11 +50,11 @@ export const store = createStore(
}), }),
state, // Initial state state, // Initial state
compose( compose(
applyMiddleware(client.middleware()) applyMiddleware(client.middleware()),
// If you are using the devToolsExtension, you can add it here also // If you are using the devToolsExtension, you can add it here also
// eslint-disable-next-line no-negated-condition // eslint-disable-next-line no-negated-condition
// typeof GLOBAL.__REDUX_DEVTOOLS_EXTENSION__ !== 'undefined' typeof GLOBAL.__REDUX_DEVTOOLS_EXTENSION__ !== 'undefined'
// ? GLOBAL.__REDUX_DEVTOOLS_EXTENSION__() ? GLOBAL.__REDUX_DEVTOOLS_EXTENSION__()
// : f => f : f => f
) )
); );