diff --git a/plugins/graphiql/src/components/GraphiQLBrowser/GraphiQLBrowser.test.tsx b/plugins/graphiql/src/components/GraphiQLBrowser/GraphiQLBrowser.test.tsx
new file mode 100644
index 0000000000..4dd18c326f
--- /dev/null
+++ b/plugins/graphiql/src/components/GraphiQLBrowser/GraphiQLBrowser.test.tsx
@@ -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', () => () => '');
+
+describe('GraphiQLPage', () => {
+ it('should render', () => {
+ mockFetch.mockResponse(() => new Promise(() => {}));
+ const rendered = render(
+
+
+ ,
+ );
+ expect(rendered.getByText('GraphiQL')).toBeInTheDocument();
+ expect(rendered.getByText('')).toBeInTheDocument();
+ });
+});
diff --git a/plugins/graphiql/src/components/GraphiQLBrowser/GraphiQLBrowser.tsx b/plugins/graphiql/src/components/GraphiQLBrowser/GraphiQLBrowser.tsx
new file mode 100644
index 0000000000..69ceec3136
--- /dev/null
+++ b/plugins/graphiql/src/components/GraphiQLBrowser/GraphiQLBrowser.tsx
@@ -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 = ({ endpoints }) => {
+ const classes = useStyles();
+ const [tabIndex, setTabIndex] = useState(0);
+
+ if (!endpoints.length) {
+ return No endpoints available;
+ }
+
+ const { id, fetcher } = endpoints[tabIndex];
+ const storage = StorageBucket.forLocalStorage(`plugin/graphiql/data/${id}`);
+
+ return (
+
+
setTabIndex(value)}
+ indicatorColor="primary"
+ >
+ {endpoints.map(({ title }, index) => (
+
+ ))}
+
+
+
+
+
+ );
+};
diff --git a/plugins/graphiql/src/components/GraphiQLBrowser/index.ts b/plugins/graphiql/src/components/GraphiQLBrowser/index.ts
new file mode 100644
index 0000000000..cb9a4a932f
--- /dev/null
+++ b/plugins/graphiql/src/components/GraphiQLBrowser/index.ts
@@ -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';
diff --git a/plugins/graphiql/src/components/GraphiQLPage/GraphiQLPage.tsx b/plugins/graphiql/src/components/GraphiQLPage/GraphiQLPage.tsx
index 76b17f545d..90a0bb92c0 100644
--- a/plugins/graphiql/src/components/GraphiQLPage/GraphiQLPage.tsx
+++ b/plugins/graphiql/src/components/GraphiQLPage/GraphiQLPage.tsx
@@ -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 = (
+
+
+
+ );
+ } else if (endpoints.error) {
+ content = (
+
+
+ Failed to load GraphQL endpoints, {endpoints.error}
+
+ We also need a proper error component
+
+
+ );
+ } else {
+ content = (
+
+
+
+ );
+ }
return (
@@ -71,14 +66,7 @@ export const GraphiQLPage: FC<{}> = () => {
-
- setTabIndex(value)}>
- {tabs.map(({ title }, index) => (
-
- ))}
-
-
-
+ {content}
);
};
diff --git a/plugins/graphiql/src/components/index.ts b/plugins/graphiql/src/components/index.ts
index ed11f03c40..c0d2228951 100644
--- a/plugins/graphiql/src/components/index.ts
+++ b/plugins/graphiql/src/components/index.ts
@@ -15,3 +15,4 @@
*/
export * from './GraphiQLPage';
+export * from './GraphiQLBrowser';
diff --git a/plugins/graphiql/src/index.ts b/plugins/graphiql/src/index.ts
index 3a0a0fe2d3..a1f5587fe1 100644
--- a/plugins/graphiql/src/index.ts
+++ b/plugins/graphiql/src/index.ts
@@ -15,3 +15,4 @@
*/
export { plugin } from './plugin';
+export * from './lib/api';