mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-15 09:22:43 +03:00
console: use requestAction instead of fetch (#5406)
This commit is contained in:
parent
d8481c3a1c
commit
4a116c793b
@ -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;
|
||||
|
@ -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, {
|
||||
method: 'POST',
|
||||
headers,
|
||||
body: JSON.stringify(getGraphQLQueryPayload(getIntrospectionQuery(), {})),
|
||||
})
|
||||
.then(r => r.json())
|
||||
dispatch(
|
||||
requestAction(
|
||||
endpoints.graphQLUrl,
|
||||
{
|
||||
method: 'POST',
|
||||
headers,
|
||||
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,
|
||||
|
@ -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);
|
||||
|
@ -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 />
|
||||
|
@ -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,
|
||||
|
@ -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 />;
|
||||
|
@ -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, {
|
||||
method: 'POST',
|
||||
headers: getHeadersAsJSON(headers),
|
||||
body: JSON.stringify(graphQLParams),
|
||||
}).then(response => response.json());
|
||||
return dispatch(
|
||||
requestAction(url, {
|
||||
method: 'POST',
|
||||
headers: getHeadersAsJSON(headers),
|
||||
body: JSON.stringify(graphQLParams),
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
/* 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`, {
|
||||
method: 'post',
|
||||
headers: reqHeaders,
|
||||
body: JSON.stringify(editedQuery),
|
||||
credentials: 'include',
|
||||
});
|
||||
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));
|
||||
};
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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],
|
||||
|
@ -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>
|
||||
|
@ -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, {
|
||||
method: 'POST',
|
||||
headers: getHeadersAsJSON(headers || []),
|
||||
body: JSON.stringify({
|
||||
query: getIntrospectionQuery(),
|
||||
}),
|
||||
})
|
||||
.then(response => response.json())
|
||||
dispatch(
|
||||
requestAction(endpoint, {
|
||||
method: 'POST',
|
||||
headers: getHeadersAsJSON(headers || []),
|
||||
body: JSON.stringify({
|
||||
query: getIntrospectionQuery(),
|
||||
}),
|
||||
})
|
||||
)
|
||||
.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}
|
||||
|
@ -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,76 +98,47 @@ const executeSQL = (isMigration, migrationName, statementTimeout) => (
|
||||
headers: dataHeaders(getState),
|
||||
body: JSON.stringify(requestBody),
|
||||
};
|
||||
fetch(url, options).then(
|
||||
response => {
|
||||
if (response.ok) {
|
||||
response.json().then(
|
||||
data => {
|
||||
if (isMigration) {
|
||||
dispatch(loadMigrationStatus());
|
||||
}
|
||||
dispatch(showSuccessNotification('SQL executed!'));
|
||||
dispatch(fetchDataInit()).then(() => {
|
||||
dispatch({ type: REQUEST_SUCCESS, data });
|
||||
});
|
||||
dispatch(fetchTrackedFunctions());
|
||||
},
|
||||
err => {
|
||||
const parsedErrorMsg = err;
|
||||
parsedErrorMsg.message = JSON.parse(err.message);
|
||||
dispatch({ type: UPDATE_MIGRATION_STATUS_ERROR, data: err });
|
||||
dispatch(
|
||||
showErrorNotification(
|
||||
'SQL execution failed!',
|
||||
'Something is wrong. Received an invalid response json.',
|
||||
parsedErrorMsg
|
||||
)
|
||||
);
|
||||
dispatch({
|
||||
type: REQUEST_ERROR,
|
||||
data: 'Something is wrong. Received an invalid response json.',
|
||||
});
|
||||
console.err('RunSQL error: ', err);
|
||||
}
|
||||
);
|
||||
return;
|
||||
}
|
||||
response.json().then(
|
||||
errorMsg => {
|
||||
const title = 'SQL Execution Failed';
|
||||
dispatch({ type: UPDATE_MIGRATION_STATUS_ERROR, data: errorMsg });
|
||||
dispatch({ type: REQUEST_ERROR, data: errorMsg });
|
||||
if (isMigration) {
|
||||
dispatch(handleMigrationErrors(title, errorMsg));
|
||||
} 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',
|
||||
});
|
||||
|
||||
return dispatch(requestAction(url, options))
|
||||
.then(
|
||||
data => {
|
||||
if (isMigration) {
|
||||
dispatch(loadMigrationStatus());
|
||||
}
|
||||
);
|
||||
},
|
||||
error => {
|
||||
console.error(error);
|
||||
dispatch(
|
||||
showErrorNotification(
|
||||
'SQL execution failed',
|
||||
'Cannot connect to server'
|
||||
)
|
||||
);
|
||||
dispatch({ type: REQUEST_ERROR, data: 'server-connection-failed' });
|
||||
}
|
||||
);
|
||||
dispatch(showSuccessNotification('SQL executed!'));
|
||||
dispatch(fetchDataInit()).then(() => {
|
||||
dispatch({ type: REQUEST_SUCCESS, data });
|
||||
});
|
||||
dispatch(fetchTrackedFunctions());
|
||||
},
|
||||
err => {
|
||||
const parsedErrorMsg = err;
|
||||
parsedErrorMsg.message = JSON.parse(err.message);
|
||||
dispatch({ type: UPDATE_MIGRATION_STATUS_ERROR, data: err });
|
||||
dispatch(
|
||||
showErrorNotification(
|
||||
'SQL execution failed!',
|
||||
'Something is wrong. Received an invalid response json.',
|
||||
parsedErrorMsg
|
||||
)
|
||||
);
|
||||
dispatch({
|
||||
type: REQUEST_ERROR,
|
||||
data: 'Something is wrong. Received an invalid response json.',
|
||||
});
|
||||
console.err('RunSQL error: ', err);
|
||||
}
|
||||
)
|
||||
.catch(errorMsg => {
|
||||
const title = 'SQL Execution Failed';
|
||||
dispatch({ type: UPDATE_MIGRATION_STATUS_ERROR, data: errorMsg });
|
||||
dispatch({ type: REQUEST_ERROR, data: errorMsg });
|
||||
if (isMigration) {
|
||||
dispatch(handleMigrationErrors(title, errorMsg));
|
||||
} else {
|
||||
dispatch(showErrorNotification(title, errorMsg.code, errorMsg));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const rawSQLReducer = (state = defaultState, action) => {
|
||||
|
@ -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) {
|
||||
|
@ -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>
|
||||
|
@ -32,6 +32,7 @@ const EditorWrapper: React.FC<Props> = ({
|
||||
isLast={isLast}
|
||||
state={state}
|
||||
dispatch={dispatch}
|
||||
reduxDispatch={reduxDispatch}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -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, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
...headers,
|
||||
},
|
||||
body: JSON.stringify(getRemoteSchemaIntrospectionQuery(remoteSchemaName)),
|
||||
})
|
||||
.then(r => r.json())
|
||||
dispatch(
|
||||
requestAction(
|
||||
endpoints.query,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
...headers,
|
||||
},
|
||||
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,
|
||||
|
@ -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;
|
||||
|
@ -14,7 +14,7 @@ import { globalCookiePolicy } from '../Endpoints';
|
||||
|
||||
const requestAction = (
|
||||
url: string,
|
||||
options: RequestInit,
|
||||
options: RequestInit = {},
|
||||
SUCCESS?: string,
|
||||
ERROR?: string,
|
||||
includeCredentials = true,
|
||||
|
Loading…
Reference in New Issue
Block a user