Skip to content

Commit 2f1ae4e

Browse files
committed
lift common state management above card and list view
1 parent 4124c31 commit 2f1ae4e

File tree

3 files changed

+46
-68
lines changed

3 files changed

+46
-68
lines changed

src/features/linodes/ListLinodes/LinodeCard.tsx

Lines changed: 19 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
import * as React from 'react';
2-
import { compose } from 'redux';
3-
import { connect } from 'react-redux';
4-
import { pathOr } from 'ramda';
52
import * as copy from 'copy-to-clipboard';
63

74
import {
@@ -52,8 +49,6 @@ type CSSClasses =
5249
'cardSection'
5350
| 'distroIcon'
5451
| 'rightMargin'
55-
| 'regionIndicator'
56-
| 'flagImg'
5752
| 'cardActions'
5853
| 'button'
5954
| 'consoleButton'
@@ -70,12 +65,6 @@ const styles: StyleRulesCallback<CSSClasses> = (theme: Theme) => ({
7065
rightMargin: {
7166
marginRight: theme.spacing.unit,
7267
},
73-
regionIndicator: {
74-
alignItems: 'center',
75-
},
76-
flagImg: {
77-
marginRight: theme.spacing.unit,
78-
},
7968
cardActions: {
8069
backgroundColor: '#f9f9f9',
8170
padding: 0,
@@ -97,8 +86,8 @@ const styles: StyleRulesCallback<CSSClasses> = (theme: Theme) => ({
9786

9887
interface Props {
9988
linode: Linode.Linode;
100-
image: Linode.Image;
101-
type: Linode.LinodeType;
89+
image?: Linode.Image;
90+
type?: Linode.LinodeType;
10291
}
10392

10493
class LinodeCard extends React.Component<Props & WithStyles<CSSClasses> > {
@@ -124,21 +113,23 @@ class LinodeCard extends React.Component<Props & WithStyles<CSSClasses> > {
124113
<div>
125114
{tags.map((tag: string, idx) => <Tag key={idx} label={tag} />)}
126115
</div>
127-
<div className={classes.cardSection}>
128-
<Grid container>
129-
<Grid item className="tac" xs={2}>
130-
<img src={distroIcons[image.vendor]} className={classes.distroIcon}/>
131-
</Grid>
132-
<Grid item xs={9}>
133-
<Typography variant="subheading">
134-
{image.label}
135-
</Typography>
136-
<Typography>
137-
{typeLabelLong(type.memory, type.disk, type.vcpus)}
138-
</Typography>
116+
{image && type &&
117+
<div className={classes.cardSection}>
118+
<Grid container>
119+
<Grid item className="tac" xs={2}>
120+
<img src={distroIcons[image.vendor]} className={classes.distroIcon}/>
121+
</Grid>
122+
<Grid item xs={9}>
123+
<Typography variant="subheading">
124+
{image.label}
125+
</Typography>
126+
<Typography>
127+
{typeLabelLong(type.memory, type.disk, type.vcpus)}
128+
</Typography>
129+
</Grid>
139130
</Grid>
140-
</Grid>
141-
</div>
131+
</div>
132+
}
142133
<div className={classes.cardSection}>
143134
<div>
144135
<Typography variant="body2">
@@ -180,18 +171,4 @@ class LinodeCard extends React.Component<Props & WithStyles<CSSClasses> > {
180171
}
181172
}
182173

183-
const mapStateToProps = (state: Linode.AppState, ownProps: Props) => {
184-
const typesCollection = pathOr([], ['api', 'linodeTypes', 'data'], state);
185-
const imagesCollection = pathOr([], ['api', 'images', 'data'], state);
186-
const { type, image } = ownProps.linode as Linode.Linode;
187-
188-
return {
189-
image: imagesCollection.find((i: Linode.Image) => i.id === image),
190-
type: typesCollection.find((t: Linode.LinodeType) => t.id === type),
191-
};
192-
};
193-
194-
export default compose<Linode.TodoAny, Linode.TodoAny, Linode.TodoAny>(
195-
connect(mapStateToProps),
196-
withStyles(styles, { withTheme: true }),
197-
)(LinodeCard);
174+
export default withStyles(styles, { withTheme: true })(LinodeCard);

src/features/linodes/ListLinodes/LinodeRow.tsx

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
import * as React from 'react';
22
import { Link } from 'react-router-dom';
3-
import { compose } from 'redux';
4-
import { connect } from 'react-redux';
53
import * as copy from 'copy-to-clipboard';
6-
import { pathOr } from 'ramda';
74

85
import {
96
withStyles,
@@ -39,16 +36,16 @@ function clip(value: string): void {
3936

4037
interface Props {
4138
linode: Linode.Linode;
42-
type: Linode.LinodeType;
43-
image: Linode.Image;
39+
type?: Linode.LinodeType;
40+
image?: Linode.Image;
4441
}
4542

4643
type PropsWithStyles = Props & WithStyles<CSSClasses>;
4744

4845
class LinodeRow extends React.Component<PropsWithStyles> {
4946
render() {
5047
const { classes, linode, type, image } = this.props;
51-
const label = displayLabel(type.memory, image.label);
48+
const specsLabel = type && image && displayLabel(type.memory, image.label);
5249

5350
/**
5451
* @todo Until tags are implemented we're using the group as a faux tag.
@@ -66,7 +63,7 @@ class LinodeRow extends React.Component<PropsWithStyles> {
6663
</Typography>
6764
</Link>
6865
</div>
69-
{label && <div>{label}</div>}
66+
{specsLabel && <div>{specsLabel}</div>}
7067
</div>
7168
</TableCell>
7269
<TableCell>
@@ -107,18 +104,4 @@ class LinodeRow extends React.Component<PropsWithStyles> {
107104
}
108105
}
109106

110-
const mapStateToProps = (state: Linode.AppState, ownProps: Props) => {
111-
const typesCollection = pathOr([], ['api', 'linodeTypes', 'data'], state);
112-
const imagesCollection = pathOr([], ['api', 'images', 'data'], state);
113-
const { type, image } = ownProps.linode as Linode.Linode;
114-
115-
return {
116-
image: imagesCollection.find((i: Linode.Image) => i.id === image),
117-
type: typesCollection.find((t: Linode.LinodeType) => t.id === type),
118-
};
119-
};
120-
121-
export default compose<Linode.TodoAny, Linode.TodoAny, Linode.TodoAny>(
122-
connect(mapStateToProps),
123-
withStyles(styles, { withTheme: true }),
124-
)(LinodeRow);
107+
export default withStyles(styles, { withTheme: true })(LinodeRow);

src/features/linodes/ListLinodes/index.tsx

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ const styles: StyleRulesCallback<CSSClasses> = (theme: Theme) => ({
6969

7070
interface Props {
7171
linodes: Linode.Linode[];
72+
images: Linode.Image[];
73+
types: Linode.LinodeType[];
7274
}
7375

7476
type CombinedProps = Props & WithStyles<CSSClasses> & RouteComponentProps<{}>;
@@ -111,7 +113,7 @@ class ListLinodes extends React.Component<CombinedProps> {
111113
}
112114

113115
linodeList() {
114-
const { linodes } = this.props;
116+
const { linodes, images, types } = this.props;
115117

116118
return (
117119
<Paper elevation={1}>
@@ -128,7 +130,14 @@ class ListLinodes extends React.Component<CombinedProps> {
128130
</TableRow>
129131
</TableHead>
130132
<TableBody>
131-
{linodes.map(linode => <LinodeRow key={linode.id} linode={linode} />)}
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+
)}
132141
</TableBody>
133142
</Table>
134143
</Grid>
@@ -138,11 +147,18 @@ class ListLinodes extends React.Component<CombinedProps> {
138147
}
139148

140149
linodeGrid() {
141-
const { linodes } = this.props;
150+
const { linodes, images, types } = this.props;
142151

143152
return (
144153
<Grid container>
145-
{linodes.map(linode => <LinodeCard key={linode.id} linode={linode}/>)}
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+
)}
146162
</Grid>
147163
);
148164
}
@@ -209,6 +225,8 @@ class ListLinodes extends React.Component<CombinedProps> {
209225

210226
const mapStateToProps = (state: any) => ({
211227
linodes: pathOr([], ['api', 'linodes', 'data'], state),
228+
types: pathOr([], ['api', 'linodeTypes', 'data'], state),
229+
images: pathOr([], ['api', 'images', 'data'], state),
212230
});
213231

214232
export default compose(

0 commit comments

Comments
 (0)