Skip to content

Commit 7d3627f

Browse files
authored
Merge pull request linode#7 from rjstires/M3-22-grid-view-update
M3-22 GridView Update
2 parents 7164cab + 27df9d4 commit 7d3627f

File tree

4 files changed

+197
-143
lines changed

4 files changed

+197
-143
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import * as React from 'react';
2+
3+
import Grid from 'material-ui/Grid';
4+
5+
import LinodeCard from './LinodeCard';
6+
7+
interface Props {
8+
linodes: Linode.Linode[];
9+
images: Linode.Image[];
10+
types: Linode.LinodeType[];
11+
}
12+
13+
const LinodesGridView: React.StatelessComponent<Props> = (props) => {
14+
const { linodes, images, types } = props;
15+
16+
return (
17+
<Grid container>
18+
{linodes.map(linode =>
19+
<LinodeCard
20+
key={linode.id}
21+
linode={linode}
22+
image={images.find(image => linode.image === image.id)}
23+
type={types.find(type => linode.type === type.id)}
24+
/>,
25+
)}
26+
</Grid>
27+
);
28+
};
29+
30+
export default LinodesGridView;
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import * as React from 'react';
2+
3+
import Grid from 'material-ui/Grid';
4+
import Paper from 'material-ui/Paper';
5+
import Table from 'material-ui/Table';
6+
import TableBody from 'material-ui/Table/TableBody';
7+
import TableCell from 'material-ui/Table/TableCell';
8+
import TableHead from 'material-ui/Table/TableHead';
9+
import TableRow from 'material-ui/Table/TableRow';
10+
11+
import LinodeRow from './LinodeRow';
12+
13+
interface Props {
14+
linodes: Linode.Linode[];
15+
images: Linode.Image[];
16+
types: Linode.LinodeType[];
17+
}
18+
19+
const LinodesListView: React.StatelessComponent<Props> = (props) => {
20+
const { linodes, images, types } = props;
21+
22+
return (
23+
<Paper elevation={1}>
24+
<Grid container>
25+
<Grid item xs={12}>
26+
<Table>
27+
<TableHead>
28+
<TableRow>
29+
<TableCell>Label</TableCell>
30+
<TableCell>Tags</TableCell>
31+
<TableCell>IP Addresses</TableCell>
32+
<TableCell>Region</TableCell>
33+
<TableCell></TableCell>
34+
</TableRow>
35+
</TableHead>
36+
<TableBody>
37+
{linodes.map(linode =>
38+
<LinodeRow
39+
key={linode.id}
40+
linode={linode}
41+
image={images.find(image => linode.image === image.id)}
42+
type={types.find(type => linode.type === type.id)}
43+
/>,
44+
)}
45+
</TableBody>
46+
</Table>
47+
</Grid>
48+
</Grid>
49+
</Paper>
50+
);
51+
};
52+
export default LinodesListView;
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import * as React from 'react';
2+
import { compose } from 'redux';
3+
4+
import {
5+
withStyles,
6+
Theme,
7+
WithStyles,
8+
StyleRulesCallback,
9+
} from 'material-ui/styles';
10+
import Button from 'material-ui/Button';
11+
import ViewList from 'material-ui-icons/ViewList';
12+
import ViewModule from 'material-ui-icons/ViewModule';
13+
14+
type CSSClasses =
15+
'root'
16+
| 'button'
17+
| 'buttonActive'
18+
| 'buttonLeft'
19+
| 'buttonRight'
20+
| 'icon';
21+
22+
const styles: StyleRulesCallback<CSSClasses> = (theme: Theme) => ({
23+
root: {
24+
marginBottom: theme.spacing.unit * 2,
25+
},
26+
button: {
27+
border: '1px solid #333',
28+
},
29+
buttonActive: {
30+
backgroundColor: '#333',
31+
color: '#f3f3f3',
32+
'&:hover': {
33+
backgroundColor: '#333',
34+
},
35+
},
36+
buttonLeft: {
37+
borderWidth: '1px 0 1px 1px',
38+
borderRadius: '5px 0 0 5px',
39+
},
40+
buttonRight: {
41+
borderWidth: '1px 1px 1px 0',
42+
borderRadius: '0 5px 5px 0',
43+
},
44+
icon: {
45+
marginRight: theme.spacing.unit,
46+
},
47+
});
48+
49+
interface Props {
50+
handleClick: (v: 'grid' | 'list') => void;
51+
status: 'grid' | 'list';
52+
}
53+
54+
const styled = withStyles(styles, { withTheme: true });
55+
56+
type CombinedProps = Props & WithStyles<CSSClasses>;
57+
58+
export const ToggleBox: React.StatelessComponent<CombinedProps> = (props) => {
59+
const {
60+
classes,
61+
handleClick,
62+
status,
63+
} = props;
64+
65+
return (
66+
<div className={classes.root}>
67+
<Button
68+
onClick={() => handleClick('list')}
69+
className={`
70+
${!status || status === 'list' && classes.buttonActive}
71+
${classes.button}
72+
${classes.buttonLeft}`
73+
}
74+
>
75+
<ViewList className={classes.icon} />
76+
List
77+
</Button>
78+
<Button
79+
onClick={() => handleClick('grid')}
80+
className={`
81+
${status === 'grid' && classes.buttonActive}
82+
${classes.button}
83+
${classes.buttonRight}`
84+
}
85+
>
86+
<ViewModule className={classes.icon} />
87+
Grid
88+
</Button>
89+
</div>
90+
);
91+
};
92+
93+
export default compose(
94+
styled,
95+
)(ToggleBox);

