mirror of
https://github.com/Kong/insomnia.git
synced 2026-04-20 14:17:29 -04:00
GraphQL updates and fixes (#421)
This commit is contained in:
@@ -4,7 +4,6 @@ import type {OAuth2Token} from '../../../../models/o-auth-2-token';
|
||||
|
||||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import moment from 'moment';
|
||||
import autobind from 'autobind-decorator';
|
||||
import OneLineEditor from '../../codemirror/one-line-editor';
|
||||
import * as misc from '../../../../common/misc';
|
||||
@@ -17,6 +16,7 @@ import Link from '../../base/link';
|
||||
import {trackEvent} from '../../../../analytics/index';
|
||||
import HelpTooltip from '../../help-tooltip';
|
||||
import PromptButton from '../../base/prompt-button';
|
||||
import TimeFromNow from '../../time-from-now';
|
||||
|
||||
const getAuthorizationUrls = () => authorizationUrls;
|
||||
const getAccessTokenUrls = () => accessTokenUrls;
|
||||
@@ -381,9 +381,9 @@ class OAuth2Auth extends React.PureComponent {
|
||||
return '(never expires)';
|
||||
}
|
||||
|
||||
const expiresAt = new Date(token.expiresAt);
|
||||
const str = moment(expiresAt).fromNow();
|
||||
return <span title={expiresAt.toString()}>(expires {str})</span>;
|
||||
return (
|
||||
<span>(expires <TimeFromNow timestamp={token.expiresAt}/>)</span>
|
||||
);
|
||||
}
|
||||
|
||||
render () {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// @flow
|
||||
import type {Request} from '../../../../models/request';
|
||||
import {newBodyRaw} from '../../../../models/request';
|
||||
|
||||
import React from 'react';
|
||||
import autobind from 'autobind-decorator';
|
||||
import {parse, print} from 'graphql';
|
||||
@@ -18,6 +17,7 @@ import type {Workspace} from '../../../../models/workspace';
|
||||
import type {Settings} from '../../../../models/settings';
|
||||
import type {RenderedRequest} from '../../../../common/render';
|
||||
import {getRenderedRequest} from '../../../../common/render';
|
||||
import TimeFromNow from '../../time-from-now';
|
||||
|
||||
type GraphQLBody = {
|
||||
query: string,
|
||||
@@ -50,6 +50,8 @@ class GraphQLEditor extends React.PureComponent {
|
||||
body: GraphQLBody,
|
||||
schema: Object | null,
|
||||
schemaFetchError: string,
|
||||
schemaLastFetchTime: number,
|
||||
schemaIsFetching: boolean,
|
||||
hideSchemaFetchErrors: boolean,
|
||||
variablesSyntaxError: string,
|
||||
forceRefreshKey: number
|
||||
@@ -63,6 +65,8 @@ class GraphQLEditor extends React.PureComponent {
|
||||
body: this._stringToGraphQL(props.content),
|
||||
schema: null,
|
||||
schemaFetchError: '',
|
||||
schemaLastFetchTime: 0,
|
||||
schemaIsFetching: false,
|
||||
hideSchemaFetchErrors: false,
|
||||
variablesSyntaxError: '',
|
||||
forceRefreshKey: 0
|
||||
@@ -74,9 +78,16 @@ class GraphQLEditor extends React.PureComponent {
|
||||
}
|
||||
|
||||
async _fetchAndSetSchema (rawRequest: Request) {
|
||||
this.setState({schemaIsFetching: true});
|
||||
|
||||
const {workspace, settings, environmentId} = this.props;
|
||||
const request: RenderedRequest = await getRenderedRequest(rawRequest, environmentId);
|
||||
const newState = {schema: this.state.schema, schemaFetchError: ''};
|
||||
const newState = {
|
||||
schema: this.state.schema,
|
||||
schemaFetchError: '',
|
||||
schemaLastFetchTime: this.state.schemaLastFetchTime,
|
||||
schemaIsFetching: false
|
||||
};
|
||||
|
||||
try {
|
||||
// TODO: Use Insomnia's network stack to handle things like authentication
|
||||
@@ -107,6 +118,7 @@ class GraphQLEditor extends React.PureComponent {
|
||||
const {data} = JSON.parse(bodyBuffer.toString());
|
||||
const schema = buildClientSchema(data);
|
||||
newState.schema = schema;
|
||||
newState.schemaLastFetchTime = Date.now();
|
||||
} else {
|
||||
newState.schemaFetchError = 'No response body received when fetching schema';
|
||||
}
|
||||
@@ -124,7 +136,7 @@ class GraphQLEditor extends React.PureComponent {
|
||||
const {body, forceRefreshKey} = this.state;
|
||||
const {variables, query} = body;
|
||||
const prettyQuery = query && print(parse(query));
|
||||
const prettyVariables = variables && prettifyJson(JSON.stringify(variables));
|
||||
const prettyVariables = variables && JSON.parse(prettifyJson(JSON.stringify(variables)));
|
||||
this._handleBodyChange(prettyQuery, prettyVariables);
|
||||
setTimeout(() => {
|
||||
this.setState({forceRefreshKey: forceRefreshKey + 1});
|
||||
@@ -191,6 +203,24 @@ class GraphQLEditor extends React.PureComponent {
|
||||
this._isMounted = false;
|
||||
}
|
||||
|
||||
renderSchemaFetchMessage () {
|
||||
let message;
|
||||
const {schemaLastFetchTime, schemaIsFetching} = this.state;
|
||||
if (schemaIsFetching) {
|
||||
message = 'Fetching schema...';
|
||||
} else if (schemaLastFetchTime > 0) {
|
||||
message = <span>schema last fetched <TimeFromNow timestamp={schemaLastFetchTime}/></span>;
|
||||
} else {
|
||||
message = 'schema not yet fetched';
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="txt-sm super-faint italic pad-sm">
|
||||
{message}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render () {
|
||||
const {
|
||||
content,
|
||||
@@ -250,6 +280,9 @@ class GraphQLEditor extends React.PureComponent {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="graphql-editor__schema-notice">
|
||||
{this.renderSchemaFetchMessage()}
|
||||
</div>
|
||||
<h2 className="no-margin pad-left-sm pad-top-sm pad-bottom-sm">
|
||||
Query Variables <HelpTooltip>Variables to use in GraphQL query <br/>(JSON
|
||||
format)</HelpTooltip>
|
||||
|
||||
47
app/ui/components/time-from-now.js
Normal file
47
app/ui/components/time-from-now.js
Normal file
@@ -0,0 +1,47 @@
|
||||
// @flow
|
||||
import React from 'react';
|
||||
import autobind from 'autobind-decorator';
|
||||
import moment from 'moment';
|
||||
|
||||
@autobind
|
||||
class TimeFromNow extends React.PureComponent {
|
||||
props: {
|
||||
timestamp: number
|
||||
};
|
||||
|
||||
state: {
|
||||
text: string
|
||||
};
|
||||
|
||||
_interval: any;
|
||||
|
||||
constructor (props: any) {
|
||||
super(props);
|
||||
this._interval = null;
|
||||
this.state = {
|
||||
text: ''
|
||||
};
|
||||
}
|
||||
|
||||
_update () {
|
||||
const {timestamp} = this.props;
|
||||
this.setState({text: moment(timestamp).fromNow()});
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this._interval = setInterval(this._update, 5000);
|
||||
this._update();
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
clearInterval(this._interval);
|
||||
}
|
||||
|
||||
render () {
|
||||
return <span title={moment(this.props.timestamp).toString()}>
|
||||
{this.state.text}
|
||||
</span>;
|
||||
}
|
||||
}
|
||||
|
||||
export default TimeFromNow;
|
||||
@@ -3,7 +3,12 @@
|
||||
.graphql-editor {
|
||||
display: grid;
|
||||
height: 100%;
|
||||
grid-template-rows: minmax(0, auto) min-content min-content minmax(0, min-content) min-content;
|
||||
grid-template-rows: minmax(0, auto)
|
||||
min-content
|
||||
min-content
|
||||
min-content
|
||||
minmax(0, min-content)
|
||||
min-content;
|
||||
|
||||
& > h2 {
|
||||
color: var(--hl);
|
||||
|
||||
Reference in New Issue
Block a user