diff --git a/app/ui/components/editors/auth/o-auth-2-auth.js b/app/ui/components/editors/auth/o-auth-2-auth.js
index 106dbbbaee..961093d017 100644
--- a/app/ui/components/editors/auth/o-auth-2-auth.js
+++ b/app/ui/components/editors/auth/o-auth-2-auth.js
@@ -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 (expires {str});
+ return (
+ (expires )
+ );
}
render () {
diff --git a/app/ui/components/editors/body/graph-ql-editor.js b/app/ui/components/editors/body/graph-ql-editor.js
index 02fd895698..5a121b3f5b 100644
--- a/app/ui/components/editors/body/graph-ql-editor.js
+++ b/app/ui/components/editors/body/graph-ql-editor.js
@@ -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 = schema last fetched ;
+ } else {
+ message = 'schema not yet fetched';
+ }
+
+ return (
+
+ {message}
+
+ );
+ }
+
render () {
const {
content,
@@ -250,6 +280,9 @@ class GraphQLEditor extends React.PureComponent {
)}
+
+ {this.renderSchemaFetchMessage()}
+
Query Variables Variables to use in GraphQL query
(JSON
format)
diff --git a/app/ui/components/time-from-now.js b/app/ui/components/time-from-now.js
new file mode 100644
index 0000000000..d736984d21
--- /dev/null
+++ b/app/ui/components/time-from-now.js
@@ -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
+ {this.state.text}
+ ;
+ }
+}
+
+export default TimeFromNow;
diff --git a/app/ui/css/components/graph-ql-editor.less b/app/ui/css/components/graph-ql-editor.less
index 1e35aefa34..d3f61acf55 100644
--- a/app/ui/css/components/graph-ql-editor.less
+++ b/app/ui/css/components/graph-ql-editor.less
@@ -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);