diff --git a/packages/generator/src/frontend/add/templates/Add.js.template b/packages/generator/src/frontend/add/templates/Add.js.template new file mode 100644 index 0000000..7bbdec1 --- /dev/null +++ b/packages/generator/src/frontend/add/templates/Add.js.template @@ -0,0 +1,109 @@ +import React, { Component, PropTypes } from 'react'; +import Relay from 'react-relay'; +import RelayStore from '../../RelayStore'; +import { withRouter } from 'react-router'; + +import <%= name %>AddMutation from './<%= name %>AddMutation'; + +import Form from '../common/Form'; + +class <%= name %>Add extends Component { + static contextTypes = { + showSnackbar: PropTypes.func, + }; + + fields = [ + { + name: 'id', + placeholder: 'ID', + required: true, + }, + // TODO - add ObjectType fields here + ]; + + onSubmit = (data) => { + const mutation = new <%= name %>AddMutation({ + viewer: this.props.viewer, + ...data, + }); + + RelayStore.commitUpdate(mutation, { + onSuccess: ({ <%= name %>Add }) => { + this.context.showSnackbar({ + message: '<%= rawName %> created successfully!', + }); + + this.props.router.push(`/<%= pluralName %>/view/${<%= name %>Add.<%= rawName %>Edge.node.id}`); + }, + onFailure: (failureResponse) => { + this.context.showSnackbar({ + message: 'There was an error while trying to create a <%= rawName %>.', + }); + + console.log('FAIL', failureResponse); + }, + }); + }; + + render() { + return ( +
+

+ New <%= name %> +

+
+
+ ); + } +} + +const styles = { + form: { + backgroundColor: 'white', + boxShadow: 'rgba(0, 0, 0, 0.056863) 0px 7px 8px, rgba(0, 0, 0, 0.227451) 0px 0px 0px', + borderWidth: 1, + borderStyle: 'solid', + borderColor: '#E7ECEA', + padding: 20, + paddingTop: 50, + }, + formContainer: { + display: 'flex', + flexWrap: 'wrap', + }, + title: { + fontSize: 25, + fontWeight: 300, + }, + actionsContainer: { + display: 'flex', + justifyContent: 'flex-end', + marginTop: 5, + paddingRight: 8, + borderTopStyle: 'solid', + borderTopWidth: 1, + paddingTop: 15, + borderColor: '#ECECEC', + }, + formField: { + marginRight: 10, + flex: '1 0 47%', + }, + selectField: { + marginRight: 10, + flex: '1 0 48%', + }, +}; + +export default Relay.createContainer(withRouter(<%= name %>Add), { + fragments: { + viewer: () => Relay.QL` + fragment on Viewer { + ${<%= name %>AddMutation.getFragment('viewer')} + } + `, + }, +}); diff --git a/packages/generator/src/frontend/add/templates/AddMutation.js.template b/packages/generator/src/frontend/add/templates/AddMutation.js.template new file mode 100644 index 0000000..8365533 --- /dev/null +++ b/packages/generator/src/frontend/add/templates/AddMutation.js.template @@ -0,0 +1,63 @@ +import Relay from 'react-relay'; + +export default class <%= name %>AddMutation extends Relay.Mutation { + static fragments = { + viewer: () => Relay.QL` + fragment on Viewer { + id + } + `, + }; + + getMutation() { + return Relay.QL`mutation { + <%= name %>Add + }`; + } + + getVariables() { + const { + id + // TODO - add mutation input fields here + } = this.props; + + return { + id + // TODO - add mutation input fields here + }; + } + + getFatQuery() { + return Relay.QL` + fragment on <%= name %>AddPayload { + <%= rawName %>Edge + viewer { + <%= pluralName %> + } + } + `; + } + + getConfigs() { + return [ + { + type: 'RANGE_ADD', + parentName: 'viewer', + parentID: this.props.viewer.id, + connectionName: '<%= pluralName %>', + edgeName: '<%= rawName %>Edge', + rangeBehaviors: { + '': 'prepend', + }, + }, + { + type: 'REQUIRED_CHILDREN', + children: [Relay.QL` + fragment on <%= name %>AddPayload { + <%= rawName %>Edge + } + `], + }, + ]; + } +} diff --git a/packages/generator/src/frontend/edit/templates/Edit.js.template b/packages/generator/src/frontend/edit/templates/Edit.js.template new file mode 100644 index 0000000..1e4bd0a --- /dev/null +++ b/packages/generator/src/frontend/edit/templates/Edit.js.template @@ -0,0 +1,106 @@ +import React, { Component, PropTypes } from 'react'; +import Relay from 'react-relay'; +import RelayStore from '../../../RelayStore'; +import { withRouter } from 'react-router'; + +import <%= name %>EditMutation from './<%= name %>EditMutation.js'; + +import Form from '../../common/Form'; + +class <%= name %>Edit extends Component { + static contextTypes = { + showSnackbar: PropTypes.func, + }; + + fields = [ + { + name: 'id', + placeholder: 'ID', + required: true, + }, + // TODO - add ObjectType fields here + ]; + + onSubmit = (data) => { + const { company } = this.props; + + const mutation = new <%= rawName %>EditMutation({ + ...data, + }); + + RelayStore.commitUpdate(mutation, { + onSuccess: () => { + this.context.showSnackbar({ + message: '<%= name %> edited successfully!', + }); + + this.props.router.goBack(); + }, + onFailure: (failureResponse) => { + this.context.showSnackbar({ + message: 'There was an error while trying to edit this <%= rawName %>.', + }); + + console.log('FAIL', failureResponse); + }, + }); + }; + + render() { + const { <%= rawName %> } = this.props; + + return ( + } + /> + ); + } +} + +const styles = { + formContainer: { + display: 'flex', + flexWrap: 'wrap', + paddingTop: 30, + paddingLeft: 10, + }, + actionsContainer: { + display: 'flex', + justifyContent: 'flex-end', + marginTop: 5, + paddingRight: 8, + borderTopStyle: 'solid', + borderTopWidth: 1, + paddingTop: 15, + borderColor: '#ECECEC', + }, + formField: { + marginRight: 10, + flex: '1 0 47%', + }, + selectField: { + marginRight: 10, + flex: '1 0 48%', + }, +}; + +export default Relay.createContainer(withRouter(<%= name %>Edit), { + initialVariables: { + id: null, + }, + fragments: { + <%= rawName %>: () => Relay.QL` + fragment on <%= name %> { + id + ${<%= name %>EditMutation.getFragment('<%= rawName %>')} + } + `, + viewer: () => Relay.QL` + fragment on Viewer { + id + } + `, + }, +}); diff --git a/packages/generator/src/frontend/edit/templates/EditMutation.js.template b/packages/generator/src/frontend/edit/templates/EditMutation.js.template new file mode 100644 index 0000000..85156de --- /dev/null +++ b/packages/generator/src/frontend/edit/templates/EditMutation.js.template @@ -0,0 +1,48 @@ +import Relay from 'react-relay'; + +export default class <%= name %>EditMutation extends Relay.Mutation { + static fragments = { + <%= rawName %>: () => Relay.QL` + fragment on <%= name %> { + id + } + `, + }; + + getMutation() { + return Relay.QL`mutation { + <%= name %>Edit + }`; + } + + getVariables() { + const { + <%= rawName %>: { + id, + }, + // Todo add more mutation input fields here + } = this.props; + + return { + id, + // Todo add more mutation input fields here + }; + } + + getFatQuery() { + return Relay.QL` + fragment on FlightEditPayload { + <%= rawName %> + } + `; + } + + getConfigs() { + return [{ + type: 'FIELDS_CHANGE', + fieldIDs: { + <%= rawName %>: this.props.<%= rawName %>.id, + }, + }]; + } +} diff --git a/packages/generator/src/frontend/list/index.js b/packages/generator/src/frontend/list/index.js new file mode 100644 index 0000000..532f87f --- /dev/null +++ b/packages/generator/src/frontend/list/index.js @@ -0,0 +1,62 @@ +import Generator from 'yeoman-generator'; +import pluralize from 'pluralize'; +import { + getMongooseModelSchema, + getConfigDir, + getRelativeConfigDir, + camelCaseText, + uppercaseFirstLetter, +} from '../../utils'; + +class ListGenerator extends Generator { + constructor(args, options) { + super(args, options); + + this.argument('name', { + type: String, + required: true, + }); + + // TODO read schema.json + + this.destinationDir = getConfigDir('list'); + } + + _getConfigDirectories() { + return getRelativeConfigDir('loader', ['model', 'connection']); + } + + generateList() { + // const schema = this.options.model ? + // getMongooseModelSchema(this.options.model, true) + // : null; + + const name = uppercaseFirstLetter(this.options.name); + + const templatePath = this.templatePath('List.js.template'); + + // const templatePath = schema ? + // this.templatePath('LoaderWithSchema.js.template') + // : this.templatePath('Loader.js.template'); + // + // const directories = this._getConfigDirectories(); + + const pluralName = pluralize(this.options.name); + + const destinationPath = this.destinationPath(`${this.destinationDir}/${name}List.js`); + const templateVars = { + name, + rawName: this.options.name, + pluralName, + pluralCamelCaseName: camelCaseText(pluralName), + }; + + this.fs.copyTpl(templatePath, destinationPath, templateVars); + } + + end() { + this.log('🔥 List created!'); + } +} + +module.exports = ListGenerator; diff --git a/packages/generator/src/frontend/list/templates/List.js.template b/packages/generator/src/frontend/list/templates/List.js.template new file mode 100644 index 0000000..8f739e4 --- /dev/null +++ b/packages/generator/src/frontend/list/templates/List.js.template @@ -0,0 +1,120 @@ +// @flow + +import React, { Component } from 'react'; +import Relay from 'react-relay'; +import { withRouter } from 'react-router'; + +import Table from '../common/Table'; +import Toolbar from '../common/Toolbar'; + +class <%= name %>List extends Component { + state = { + isLoading: true, + }; + + tableColumns = [ + { + property: '', + header: { + label: 'Actions', + }, + icon: 'mode_edit', + type: 'icon', + clickPath: '/<%= pluralName %>/view/:id', + }, + { + property: 'id', + header: { + label: 'ID', + }, + }, + // TODO - add more fields to table + ]; + + componentDidMount = () => { + this.setState({ + isLoading: false, + }); + }; + + _handleNew = () => this.props.router.push('/<%= pluralName %>/new'); + + _handleRefreshList = () => { + this.setState({ + isLoading: true, + }); + + this.props.relay.forceFetch({}, ({ done }) => { + if (done) { + this.setState({ + isLoading: false, + }); + } + }); + }; + + _handleLoadMore = () => { + const { relay } = this.props; + + this.setState({ + isLoading: true, + }); + + relay.setVariables({ + count: relay.variables.count + 10, + }, ({ done }) => { + if (done) { + this.setState({ + isLoading: false, + }); + } + }); + }; + + render() { + const { isLoading } = this.state; + + return ( +
+ + primaryActionLabel="New <%= name %>" + primaryActionOnClick={this._handleNew} + onRefresh={this._handleRefreshList} + /> + + } + router={this.props.router} + onLoadMore={this._handleLoadMore} + isLoading={isLoading} + /> + + ); + } +} + +export default Relay.createContainer(withRouter(<%= name %>List), { + initialVariables: { + count: 20, + }, + fragments: { + viewer: () => Relay.QL` + fragment on Viewer { + <%= pluralName %>(first: $count) { + pageInfo { + hasNextPage + } + edges { + node { + id + // TODO - add relay fields + } + } + } + } + `, + }, +}); diff --git a/packages/generator/src/frontend/view/templates/View.js.template b/packages/generator/src/frontend/view/templates/View.js.template new file mode 100644 index 0000000..0a81b6b --- /dev/null +++ b/packages/generator/src/frontend/view/templates/View.js.template @@ -0,0 +1,57 @@ +import React, { Component } from 'react'; +import Relay from 'react-relay'; +import { withRouter } from 'react-router'; + +import <%= name %>Edit from './<%= name %>Edit'; + +import Tabs from '../../common/Tabs'; + +class <%= name %>View extends Component { + render() { + const { viewer } = this.props; + const { <%= rawName %> } = viewer; + + const tabs = [{ + label: 'Details', + component: ( + ={<%= rawName %>} + viewer={viewer} + /> + ), + icon: 'assignment', + }]; + + return ( +
+

<%= name %>: {<%= rawName %>.id}

+ + +
+ ); + } +} + +const styles = { + title: { + fontSize: 25, + fontWeight: 300, + }, +}; + +export default Relay.createContainer(withRouter(<%= name %>View), { + initialVariables: { + id: null, + }, + fragments: { + viewer: ({ id }) => Relay.QL` + fragment on Viewer { + <%= rawName %>(id: $id) { + id + ${<%= name %>Edit.getFragment('<%= rawName %>')} + } + ${<%= name %>Edit.getFragment('viewer')} + } + `, + }, +});