src/features/linodes/ListLinodes/index.tsx

Lines changed: 20 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -7,73 +7,22 @@ import {
77
import { compose } from 'redux';
88
import { pathOr } from 'ramda';
99

10-
import {
11-
withStyles,
12-
Theme,
13-
WithStyles,
14-
StyleRulesCallback,
15-
} from 'material-ui/styles';
16-
import Button from 'material-ui/Button';
17-
import Grid from 'material-ui/Grid';
18-
import Paper from 'material-ui/Paper';
19-
import Table from 'material-ui/Table';
20-
import TableBody from 'material-ui/Table/TableBody';
21-
import TableCell from 'material-ui/Table/TableCell';
22-
import TableHead from 'material-ui/Table/TableHead';
23-
import TableRow from 'material-ui/Table/TableRow';
24-
25-
import ViewList from 'material-ui-icons/ViewList';
26-
import ViewModule from 'material-ui-icons/ViewModule';
27-
2810
import WithDocumentation from 'src/components/WithDocumentation';
29-
import LinodeCard from './LinodeCard';
30-
import LinodeRow from './LinodeRow';
11+
12+
import LinodesListView from './LinodesListView';
13+
import LinodesGridView from './LinodesGridView';
3114
import ListLinodesEmptyState from './ListLinodesEmptyState';
15+
import ToggleBox from './ToggleBox';
3216

3317
import './linodes.css';
3418

35-
type CSSClasses =
36-
'toggleBox'
37-
| 'toggleButton'
38-
| 'toggleButtonActive'
39-
| 'toggleButtonLeft'
40-
| 'toggleButtonRight'
41-
| 'icon';
42-
43-
const styles: StyleRulesCallback<CSSClasses> = (theme: Theme) => ({
44-
toggleBox: {
45-
marginBottom: theme.spacing.unit * 2,
46-
},
47-
toggleButton: {
48-
border: '1px solid #333',
49-
},
50-
toggleButtonActive: {
51-
backgroundColor: '#333',
52-
color: '#f3f3f3',
53-
'&:hover': {
54-
backgroundColor: '#333',
55-
},
56-
},
57-
toggleButtonLeft: {
58-
borderWidth: '1px 0 1px 1px',
59-
borderRadius: '5px 0 0 5px',
60-
},
61-
toggleButtonRight: {
62-
borderWidth: '1px 1px 1px 0',
63-
borderRadius: '0 5px 5px 0',
64-
},
65-
icon: {
66-
marginRight: theme.spacing.unit,
67-
},
68-
});
69-
7019
interface Props {
7120
linodes: Linode.Linode[];
7221
images: Linode.Image[];
7322
types: Linode.LinodeType[];
7423
}
7524

76-
type CombinedProps = Props & WithStyles<CSSClasses> & RouteComponentProps<{}>;
25+
type CombinedProps = Props & RouteComponentProps<{}>;
7726

7827
class ListLinodes extends React.Component<CombinedProps> {
7928
static defaultProps = {
@@ -107,102 +56,31 @@ class ListLinodes extends React.Component<CombinedProps> {
10756
},
10857
];
10958

110-
changeViewStyle(style: string) {
59+
changeViewStyle = (style: string) => {
11160
const { history } = this.props;
11261
history.push(`#${style}`);
11362
}
11463

115-
linodeList() {
116-
const { linodes, images, types } = this.props;
117-
118-
return (
119-
<Paper elevation={1}>
120-
<Grid container>
121-
<Grid item xs={12}>
122-
<Table>
123-
<TableHead>
124-
<TableRow>
125-
<TableCell>Label</TableCell>
126-
<TableCell>Tags</TableCell>
127-
<TableCell>IP Addresses</TableCell>
128-
<TableCell>Region</TableCell>
129-
<TableCell></TableCell>
130-
</TableRow>
131-
</TableHead>
132-
<TableBody>
133-
{linodes.map(linode =>
134-
<LinodeRow
135-
key={linode.id}
136-
linode={linode}
137-
image={images.find(image => linode.image === image.id)}
138-
type={types.find(type => linode.type === type.id)}
139-
/>,
140-
)}
141-
</TableBody>
142-
</Table>
143-
</Grid>
144-
</Grid>
145-
</Paper>
146-
);
147-
}
148-
149-
linodeGrid() {
150-
const { linodes, images, types } = this.props;
151-
152-
return (
153-
<Grid container>
154-
{linodes.map(linode =>
155-
<LinodeCard
156-
key={linode.id}
157-
linode={linode}
158-
image={images.find(image => linode.image === image.id)}
159-
type={types.find(type => linode.type === type.id)}
160-
/>,
161-
)}
162-
</Grid>
163-
);
164-
}
165-
166-
toggleBox() {
167-
const { classes, location: { hash } } = this.props;
168-
169-
return (
170-
<div className={classes.toggleBox}>
171-
<Button
172-
onClick={() => this.changeViewStyle('list')}
173-
className={`
174-
${hash !== '#grid' && classes.toggleButtonActive}
175-
${classes.toggleButton}
176-
${classes.toggleButtonLeft}`
177-
}
178-
>
179-
<ViewList className={classes.icon}/>
180-
List
181-
</Button>
182-
<Button
183-
onClick={() => this.changeViewStyle('grid')}
184-
className={`
185-
${hash === '#grid' && classes.toggleButtonActive}
186-
${classes.toggleButton}
187-
${classes.toggleButtonRight}`
188-
}
189-
>
190-
<ViewModule className={classes.icon}/>
191-
Grid
192-
</Button>
193-
</div>
194-
);
195-
}
196-
19764
listLinodes() {
19865
const { location: { hash } } = this.props;
19966

20067
return (
20168
<React.Fragment>
202-
{this.toggleBox()}
69+
<ToggleBox
70+
handleClick={this.changeViewStyle}
71+
status={hash === '#grid' ? 'grid' : 'list'}
72+
/>
20373
{hash === '#grid'
204-
? this.linodeGrid()
205-
: this.linodeList()
74+
? <LinodesGridView
75+
linodes={this.props.linodes}
76+
images={this.props.images}
77+
types={this.props.types}
78+
/>
79+
: <LinodesListView
80+
linodes={this.props.linodes}
81+
images={this.props.images}
82+
types={this.props.types}
83+
/>
20684
}
20785
</React.Fragment>
20886
);
@@ -231,6 +109,5 @@ const mapStateToProps = (state: any) => ({
231109

232110
export default compose(
233111
connect<Props>(mapStateToProps),
234-
withStyles(styles, { withTheme: true }),
235112
withRouter,
236113
)(ListLinodes);

0 commit comments

Comments
 (0)