console: use requestAction instead of fetch (#5406)

This commit is contained in:
soorajshankar 2020-07-20 21:18:59 +05:30 committed by GitHub
parent d8481c3a1c
commit 4a116c793b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 192 additions and 174 deletions

View File

@ -11,7 +11,7 @@ type DropDownButtonProps = {
}[];
dataKey: string;
dataIndex?: string;
onButtonChange: (e: React.MouseEvent) => void;
onButtonChange: (e: React.MouseEvent<{}>) => void;
onInputChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
value?: string;
inputVal: string;

View File

@ -5,6 +5,8 @@ import {
} from 'graphql';
import React from 'react';
import endpoints from '../../../Endpoints';
import { Dispatch } from '../../../types';
import requestAction from '../../../utils/requestAction';
export const getGraphQLQueryPayload = (
query: string,
@ -14,7 +16,7 @@ export const getGraphQLQueryPayload = (
variables,
});
export const useIntrospectionSchema = (headers = {}) => {
export const useIntrospectionSchema = (headers = {}, dispatch: Dispatch) => {
const [schema, setSchema] = React.useState<GraphQLSchema | null>(null);
const [loading, setLoading] = React.useState(true);
const [error, setError] = React.useState(null);
@ -22,12 +24,22 @@ export const useIntrospectionSchema = (headers = {}) => {
const introspect = () => {
setLoading(true);
fetch(endpoints.graphQLUrl, {
dispatch(
requestAction(
endpoints.graphQLUrl,
{
method: 'POST',
headers,
body: JSON.stringify(getGraphQLQueryPayload(getIntrospectionQuery(), {})),
})
.then(r => r.json())
body: JSON.stringify(
getGraphQLQueryPayload(getIntrospectionQuery(), {})
),
},
undefined,
undefined,
true,
true
)
)
.then(response => {
if (response.data) {
setSchema(buildClientSchema(response.data));
@ -45,7 +57,7 @@ export const useIntrospectionSchema = (headers = {}) => {
return () => setSchema(null);
};
React.useEffect(introspect, []);
React.useEffect(introspect, [dispatch, headers]);
return {
schema,

View File

@ -13,6 +13,7 @@ const CodeTabs = ({
currentAction,
parentMutation,
shouldDerive,
dispatch,
}) => {
const [loading, setLoading] = React.useState(true);
const [error, setError] = React.useState(null);
@ -25,7 +26,8 @@ const CodeTabs = ({
framework,
currentAction.action_name,
actionsSdl,
shouldDerive ? parentMutation : null
shouldDerive ? parentMutation : null,
dispatch
)
.then(codeFiles => {
setCodegenFiles(codeFiles);

View File

@ -14,7 +14,7 @@ import { Icon } from '../../../UIKit/atoms';
import CodeTabs from './CodeTabs';
import DerivedFrom from './DerivedFrom';
const Codegen = ({ allActions, allTypes, currentAction }) => {
const Codegen = ({ dispatch, allActions, allTypes, currentAction }) => {
const [allFrameworks, setAllFrameworks] = React.useState([]);
const [selectedFramework, selectFramework] = React.useState('');
const [loading, setLoading] = React.useState(true);
@ -33,7 +33,7 @@ const Codegen = ({ allActions, allTypes, currentAction }) => {
const init = () => {
setLoading(true);
setError(null);
getAllCodegenFrameworks()
getAllCodegenFrameworks(dispatch)
.then(frameworks => {
setAllFrameworks(frameworks);
selectFramework(frameworks[0].name);
@ -188,6 +188,7 @@ const Codegen = ({ allActions, allTypes, currentAction }) => {
currentAction={currentAction}
shouldDerive={shouldDerive}
parentMutation={parentMutation}
dispatch={dispatch}
/>
</div>
<hr />

View File

@ -19,6 +19,8 @@ const {
} = require('graphql');
const { camelize } = require('inflection');
import { getPersistedDerivedAction } from '../lsUtils';
import requestAction from '../../../../utils/requestAction';
import requestActionPlain from '../../../../utils/requestActionPlain';
export const getCodegenFilePath = framework => {
return `${BASE_CODEGEN_PATH}/${framework}/actions-codegen.js`;
@ -37,18 +39,12 @@ export const getGlitchProjectURL = () => {
export const GLITCH_PROJECT_URL = '';
export const getAllCodegenFrameworks = () => {
return fetch(ALL_FRAMEWORKS_FILE_PATH)
.then(r => r.json())
.catch(e => {
console.error('could not fetch the latest codegen file');
throw e;
});
export const getAllCodegenFrameworks = dispatch => {
return dispatch(requestAction(ALL_FRAMEWORKS_FILE_PATH, {}));
};
export const getCodegenFunc = framework => {
return fetch(getCodegenFilePath(framework))
.then(r => r.text())
export const getCodegenFunc = (framework, dispatch) => {
return dispatch(requestActionPlain(getCodegenFilePath(framework)))
.then(rawJsString => {
const { codegen } = require('@graphql-codegen/core');
const typescriptPlugin = require('@graphql-codegen/typescript');
@ -65,9 +61,10 @@ export const getFrameworkCodegen = (
framework,
actionName,
actionsSdl,
parentOperation
parentOperation,
dispatch
) => {
return getCodegenFunc(framework)
return getCodegenFunc(framework, dispatch)
.then(codegenerator => {
const derive = {
operation: parentOperation,

View File

@ -7,12 +7,13 @@ import Tooltip from './Tooltip';
import styles from './Styles.scss';
import { useIntrospectionSchema } from '../../../../Common/utils/graphqlUtils';
const CloneType = ({ headers, toggleModal, handleClonedTypes }) => {
const CloneType = ({ headers, toggleModal, handleClonedTypes, dispatch }) => {
const [prefix, setPrefix] = React.useState('_');
const prefixOnChange = e => setPrefix(e.target.value);
const { schema, loading, error, introspect } = useIntrospectionSchema(
headers
headers,
dispatch
);
if (loading) return <Spinner />;

View File

@ -12,6 +12,7 @@ import { execute } from 'apollo-link';
import { getHeadersAsJSON, getGraphQLEndpoint } from './utils';
import { saveAppState, clearState } from '../../AppState.js';
import { ADMIN_SECRET_HEADER_KEY } from '../../../constants';
import requestActionPlain from '../../../utils/requestActionPlain';
const CHANGE_TAB = 'ApiExplorer/CHANGE_TAB';
const CHANGE_API_SELECTION = 'ApiExplorer/CHANGE_API_SELECTION';
@ -214,20 +215,22 @@ const isSubscription = graphQlParams => {
return false;
};
const graphQLFetcherFinal = (graphQLParams, url, headers) => {
const graphQLFetcherFinal = (graphQLParams, url, headers, dispatch) => {
if (isSubscription(graphQLParams)) {
return graphqlSubscriber(graphQLParams, url, headers);
}
return fetch(url, {
return dispatch(
requestAction(url, {
method: 'POST',
headers: getHeadersAsJSON(headers),
body: JSON.stringify(graphQLParams),
}).then(response => response.json());
})
);
};
/* Analyse Fetcher */
const analyzeFetcher = (headers, mode) => {
return query => {
return (query, dispatch) => {
const editedQuery = {
query,
is_relay: mode === 'relay',
@ -255,12 +258,14 @@ const analyzeFetcher = (headers, mode) => {
editedQuery.user = user;
return fetch(`${Endpoints.graphQLUrl}/explain`, {
return dispatch(
requestAction(`${Endpoints.graphQLUrl}/explain`, {
method: 'post',
headers: reqHeaders,
body: JSON.stringify(editedQuery),
credentials: 'include',
});
})
);
};
};
/* End of it */
@ -436,9 +441,9 @@ const getStateAfterClearingHistory = state => {
};
};
const getRemoteQueries = (queryUrl, cb) => {
fetch(queryUrl)
.then(resp => resp.text().then(cb))
const getRemoteQueries = (queryUrl, cb, dispatch) => {
dispatch(requestActionPlain(queryUrl))
.then(cb)
.catch(e => console.error('Invalid query file URL: ', e));
};

View File

@ -6,7 +6,7 @@ import { print, parse } from 'graphql';
import { isValidGraphQLOperation } from '../utils';
import { getGraphQLQueryPayload } from '../../../Common/utils/graphqlUtils';
export default class AnalyseButton extends React.Component {
export default class AnalyzeButton extends React.Component {
constructor(props) {
super(props);
// Ensure props are correct
@ -71,6 +71,7 @@ export default class AnalyseButton extends React.Component {
mode={mode}
analyseQuery={this.state.analyseQuery}
clearAnalyse={this.clearAnalyse.bind(this)}
dispatch={this.props.dispatch}
{...this.props}
/>
)}
@ -172,7 +173,7 @@ export default class AnalyseButton extends React.Component {
};
}
AnalyseButton.propTypes = {
AnalyzeButton.propTypes = {
operations: PropTypes.array,
query: PropTypes.string,
variables: PropTypes.string,

View File

@ -14,14 +14,9 @@ export default class QueryAnalyser extends React.Component {
}
componentDidMount() {
const { dispatch, analyseQuery } = this.props;
this.props
.analyzeFetcher(this.props.analyseQuery.query)
.then(r => {
if (r.ok) {
return r.json();
}
return r.text().then(rText => Promise.reject(new Error(rText)));
})
.analyzeFetcher(analyseQuery.query, dispatch)
.then(data => {
this.setState({
analyseData: Array.isArray(data) ? data : [data],

View File

@ -93,7 +93,8 @@ class GraphiQLWrapper extends Component {
return graphQLFetcherFinal(
graphQLParams,
getGraphQLEndpoint(mode),
graphqlNetworkData.headers
graphqlNetworkData.headers,
dispatch
);
};
@ -235,6 +236,7 @@ class GraphiQLWrapper extends Component {
<AnalyzeButton
operations={graphiqlContext && graphiqlContext.state.operations}
analyzeFetcher={analyzeFetcherInstance}
dispatch={dispatch}
{...analyzerProps}
/>
</GraphiQL.Toolbar>

View File

@ -18,6 +18,7 @@ import { getHeadersAsJSON } from '../utils';
import '../GraphiQLWrapper/GraphiQL.css';
import './OneGraphExplorer.css';
import { showErrorNotification } from '../../Common/Notification';
import requestAction from '../../../../utils/requestAction';
class OneGraphExplorer extends React.Component {
state = {
@ -53,13 +54,15 @@ class OneGraphExplorer extends React.Component {
}
setPersistedQuery() {
const { urlParams, numberOfTables } = this.props;
const { urlParams, numberOfTables, dispatch } = this.props;
const queryFile = urlParams ? urlParams.query_file : null;
if (queryFile) {
getRemoteQueries(queryFile, remoteQuery =>
this.setState({ query: remoteQuery })
getRemoteQueries(
queryFile,
remoteQuery => this.setState({ query: remoteQuery }),
dispatch
);
} else if (numberOfTables === 0) {
const NO_TABLES_MESSAGE = `# Looks like you do not have any tables.
@ -96,14 +99,15 @@ class OneGraphExplorer extends React.Component {
const headers = JSON.parse(JSON.stringify(headers_));
dispatch(setLoading(true));
this.setState({ schema: null });
fetch(endpoint, {
dispatch(
requestAction(endpoint, {
method: 'POST',
headers: getHeadersAsJSON(headers || []),
body: JSON.stringify({
query: getIntrospectionQuery(),
}),
})
.then(response => response.json())
)
.then(result => {
if (result.errors && result.errors.length > 0) {
const errorMessage = result.errors[0].message;
@ -191,19 +195,6 @@ class OneGraphExplorer extends React.Component {
const { renderGraphiql } = this.props;
const explorer = (
<GraphiQLExplorer
schema={schema}
query={query}
onEdit={this.editQuery}
explorerIsOpen={explorerOpen}
onToggleExplorer={this.handleToggle}
getDefaultScalarArgValue={getDefaultScalarArgValue}
makeDefaultArg={makeDefaultArg}
width={explorerWidth}
/>
);
let explorerSeparator;
if (explorerOpen) {
explorerSeparator = (
@ -230,7 +221,16 @@ class OneGraphExplorer extends React.Component {
onMouseUp={this.handleExplorerResizeStop}
>
<div className="gqlexplorer">
{explorer}
<GraphiQLExplorer
schema={schema}
query={query}
onEdit={this.editQuery}
explorerIsOpen={explorerOpen}
onToggleExplorer={this.handleToggle}
getDefaultScalarArgValue={getDefaultScalarArgValue}
makeDefaultArg={makeDefaultArg}
width={explorerWidth}
/>
{explorerSeparator}
</div>
{graphiql}

View File

@ -17,6 +17,7 @@ import { getStatementTimeoutSql, parseCreateSQL } from './utils';
import dataHeaders from '../Common/Headers';
import returnMigrateUrl from '../Common/getMigrateUrl';
import { getRunSqlQuery } from '../../../Common/utils/v1QueryUtils';
import requestAction from '../../../../utils/requestAction';
const MAKING_REQUEST = 'RawSQL/MAKING_REQUEST';
const SET_SQL = 'RawSQL/SET_SQL';
@ -97,10 +98,9 @@ const executeSQL = (isMigration, migrationName, statementTimeout) => (
headers: dataHeaders(getState),
body: JSON.stringify(requestBody),
};
fetch(url, options).then(
response => {
if (response.ok) {
response.json().then(
return dispatch(requestAction(url, options))
.then(
data => {
if (isMigration) {
dispatch(loadMigrationStatus());
@ -128,11 +128,8 @@ const executeSQL = (isMigration, migrationName, statementTimeout) => (
});
console.err('RunSQL error: ', err);
}
);
return;
}
response.json().then(
errorMsg => {
)
.catch(errorMsg => {
const title = 'SQL Execution Failed';
dispatch({ type: UPDATE_MIGRATION_STATUS_ERROR, data: errorMsg });
dispatch({ type: REQUEST_ERROR, data: errorMsg });
@ -141,32 +138,7 @@ const executeSQL = (isMigration, migrationName, statementTimeout) => (
} else {
dispatch(showErrorNotification(title, errorMsg.code, errorMsg));
}
},
() => {
dispatch(
showErrorNotification(
'SQL execution failed!',
'Something is wrong. Please check your configuration again'
)
);
dispatch({
type: REQUEST_ERROR,
data: 'Something is wrong. Please check your configuration again',
});
}
);
},
error => {
console.error(error);
dispatch(
showErrorNotification(
'SQL execution failed',
'Cannot connect to server'
)
);
dispatch({ type: REQUEST_ERROR, data: 'server-connection-failed' });
}
);
};
const rawSQLReducer = (state = defaultState, action) => {

View File

@ -1,4 +1,5 @@
import React from 'react';
import { ThunkAction } from 'redux-thunk';
import globals from '../../../../../../Globals';
import { useIntrospectionSchemaRemote } from '../../../../RemoteSchema/graphqlUtils';
import {
@ -12,6 +13,7 @@ import { LoadingSkeleton, NoRemoteSchemaPlaceholder } from './PlaceHolder';
import ArgElement from './ArgElement';
import FieldElement from './FieldElement';
import styles from '../SchemaExplorer.scss';
import { ReduxState, ReduxAction } from '../../../../../../types';
type Props = {
relationship: RemoteRelationship;
@ -21,6 +23,7 @@ type Props = {
handleArgValueChange: (a: TreeArgElement, value: string) => void;
remoteSchemaName: string;
columns: string[];
reduxDispatch: ThunkAction<void, ReduxState, unknown, ReduxAction>;
};
const Explorer: React.FC<Props> = ({
@ -31,12 +34,14 @@ const Explorer: React.FC<Props> = ({
handleArgValueKindChange,
remoteSchemaName,
columns,
reduxDispatch,
}) => {
const { loading, error, schema, introspect } = useIntrospectionSchemaRemote(
remoteSchemaName,
{
'x-hasura-admin-secret': globals.adminSecret,
}
},
reduxDispatch
);
if (!remoteSchemaName) {

View File

@ -1,4 +1,5 @@
import React from 'react';
import { ThunkAction } from 'redux-thunk';
import {
RemoteRelationship,
TreeArgElement,
@ -23,6 +24,7 @@ import {
} from '../Tooltips';
import Explorer from './Explorer';
import { Table } from '../../../../../Common/utils/pgUtils';
import { ReduxState, ReduxAction } from '../../../../../../types';
type Props = {
table: Table;
@ -30,6 +32,7 @@ type Props = {
isLast: boolean;
state: RemoteRelationship;
dispatch: React.Dispatch<RemoteRelAction>;
reduxDispatch: ThunkAction<void, ReduxState, unknown, ReduxAction>;
};
const RemoteRelEditor: React.FC<Props> = ({
@ -38,6 +41,7 @@ const RemoteRelEditor: React.FC<Props> = ({
remoteSchemas,
state,
dispatch,
reduxDispatch,
}) => {
const handleNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
e.persist();
@ -149,6 +153,7 @@ const RemoteRelEditor: React.FC<Props> = ({
handleArgValueChange={handleArgValueChange}
remoteSchemaName={state.remoteSchema}
columns={tableColumns}
reduxDispatch={reduxDispatch}
/>
</div>
</div>

View File

@ -32,6 +32,7 @@ const EditorWrapper: React.FC<Props> = ({
isLast={isLast}
state={state}
dispatch={dispatch}
reduxDispatch={reduxDispatch}
/>
);

View File

@ -2,6 +2,7 @@ import { useEffect, useState } from 'react';
import endpoints from '../../../Endpoints';
import { getRemoteSchemaIntrospectionQuery } from '../../Common/utils/v1QueryUtils';
import { buildClientSchema, isWrappingType, isObjectType } from 'graphql';
import requestAction from '../../../utils/requestAction';
// local cache where introspection schema is cached
let introspectionSchemaCache = {};
@ -14,7 +15,11 @@ export const clearIntrospectionSchemaCache = remoteSchemaName => {
};
// custom hook for introspecting remote schema
export const useIntrospectionSchemaRemote = (remoteSchemaName, headers) => {
export const useIntrospectionSchemaRemote = (
remoteSchemaName,
headers,
dispatch
) => {
const [schema, setSchema] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
@ -33,14 +38,24 @@ export const useIntrospectionSchemaRemote = (remoteSchemaName, headers) => {
// perform introspection
setLoading(true);
setError(null);
fetch(endpoints.query, {
dispatch(
requestAction(
endpoints.query,
{
method: 'POST',
headers: {
...headers,
},
body: JSON.stringify(getRemoteSchemaIntrospectionQuery(remoteSchemaName)),
})
.then(r => r.json())
body: JSON.stringify(
getRemoteSchemaIntrospectionQuery(remoteSchemaName)
),
},
undefined,
undefined,
true,
true
)
)
.then(response => {
const clientSchema = buildClientSchema(response.data);
setSchema(clientSchema);
@ -54,7 +69,7 @@ export const useIntrospectionSchemaRemote = (remoteSchemaName, headers) => {
});
};
useEffect(introspectSchema, [remoteSchemaName]);
useEffect(introspectSchema, [remoteSchemaName, dispatch, headers]);
return {
schema,

View File

@ -1,20 +1,28 @@
import React, { Component } from 'react';
import { Connect } from 'react-redux';
import { GraphQLVoyager } from 'graphql-voyager';
import fetch from 'isomorphic-fetch';
import Endpoints from '../../../Endpoints';
import '../../../../node_modules/graphql-voyager/dist/voyager.css';
import './voyagerView.css';
import requestAction from '../../../utils/requestAction';
import { Dispatch } from '../../../types';
interface VoyagerViewProps {
headers: Headers;
}
interface StateProps {
headers: Headers;
}
const mapStateToProps = (state: State) => {
return {
headers: state.tables.dataHeaders,
};
};
const mapDispatchToProps = (dispatch: Dispatch) => {
return {
requestAction: (url: string, options: RequestInit) =>
dispatch(requestAction(url, options)),
};
};
// TODO: replace by redux State when it's defined
interface State {
tables: {
@ -22,16 +30,17 @@ interface State {
};
}
type Props = VoyagerViewProps & StateProps;
type Props = VoyagerViewProps &
ReturnType<typeof mapStateToProps> &
ReturnType<typeof mapDispatchToProps>;
class VoyagerView extends Component<Props, State> {
introspectionProvider = (query: string) => {
return fetch(Endpoints.graphQLUrl, {
introspectionProvider = (query: string) =>
this.props.requestAction(Endpoints.graphQLUrl, {
method: 'POST',
headers: this.props.headers,
body: JSON.stringify({ query }),
}).then(response => response.json());
};
});
render() {
return (
@ -44,12 +53,7 @@ class VoyagerView extends Component<Props, State> {
}
const generatedVoyagerConnector = (connect: Connect) => {
const mapStateToProps = (state: State) => {
return {
headers: state.tables.dataHeaders,
};
};
return connect(mapStateToProps)(VoyagerView);
return connect(mapStateToProps, mapDispatchToProps)(VoyagerView);
};
export default generatedVoyagerConnector;

View File

@ -14,7 +14,7 @@ import { globalCookiePolicy } from '../Endpoints';
const requestAction = (
url: string,
options: RequestInit,
options: RequestInit = {},
SUCCESS?: string,
ERROR?: string,
includeCredentials = true,