plugins/graphiql: separate GraphiQLBrowser component and load endpoints from api
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import mockFetch from 'jest-fetch-mock';
|
||||
import { GraphiQLPage } from './GraphiQLPage';
|
||||
import { ThemeProvider } from '@material-ui/core';
|
||||
import { lightTheme } from '@backstage/theme';
|
||||
|
||||
jest.mock('graphiql', () => () => '<GraphiQL />');
|
||||
|
||||
describe('GraphiQLPage', () => {
|
||||
it('should render', () => {
|
||||
mockFetch.mockResponse(() => new Promise(() => {}));
|
||||
const rendered = render(
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<GraphiQLPage />
|
||||
</ThemeProvider>,
|
||||
);
|
||||
expect(rendered.getByText('GraphiQL')).toBeInTheDocument();
|
||||
expect(rendered.getByText('<GraphiQL />')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { FC, useState } from 'react';
|
||||
import { Tabs, Tab, makeStyles, Typography } from '@material-ui/core';
|
||||
import 'graphiql/graphiql.css';
|
||||
import GraphiQL from 'graphiql';
|
||||
import { StorageBucket } from 'lib/storage';
|
||||
import { GraphQLEndpoint } from 'lib/api';
|
||||
|
||||
const useStyles = makeStyles({
|
||||
root: {
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexFlow: 'column nowrap',
|
||||
},
|
||||
graphiQlWrapper: {
|
||||
flex: 1,
|
||||
'@global': {
|
||||
'.graphiql-container': {
|
||||
boxSizing: 'initial',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
type GraphiQLBrowserProps = {
|
||||
endpoints: GraphQLEndpoint[];
|
||||
};
|
||||
|
||||
export const GraphiQLBrowser: FC<GraphiQLBrowserProps> = ({ endpoints }) => {
|
||||
const classes = useStyles();
|
||||
const [tabIndex, setTabIndex] = useState(0);
|
||||
|
||||
if (!endpoints.length) {
|
||||
return <Typography variant="h4">No endpoints available</Typography>;
|
||||
}
|
||||
|
||||
const { id, fetcher } = endpoints[tabIndex];
|
||||
const storage = StorageBucket.forLocalStorage(`plugin/graphiql/data/${id}`);
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<Tabs
|
||||
value={tabIndex}
|
||||
onChange={(_, value) => setTabIndex(value)}
|
||||
indicatorColor="primary"
|
||||
>
|
||||
{endpoints.map(({ title }, index) => (
|
||||
<Tab key={index} label={title} value={index} />
|
||||
))}
|
||||
</Tabs>
|
||||
<div className={classes.graphiQlWrapper}>
|
||||
<GraphiQL key={tabIndex} fetcher={fetcher} storage={storage} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './GraphiQLBrowser';
|
||||
@@ -14,56 +14,51 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { FC, useState } from 'react';
|
||||
import { Tabs, Tab, makeStyles } from '@material-ui/core';
|
||||
import { Page, pageTheme, Content, Header, HeaderLabel } from '@backstage/core';
|
||||
import React, { FC } from 'react';
|
||||
import {
|
||||
Content,
|
||||
Header,
|
||||
HeaderLabel,
|
||||
Page,
|
||||
Progress,
|
||||
pageTheme,
|
||||
useApi,
|
||||
} from '@backstage/core';
|
||||
import { useAsync } from 'react-use';
|
||||
import 'graphiql/graphiql.css';
|
||||
import GraphiQL from 'graphiql';
|
||||
import { StorageBucket } from 'lib/storage';
|
||||
|
||||
const tabs = [
|
||||
{
|
||||
id: 'gitlab',
|
||||
title: 'GitLab',
|
||||
fetcher: async (params: any) => {
|
||||
const res = await fetch('https://gitlab.com/api/graphql', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(params),
|
||||
});
|
||||
return res.json();
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'countries',
|
||||
title: 'Countries',
|
||||
fetcher: async (params: any) => {
|
||||
const res = await fetch('https://countries.trevorblades.com/', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(params),
|
||||
});
|
||||
return res.json();
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const useStyles = makeStyles({
|
||||
root: {
|
||||
'@global': {
|
||||
'.graphiql-container': {
|
||||
boxSizing: 'initial',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
import { graphQlBrowseApiRef } from 'lib/api';
|
||||
import { GraphiQLBrowser } from 'components';
|
||||
import { Typography } from '@material-ui/core';
|
||||
|
||||
export const GraphiQLPage: FC<{}> = () => {
|
||||
const classes = useStyles();
|
||||
const [tabIndex, setTabIndex] = useState(0);
|
||||
const graphQlBrowseApi = useApi(graphQlBrowseApiRef);
|
||||
const endpoints = useAsync(() => graphQlBrowseApi.getEndpoints());
|
||||
|
||||
const { id, fetcher } = tabs[tabIndex];
|
||||
const storage = StorageBucket.forLocalStorage(`plugin/graphiql/data/${id}`);
|
||||
let content: JSX.Element;
|
||||
|
||||
if (endpoints.loading) {
|
||||
content = (
|
||||
<Content>
|
||||
<Progress />
|
||||
</Content>
|
||||
);
|
||||
} else if (endpoints.error) {
|
||||
content = (
|
||||
<Content>
|
||||
<Typography variant="h4" color="error">
|
||||
Failed to load GraphQL endpoints, {endpoints.error}
|
||||
<br />
|
||||
We also need a proper error component
|
||||
</Typography>
|
||||
</Content>
|
||||
);
|
||||
} else {
|
||||
content = (
|
||||
<Content noPadding>
|
||||
<GraphiQLBrowser endpoints={endpoints.value!} />
|
||||
</Content>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Page theme={pageTheme.tool}>
|
||||
@@ -71,14 +66,7 @@ export const GraphiQLPage: FC<{}> = () => {
|
||||
<HeaderLabel label="Owner" value="Spotify" />
|
||||
<HeaderLabel label="Lifecycle" value="Alpha" />
|
||||
</Header>
|
||||
<Content noPadding className={classes.root}>
|
||||
<Tabs value={tabIndex} onChange={(_, value) => setTabIndex(value)}>
|
||||
{tabs.map(({ title }, index) => (
|
||||
<Tab key={index} label={title} value={index} />
|
||||
))}
|
||||
</Tabs>
|
||||
<GraphiQL key={tabIndex} fetcher={fetcher} storage={storage} />
|
||||
</Content>
|
||||
{content}
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -15,3 +15,4 @@
|
||||
*/
|
||||
|
||||
export * from './GraphiQLPage';
|
||||
export * from './GraphiQLBrowser';
|
||||
|
||||
@@ -15,3 +15,4 @@
|
||||
*/
|
||||
|
||||
export { plugin } from './plugin';
|
||||
export * from './lib/api';
|
||||
|
||||
Reference in New Issue
Block a user