Skip to content

Commit 651ada7

Browse files
potik1mysiar
authored andcommitted
React Native generator (#86)
* template fix * test fix * templates update * working but still in progress * list fixed * list fixed * finished * dependencies update
1 parent f961c25 commit 651ada7

File tree

13 files changed

+2382
-1130
lines changed

13 files changed

+2382
-1130
lines changed

package.json

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,29 +16,29 @@
1616
"author": "Kévin Dunglas",
1717
"license": "MIT",
1818
"devDependencies": {
19-
"babel-cli": "^6.24.0",
20-
"babel-core": "^6.24.0",
21-
"babel-eslint": "^7.2.0",
22-
"babel-jest": "^19.0.0",
19+
"babel-cli": "^6.26.0",
20+
"babel-core": "^6.26.3",
21+
"babel-eslint": "^10.0.0",
22+
"babel-jest": "^23.6.0",
2323
"babel-plugin-transform-flow-strip-types": "^6.22.0",
2424
"babel-plugin-transform-runtime": "^6.23.0",
25-
"babel-preset-es2015": "^6.24.0",
26-
"babel-preset-stage-0": "^6.22.0",
27-
"eslint": "^3.18.0",
28-
"eslint-config-prettier": "^2.9.0",
29-
"eslint-plugin-import": "^2.2.0",
30-
"eslint-plugin-prettier": "^2.6.0",
31-
"jest": "^23",
32-
"prettier": "^1.13.2",
33-
"tmp": "^0.0.31"
25+
"babel-preset-es2015": "^6.24.1",
26+
"babel-preset-stage-0": "^6.24.1",
27+
"eslint": "^5.6.0",
28+
"eslint-config-prettier": "^3.1.0",
29+
"eslint-plugin-import": "^2.14.0",
30+
"eslint-plugin-prettier": "^2.6.2",
31+
"jest": "^23.6.0",
32+
"prettier": "^1.14.3",
33+
"tmp": "^0.0.33"
3434
},
3535
"dependencies": {
3636
"@api-platform/api-doc-parser": "^0.5.0",
37-
"babel-runtime": "^6.23.0",
38-
"chalk": "^2.1.0",
39-
"commander": "^2.9.0",
40-
"handlebars": "^4.0.6",
41-
"handlebars-helpers": "^0.9.8",
37+
"babel-runtime": "^6.26.0",
38+
"chalk": "^2.4.1",
39+
"commander": "^2.18.0",
40+
"handlebars": "^4.0.12",
41+
"handlebars-helpers": "^0.10.0",
4242
"isomorphic-fetch": "^2.2.1",
4343
"mkdirp": "^0.5.1",
4444
"sprintf-js": "^1.1.1"

src/generators/ReactNativeGenerator.js

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
import chalk from "chalk";
2+
import handlebars from "handlebars";
23
import BaseGenerator from "./BaseGenerator";
34

45
export default class extends BaseGenerator {
56
constructor(params) {
67
super(params);
78

9+
handlebars.registerHelper("ifNotResource", function(item, options) {
10+
if (item === null) {
11+
return options.fn(this);
12+
}
13+
return options.inverse(this);
14+
});
15+
816
this.registerTemplates(`react-common/`, [
917
// actions
1018
"actions/foo/create.js",
@@ -25,14 +33,22 @@ export default class extends BaseGenerator {
2533
"reducers/foo/show.js"
2634
]);
2735

28-
this.registerTemplates(`react/`, [
36+
this.registerTemplates(`react-native/`, [
2937
// components
3038
"components/foo/Create.js",
3139
"components/foo/Form.js",
3240
"components/foo/index.js",
3341
"components/foo/List.js",
3442
"components/foo/Update.js",
35-
"components/foo/Show.js"
43+
"components/foo/Show.js",
44+
"components/Spinner.js",
45+
"components/Confirm.js",
46+
47+
// routes
48+
"routes/foo.js",
49+
50+
// helpers
51+
"utils/helpers.js"
3652
]);
3753
}
3854

@@ -75,7 +91,7 @@ combineReducers(${titleLc},{/* ... */}),
7591

7692
// Create directories
7793
// These directories may already exist
78-
for (let dir of [`${dir}/utils`, `${dir}/config`]) {
94+
for (let dir of [`${dir}/utils`, `${dir}/config`, `${dir}/routes`]) {
7995
this.createDir(dir, false);
8096
}
8197

@@ -109,12 +125,23 @@ combineReducers(${titleLc},{/* ... */}),
109125
"reducers/%s/index.js",
110126
"reducers/%s/list.js",
111127
"reducers/%s/update.js",
112-
"reducers/%s/show.js"
128+
"reducers/%s/show.js",
129+
130+
// routes
131+
"routes/%s.js"
113132
]) {
114133
this.createFileFromPattern(pattern, dir, lc, context);
115134
}
116135

117-
this.createFile("utils/fetch.js", `${dir}/utils/fetch.js`, context, false);
136+
for (let file of [
137+
"utils/fetch.js",
138+
"utils/helpers.js",
139+
"components/Spinner.js",
140+
"components/Confirm.js"
141+
]) {
142+
this.createFile(file, `${dir}/${file}`);
143+
}
144+
118145
this.createEntrypoint(api.entrypoint, `${dir}/config/_entrypoint.js`);
119146
}
120147
}

src/generators/ReactNativeGenerator.test.js

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ test("Generate a React app", () => {
4545
"/actions/abc/update.js",
4646

4747
"/components/abc/Create.js",
48+
"/components/abc/Form.js",
49+
"/components/abc/index.js",
50+
"/components/abc/List.js",
51+
"/components/abc/Show.js",
4852
"/components/abc/Update.js",
4953

5054
"/reducers/abc/create.js",
@@ -55,14 +59,5 @@ test("Generate a React app", () => {
5559
"/reducers/abc/update.js"
5660
].forEach(file => expect(fs.existsSync(tmpobj.name + file)).toBe(true));
5761

58-
[
59-
"/components/abc/Form.js",
60-
"/components/abc/List.js",
61-
"/components/abc/Show.js"
62-
].forEach(file => {
63-
expect(fs.existsSync(tmpobj.name + file)).toBe(true);
64-
expect(fs.readFileSync(tmpobj.name + file, "utf8")).toMatch(/bar/);
65-
});
66-
6762
tmpobj.removeCallback();
6863
});
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import React from 'react';
2+
import { Text, View, Modal, TouchableOpacity } from 'react-native';
3+
import PropTypes from 'prop-types';
4+
5+
6+
const Confirm = ({children, visible, onAccept, onDecline}) => {
7+
8+
const {textStyle, containerStyle, viewStyle, buttonStyle, textButtonStyle} = styles;
9+
10+
return (
11+
12+
<Modal
13+
visible={visible}
14+
transparent
15+
animationType="slide"
16+
onRequestClose={() => {}}
17+
>
18+
<View style={containerStyle}>
19+
<View style={viewStyle}>
20+
<Text style={textStyle}>{children}</Text>
21+
</View>
22+
23+
<View style={viewStyle}>
24+
<TouchableOpacity onPress={onAccept} style={ buttonStyle }>
25+
<Text style={ textButtonStyle }>Yes
26+
</Text>
27+
</TouchableOpacity>
28+
<TouchableOpacity onPress={onDecline} style={ buttonStyle }>
29+
<Text style={ textButtonStyle }>No
30+
</Text>
31+
</TouchableOpacity>
32+
</View>
33+
</View>
34+
</Modal>
35+
);
36+
};
37+
38+
const styles = {
39+
textStyle: {
40+
flex: 1,
41+
fontSize: 18,
42+
textAlign: 'center',
43+
lineHeight: 40,
44+
},
45+
containerStyle: {
46+
backgroundColor: 'rgba(0,0,0,0.75)',
47+
position: 'relative',
48+
flex: 1,
49+
justifyContent: 'center',
50+
51+
},
52+
viewStyle:{
53+
borderBottomWidth:1,
54+
padding:10,
55+
backgroundColor: '#fff',
56+
justifyContent: 'flex-start',
57+
flexDirection:'row',
58+
borderColor:'#ddd',
59+
position: 'relative',
60+
},
61+
buttonStyle:{
62+
flex: 1,
63+
alignSelf: 'stretch',
64+
backgroundColor: '#fff',
65+
borderRadius: 5,
66+
borderWidth: 1,
67+
borderColor: '#3faab4',
68+
marginRight: 5,
69+
marginLeft: 5,
70+
},
71+
textButtonStyle: {
72+
alignSelf: 'center',
73+
color: '#3faab4',
74+
fontSize:16,
75+
fontWeight:'600',
76+
paddingTop:10,
77+
paddingBottom:10,
78+
},
79+
};
80+
81+
Confirm.propTypes = {
82+
onDecline: PropTypes.func,
83+
onAccept: PropTypes.func,
84+
visible: PropTypes.bool,
85+
children: PropTypes.string,
86+
};
87+
88+
export { Confirm };
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import React from 'react';
2+
import { View, ActivityIndicator } from 'react-native';
3+
import PropTypes from 'prop-types';
4+
5+
const Spinner = ({size}) => {
6+
return (
7+
<View style={styles.spinnerStyle} >
8+
<ActivityIndicator size={size || 'large'} />
9+
</View>
10+
);
11+
};
12+
13+
const styles = {
14+
spinnerStyle: {
15+
flex: 1,
16+
justifyContent: 'center',
17+
alignItems: 'center'
18+
},
19+
};
20+
21+
Spinner.propTypes={
22+
size: PropTypes.string.isRequired
23+
};
24+
25+
export default Spinner;
Lines changed: 54 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,51 @@
1-
import React, {Component} from 'react';
2-
import {ScrollView, Text} from 'react-native';
3-
import {connect} from 'react-redux';
1+
import React, { Component } from 'react';
2+
import { View, Text, ScrollView } from 'react-native';
3+
import { connect } from 'react-redux';
44
import PropTypes from 'prop-types';
55
import Form from './Form';
6-
import { create, loading, error } from '../../actions/{{{ lc }}}/create';
6+
import { create, loading, error } from '../../actions/{{{lc}}}/create';
7+
import { Actions } from 'react-native-router-flux';
8+
import { delayRefresh } from '../../utils/helpers';
79

810
class Create extends Component {
9-
static propTypes = {
10-
error: PropTypes.string,
11-
loading: PropTypes.bool.isRequired,
12-
created: PropTypes.object,
13-
create: PropTypes.func.isRequired,
14-
reset: PropTypes.func.isRequired,
15-
};
1611

1712
componentWillUnmount() {
1813
this.props.reset();
1914
}
2015

16+
onSubmit = values => {
17+
this.props.create(values);
18+
Actions.{{{lc}}}List();
19+
delayRefresh();
20+
};
21+
2122
render() {
23+
24+
if (this.props.created) return Actions.pop();
25+
26+
const {viewStyle, textStyle} = styles;
27+
2228
return (
23-
<ScrollView>
24-
<Text>Create component {{lc}}</Text>
25-
</ScrollView>
29+
<View>
30+
<ScrollView keyboardShouldPersistTaps='always'>
31+
{this.props.error && <View style={viewStyle}><Text
32+
style={textStyle}>{this.props.error}</Text></View>}
33+
<Form mySubmit={values => this.onSubmit(values)}/>
34+
</ScrollView>
35+
</View>
2636
);
2737
}
2838
}
2939

30-
const mapStateToProps = (state) => {
40+
const mapStateToProps = state => {
3141
return {
32-
created: state.{{{ lc }}}.create.created,
33-
error: state.{{{ lc }}}.create.error,
34-
loading: state.{{{ lc }}}.create.loading,
35-
};
42+
created: state.{{{lc}}}.create.created,
43+
error: state.{{{lc}}}.create.error,
44+
loading: state.{{{lc}}}.create.loading,
45+
};
3646
};
3747

38-
const mapDispatchToProps = (dispatch) => {
48+
const mapDispatchToProps = dispatch => {
3949
return {
4050
create: values => dispatch(create(values)),
4151
reset: () => {
@@ -45,4 +55,28 @@ const mapDispatchToProps = (dispatch) => {
4555
};
4656
};
4757

58+
const styles = {
59+
viewStyle: {
60+
borderBottomWidth: 1,
61+
padding: 5,
62+
backgroundColor: '#fff',
63+
justifyContent: 'flex-start',
64+
flexDirection: 'row',
65+
borderColor: '#ddd',
66+
position: 'relative',
67+
},
68+
textStyle: {
69+
color: 'red',
70+
textAlign: 'center',
71+
},
72+
};
73+
74+
Create.propTypes = {
75+
error: PropTypes.string,
76+
loading: PropTypes.bool.isRequired,
77+
created: PropTypes.object,
78+
create: PropTypes.func.isRequired,
79+
reset: PropTypes.func.isRequired
80+
};
81+
4882
export default connect(mapStateToProps, mapDispatchToProps)(Create);

0 commit comments

Comments
 (0)