import express from 'express'; import { graphqlExpress, graphiqlExpress } from 'graphql-server-express'; import bodyParser from 'body-parser'; import cors from 'cors'; import { schema } from './schema'; import { execute, subscribe } from 'graphql'; import { createServer } from 'http'; import { SubscriptionServer } from 'subscriptions-transport-ws'; import db from 'sqlite'; import connectors from './connectors'; import jwt from'express-jwt'; const { GQLSERVERLOCAL, GQLSERVERPROD, WEBSERVER, PATH, DATABASE, AUTH } = require('./config'); let p = db.open(DATABASE.NAME).then(db =>{ console.error("SQLite: DB ok "); }).catch(error => { console.error("SQLite: DB error: " + error); }); const server = express(); const corsOptions = { origin(origin, callback){ callback(null, true); }, credentials: true }; server.use(cors(corsOptions)); server.use(PATH.GQL, bodyParser.json(), jwt({ secret: AUTH.secret, credentialsRequired: false, getToken: function fromHeaderOrQuerystring (req) { if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') { return req.headers.authorization.split(' ')[1]; } else if (req.query && req.query.token) { return req.query.token; } return null; } }), graphqlExpress(req => ({ schema: schema, context: { user: req.user ? connectors.findUser(req.user.id) : Promise.resolve(null), }, // context resolvers.js }))); // , websockets const ws = createServer(server); server.use(PATH.GIQL, graphiqlExpress({ endpointURL: PATH.GQL, subscriptionsEndpoint: `ws://${GQLSERVERPROD.HOST}:${GQLSERVERPROD.PORT}/subscriptions` })); ws.listen(GQLSERVERPROD.PORT, () => { console.log(`GraphQL Server v1 is now running on ${GQLSERVERPROD.HOST}:${GQLSERVERPROD.PORT}`); new SubscriptionServer({ execute, subscribe, schema }, { server: ws, path: PATH.SUBS, }); });
[...] type DeletePlantResult { rows_changed: Int error: String } input IdsInput { ids: [String] } deletePlant(data: IdsInput): DeletePlantResult [...]
import connectors from './connectors'; export const resolvers = { Mutation: { [...] deletePlant: (root, params, context) => { // context , server.js [...] const errors = []; const {data} = params const ids = data.ids.map(function(id){ return "'" + id + "'" }).join(",") return connectors.deletePlant(ids) .then(rows_changed => ({ rows_changed, errors })) .catch((err) => { if (err.code && err.message) { errors.push({ key: err.code, value: err.message }); return { errors }; } }); },//deletePlant } [...] }
deletePlant(ids) { return new Promise((resolve, reject) => { return db.run(` DELETE FROM 'plants' WHERE id IN(${ids}) `) .then((plant) => { resolve(plant.changes); }) .catch((err) => { return reject(err); }); }) },//deletePlant
import React from 'react'; import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table'; import { reduxForm } from 'redux-form'; import { Button, ProgressBar } from 'react-bootstrap'; [...] class PlantsPage extends React.Component { addEmptyItem() { this.props.addPlant({ variables: {data: {firm_id:this.props.params.firm_id, user_crt_id:'system_user',user_mod_id:'system_user'}} }); } [...] }; render() { if (this.props.data.loading) return <ProgressBar active bsStyle="info" now={100} />; return ( <div className="container"> <h1></h1> <BootstrapTable data={ this.props.data.getPlants.plants } [...] > <TableHeaderColumn dataField='title' [...] ></TableHeaderColumn> [...] </BootstrapTable> <Button [...] onClick={ () => { this.addEmptyItem(); } }> </Button> </div> ) } } [...] export default PlantsPage;
import React from 'react'; import { withRouter } from 'react-router'; import { connect } from 'react-redux'; import gql from 'graphql-tag'; import { graphql, compose } from 'react-apollo'; import PlantsPage from "../components/PlantsPage"; class PlantsContainer extends React.Component { render() { return <PlantsPage {...this.props} />; } }//class const gqlGetPlants = gql` query getForPlants($firm_id:String!,$object_id:String!,$holding_id:String!) { getPlants(firm_id: $firm_id) { plants { id, title, shops_count, [...] }, errors { key, value, } }, } `; const gqlGetPlantsProps = { options: (ownProps) => ({ pollInterval: 0, variables: { firm_id: ownProps.params.firm_id, object_id: ownProps.params.firm_id, holding_id: 'all', }, }), } const gqlAddPlant = gql` mutation ($data: PlantInput) { addPlant(data: $data) { id, errors { key value } } } `; const gqlAddPlantProps = { name: 'addPlant', options: { refetchQueries: [ 'getForPlants', ], }, }; [...] const PlantsWithData = compose( graphql(gqlUpdatePlant, gqlUpdatePlantProps), graphql(gqlGetPlants, gqlGetPlantsProps), [...] )(withRouter(PlantsContainer)); const PlantsWithDataAndDispatch = connect( null, // mapStateToProps null, // mapDispatchToProps )(PlantsWithData); export default PlantsWithDataAndDispatch
import React from 'react'; import { Field, reduxForm } from 'redux-form'; import { Button, ControlLabel, FormGroup, Alert } from 'react-bootstrap'; const renderErrors = (errors) => ( <Alert bsStyle="warning"> {errors.map((error, index) => <span key={index}>{error.value}</span>)} </Alert> ); class ProfilePage extends React.Component { render() { const errors = this.props.errors <= 0 ? null : renderErrors(this.props.errors) const { handleSubmit } = this.props; return ( <div className="container"> <form onSubmit={handleSubmit} > <FormGroup controlId="firstname"> <ControlLabel>:</ControlLabel> <Field className="form-control" id="firstname" name="firstname" type="text" component="input" placeholder=" (: '')"/> </FormGroup> [...] {errors} <Button type="submit" bsStyle="primary"> </Button> </form> </div> ) } } ProfilePage = reduxForm({ form: 'ProfileForm', enableReinitialize: true, })(ProfilePage); // enableReinitialize: true, - export default ProfilePage;
import React from 'react'; import { withRouter } from 'react-router'; import { connect } from 'react-redux'; import gql from 'graphql-tag'; import { graphql, compose } from 'react-apollo'; import ProfilePage from '../components/ProfilePage'; import { toastr } from 'react-redux-toastr' const jwtDecode = require('jwt-decode'); class ProfileContainer extends React.Component { constructor(props) { super(props); this.state = { errors: [] }; } handleSubmit(data) { this.props.updateProfile({ variables: { data: { firstname: data.firstname, [...] }, id: jwtDecode(localStorage.getItem('token')).id }}) .then((response) => { this.setState({ errors: [] }); if (response.data.updateProfile.errors.length <= 0) { toastr.success('*', ' ', {showCloseButton: false}) } else { this.setState({ errors: response.data.updateProfile.errors }); } }) .catch((err) => { console.error(err); toastr.error('*', ' ', {showCloseButton: false}) }); }//handleSubmit render() { return <ProfilePage {...this.props} onSubmit={this.handleSubmit.bind(this)} errors={this.state.errors} />; } }//class const gqlGetProfile = gql` query getProfile ($user_id: String!) { getProfile(user_id: $user_id) { profile { id, firstname, [...] }, errors { key, value }, } } `; const gqlGetProfileProps = { options: (ownProps) => ({ variables: { user_id: jwtDecode(localStorage.getItem('token')).id, }, }), props: ({ ownProps, data }) => { if (data.loading) { return { initialValues: { test: [] }, errors: [] }; }; return { initialValues: data.getProfile.profile, errors: data.getProfile.errors, }; } } const gqlUpdateProfile = gql` mutation ($data: ProfileInput, $id : String) { updateProfile(data: $data, id : $id) { token, errors { key, value }, } } `; const gqlUpdateProfileProps = { name: 'updateProfile', options: { refetchQueries: [ 'getProfile', ], }, }; const ProfileWithData = compose( graphql(gqlUpdateProfile, gqlUpdateProfileProps), graphql(gqlGetProfile, gqlGetProfileProps), )(withRouter(ProfileContainer)); const ProfileWithDataAndDispatch = connect( null, null )(ProfileWithData); export default ProfileWithDataAndDispatch
import React, { Component } from 'react'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import CheckpointPage from '../components/CheckpointPage'; import { saveCheckpoint } from '../actions/CheckpointsActions'; import { Actions } from 'react-native-router-flux'; import { ToastAndroid } from 'react-native'; class CheckpointContainer extends Component { handleSubmit = (data, dispatch) => { return new Promise((resolve) => { setTimeout(() => { this.props.saveCheckpoint(this.props.checkpoint_id,this.props.checkup_id,data.check_note,data.params).then((result)=>{ ToastAndroid.showWithGravity(' ', ToastAndroid.SHORT, ToastAndroid.BOTTOM); return true; }).catch((error)=>{ ToastAndroid.showWithGravity(' ', ToastAndroid.SHORT, ToastAndroid.BOTTOM); }) resolve(); }, 100) }) } render() { return <CheckpointPage {...this.props} onSubmit={this.handleSubmit.bind(this)} /> } }//class const mapStateToProps = (state) => { return { stateValues: state.checkpointData, }; }; const mapDispatchToProps = (dispatch) => { return bindActionCreators ({ saveCheckpoint: (checkpoint_id, checkup_id, note,formData) => saveCheckpoint(checkpoint_id, checkup_id, note, formData), }, dispatch); } export default connect(mapStateToProps, mapDispatchToProps)(CheckpointContainer);
import React, { Component } from 'react' import styles from '../styles'; import { reduxForm } from 'redux-form/immutable' import { ActionsContainer, Button, FieldsContainer, Fieldset, Form, } from 'react-native-clean-form' import { Input, } from 'react-native-clean-form/redux-form-immutable' import { View, Text, StyleSheet, } from 'react-native' class CheckpointPage extends Component { render() { const { handleSubmit, submitting, onSubmit } = this.props return ( <View style={{marginTop: 80, flex:1, flexDirection: 'column', }}> <Form> <FieldsContainer> <Fieldset label=":" last> { this.props.stateValues.params.map((param, i) => { [...] }) } </Fieldset> <Fieldset label=":" last> <Input name="check_note" label=":" placeholder=", ..." multiline={true} numberOfLines={2} inlineLabel={false} /> </Fieldset> </FieldsContainer> <ActionsContainer> <Button icon="md-checkmark" iconPlacement="right" onPress={handleSubmit(onSubmit)} submitting={submitting}></Button> </ActionsContainer> </Form> </View> ) } } export default reduxForm({ form: 'Form', enableReinitialize: true, keepDirtyOnReinitialize: true, })(CheckpointPage)
import * as types from '../actions/ActionTypes'; var uuid = require('react-native-uuid'); [...] export function saveCheckpointSuccess(data) { return { type: 'SAVE_CHECKPOINT_SUCCESS', data }; } function txUpdateChecks(result, check_id, note) { console.log('CheckpointsActions/txUpdateChecks:', check_id, note); return new Promise(function(resolve, reject) { db.transaction((tx)=>{ tx.executeSql(`UPDATE checks SET note = '${note}', dt_mod = '${nowSQL()}' WHERE checks.id = '${check_id}'`).then(([tx,results]) =>{ result = results.rowsAffected; resolve(result); }).catch((error) => { reject(error); });//catch executeSql });//db.transaction })//return }//txUpdateChecks() [...] export function saveCheckpoint(checkpoint_id, checkup_id, note, values) { return (dispatch) => { let result; return txSelectChecks(checkup_id,checkpoint_id).then((check_id) => { if (!check_id) { txInsertChecks(result,checkpoint_id,checkup_id,note).then((check_id) => txInsertCheckValues(result,check_id,values)) .then((result) => { dispatch(saveCheckpointSuccess(result)); }).catch(error => { dispatch(dbFailed({method:'saveCheckpoint !check_id',error})); }); }//if else { txUpdateChecks(result,check_id,note).then((result) => txUpdateCheckValues(result,check_id,values)) .then((result) => { dispatch(saveCheckpointSuccess(result)); }).catch(error => { dispatch(dbFailed({method:'txUpdateChecks/tx',error})); }); }//else }).catch(error => { dispatch(dbFailed({method:'txSelectChecks/tx',error})); }); }//return }//saveCheckpoint : Actions.routesPage({shop_id:'6f6853d0-a642-11e7-83e7-792a5b00d12c_shop'});
[...] <uses-permission android:name="android.permission.NFC" /> [...] <intent-filter> <action android:name="android.nfc.action.TECH_DISCOVERED"/> </intent-filter> <meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/nfc_tech_filter" /> [...] nfc_tech_filter.xml, , NFC : <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <tech-list> <tech>android.nfc.tech.IsoDep</tech> </tech-list> <tech-list> <tech>android.nfc.tech.NfcA</tech> </tech-list> <tech-list> <tech>android.nfc.tech.NfcB</tech> </tech-list> <tech-list> <tech>android.nfc.tech.NfcF</tech> </tech-list> <tech-list> <tech>android.nfc.tech.NfcV</tech> </tech-list> <tech-list> <tech>android.nfc.tech.Ndef</tech> </tech-list> <tech-list> <tech>android.nfc.tech.NdefFormatable</tech> </tech-list> <tech-list> <tech>android.nfc.tech.MifareClassic</tech> </tech-list> <tech-list> <tech>android.nfc.tech.MifareUltralight</tech> </tech-list> <tech-list> <tech>android.nfc.tech.NfcBarcode</tech> </tech-list> </resources>
const nfcListener = DeviceEventEmitter.addListener('NFCCardID', data => { console.log('NFC id', data.id) [...] })
[...] import { SubscriptionClient, addGraphQLSubscriptions } from 'subscriptions-transport-ws'; wsClient = new SubscriptionClient(`ws://10.0.2.2:3002/subscriptions`, { reconnect: true, timeout: 10000, } ) const networkInterfaceWithSubscriptions = addGraphQLSubscriptions( networkInterface, wsClient, ); function dataIdFromObject (result) { if (result.__typename) { if (result.id !== undefined) { return `${result.__typename}:${result.id}`; } } return null; } const client = new ApolloClient({ networkInterface: networkInterfaceWithSubscriptions, customResolvers: { Query: { channel: (_, args) => { return toIdValue(dataIdFromObject({ __typename: 'Channel', id: 1 })) }, }, }, dataIdFromObject, }); [...]
[...] <Button title=' ' icon={{name:'tap-and-play'}} buttonStyle={styles.button} onPress={ () => { this.props.sendTag({variables: { tag: {shop_id : 1, tag_id : data.tagId} } }).then(res => { ToastAndroid.showWithGravity(` `, ToastAndroid.SHORT, ToastAndroid.BOTTOM); } ).catch(error =>{ ToastAndroid.showWithGravity(` (?)`, ToastAndroid.SHORT, ToastAndroid.BOTTOM); }) ; } } /> [...]
[...] const gqlSendTag = gql` mutation sendTag($tag: TagInput!) { sendTag(tag: $tag) { tag_id shop_id title } } `; const gqlSendTagProps = { name: 'sendTag', options: { }, }; [...]
import express from 'express'; import { createServer } from 'http'; const server = express(); [...] const ws = createServer(server); server.use(PATH.GIQL, graphiqlExpress({ endpointURL: PATH.GQL, subscriptionsEndpoint: `ws://${GQLSERVERLOCAL.HOST}:${GQLSERVERLOCAL.PORT}/subscriptions` })); ws.listen(GQLSERVERLOCAL.PORT, () => { new SubscriptionServer({ execute, subscribe, schema }, { server: ws, path: PATH.SUBS, }); }); [...]
type Mutation { [...] sendTag(tag: TagInput!): Tag } [...] input TagInput{ shop_id: String tag_id: String title: String } type Tag { shop_id: String tag_id: String title: String } type Subscription { tagSent(shop_id: String): Tag } [...]
import { PubSub } from 'graphql-subscriptions'; import { withFilter } from 'graphql-subscriptions'; const pubsub = new PubSub(); [...] export const resolvers = { Mutation: { sendTag: (root, { tag }) => { const newMessage = { title: tag.title, shop_id: tag.shop_id, tag_id: tag.tag_id }; pubsub.publish('tagSent', { tagSent: newMessage, shop_id: '1'}); return newMessage; }, [...] }, Subscription: { tagSent: { subscribe: withFilter(() => pubsub.asyncIterator('tagSent'), (payload, variables) => { return payload.shop_id === variables.shop_id; }), }, [...] }, }
[...] import { SubscriptionClient, addGraphQLSubscriptions } from 'subscriptions-transport-ws'; wsClient = new SubscriptionClient(`ws://localhost:3002/subscriptions`, { reconnect: true, }) const networkInterfaceWithSubscriptions = addGraphQLSubscriptions( networkInterface, wsClient, ); function dataIdFromObject (result) { if (result.__typename) { if (result.id !== undefined) { return `${result.__typename}:${result.id}`; } } return null; } const client = new ApolloClient({ networkInterface: networkInterfaceWithSubscriptions, customResolvers: { Query: { channel: (_, args) => { return toIdValue(dataIdFromObject({ __typename: 'Channel', id: 1 })) }, }, }, dataIdFromObject, }); [...]
import { Field } from 'redux-form'; [...] <Field className="form-control" id="tag_id" name="tag_id" type="text" component="input" placeholder=" ' '"/> [...]
[...] import { change as changeFieldValue } from 'redux-form'; const tagSubscription = gql` subscription tagSent($shop_id: String) { tagSent(shop_id: $shop_id) { tag_id shop_id title }, } ` class AddCheckpointContainer extends React.Component { componentWillMount() { this.props.data.subscribeToMore({ document: tagSubscription, variables: { shop_id: 1, }, onError: (err) => console.error('subscribeToMore ERROR:',err), updateQuery: (prev, {subscriptionData}) => { console.log('updateQuery:',subscriptionData) this.props.changeFieldValue("addCheckpointForm", "tag_id", subscriptionData.data.tagSent.tag_id); } }); }//componentWillMount() [...] }
const util = require('util') util.inspect.defaultOptions.showHidden = false util.inspect.defaultOptions.depth = null util.inspect.defaultOptions.maxArrayLength = 1000 util.inspect.defaultOptions.colors = true [...] console.log("data: ", util.inspect(data))
variable.then(function(result) { console.log('!',result) })
Source: https://habr.com/ru/post/349762/
All Articles