mirror of
https://github.com/usebruno/bruno.git
synced 2024-11-21 23:43:15 +01:00
feat: graphql docs explorer (#65)
This commit is contained in:
parent
dcdeb78995
commit
2393092248
@ -16,6 +16,7 @@
|
||||
"@tabler/icons": "^1.46.0",
|
||||
"@tippyjs/react": "^4.2.6",
|
||||
"@usebruno/schema": "0.2.0",
|
||||
"@usebruno/graphql-docs": "0.1.0",
|
||||
"axios": "^0.26.0",
|
||||
"classnames": "^2.3.1",
|
||||
"codemirror": "^5.65.2",
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import find from 'lodash/find';
|
||||
import get from 'lodash/get';
|
||||
import classnames from 'classnames';
|
||||
@ -13,7 +13,7 @@ import { sendRequest, saveRequest } from 'providers/ReduxStore/slices/collection
|
||||
import useGraphqlSchema from './useGraphqlSchema';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
|
||||
const GraphQLRequestPane = ({ item, collection, leftPaneWidth }) => {
|
||||
const GraphQLRequestPane = ({ item, collection, leftPaneWidth, onSchemaLoad, toggleDocs, handleGqlClickReference }) => {
|
||||
const dispatch = useDispatch();
|
||||
const tabs = useSelector((state) => state.tabs.tabs);
|
||||
const activeTabUid = useSelector((state) => state.tabs.activeTabUid);
|
||||
@ -36,6 +36,12 @@ const GraphQLRequestPane = ({ item, collection, leftPaneWidth }) => {
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if(onSchemaLoad) {
|
||||
onSchemaLoad(schema);
|
||||
}
|
||||
}, [schema]);
|
||||
|
||||
const onQueryChange = (value) => {
|
||||
dispatch(
|
||||
updateRequestGraphqlQuery({
|
||||
@ -60,7 +66,16 @@ const GraphQLRequestPane = ({ item, collection, leftPaneWidth }) => {
|
||||
const getTabPanel = (tab) => {
|
||||
switch (tab) {
|
||||
case 'query': {
|
||||
return <QueryEditor theme={storedTheme} schema={schema} width={leftPaneWidth} onSave={onSave} value={query} onRun={onRun} onEdit={onQueryChange} />;
|
||||
return <QueryEditor
|
||||
theme={storedTheme}
|
||||
schema={schema}
|
||||
width={leftPaneWidth}
|
||||
onSave={onSave}
|
||||
value={query}
|
||||
onRun={onRun}
|
||||
onEdit={onQueryChange}
|
||||
onClickReference={handleGqlClickReference}
|
||||
/>;
|
||||
}
|
||||
case 'headers': {
|
||||
return <RequestHeaders item={item} collection={collection} />;
|
||||
@ -104,9 +119,12 @@ const GraphQLRequestPane = ({ item, collection, leftPaneWidth }) => {
|
||||
{!isSchemaLoading && schema ? <IconRefresh size={18} strokeWidth={1.5}/> : null }
|
||||
<span className='ml-1'>{schema ? 'Schema' : 'Load Schema'}</span>
|
||||
</div>
|
||||
{/* <div className='flex items-center cursor-pointer hover:underline ml-2'>
|
||||
<div
|
||||
className='flex items-center cursor-pointer hover:underline ml-2'
|
||||
onClick={toggleDocs}
|
||||
>
|
||||
<IconBook size={18} strokeWidth={1.5} /><span className='ml-1'>Docs</span>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<section className="flex w-full mt-5">{getTabPanel(focusedTab.requestPaneTab)}</section>
|
||||
|
@ -25,6 +25,25 @@ const StyledWrapper = styled.div`
|
||||
border-left: solid 1px ${(props) => props.theme.requestTabPanel.dragbar.activeBorder};
|
||||
}
|
||||
}
|
||||
|
||||
div.graphql-docs-explorer-container {
|
||||
background: white;
|
||||
outline: none;
|
||||
box-shadow: rgb(0 0 0 / 15%) 0px 0px 8px;
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
z-index: 2000;
|
||||
width: 350px;
|
||||
height: 100%;
|
||||
|
||||
div.doc-explorer-title {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
div.doc-explorer-rhs {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default StyledWrapper;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import find from 'lodash/find';
|
||||
import toast from 'react-hot-toast';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
@ -12,6 +12,7 @@ import { sendRequest } from 'providers/ReduxStore/slices/collections/actions';
|
||||
import RequestNotFound from './RequestNotFound';
|
||||
import QueryUrl from 'components/RequestPane/QueryUrl';
|
||||
import NetworkError from 'components/ResponsePane/NetworkError';
|
||||
import { DocExplorer } from '@usebruno/graphql-docs';
|
||||
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
|
||||
@ -35,6 +36,22 @@ const RequestTabPanel = () => {
|
||||
const [rightPaneWidth, setRightPaneWidth] = useState(screenWidth - asideWidth - leftPaneWidth - DEFAULT_PADDING);
|
||||
const [dragging, setDragging] = useState(false);
|
||||
|
||||
// Not a recommended pattern here to have the child component
|
||||
// make a callback to set state, but treating this as an exception
|
||||
const docExplorerRef = useRef(null);
|
||||
const [schema, setSchema] = useState(null);
|
||||
const [showGqlDocs, setShowGqlDocs] = useState(false);
|
||||
const onSchemaLoad = (schema) => setSchema(schema);
|
||||
const toggleDocs = () => setShowGqlDocs((showGqlDocs) => !showGqlDocs);
|
||||
const handleGqlClickReference = (reference) => {
|
||||
if(docExplorerRef.current) {
|
||||
docExplorerRef.current.showDocForReference(reference);
|
||||
}
|
||||
if(!showGqlDocs) {
|
||||
setShowGqlDocs(true);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const leftPaneWidth = (screenWidth - asideWidth) / 2.2;
|
||||
setLeftPaneWidth(leftPaneWidth);
|
||||
@ -113,7 +130,7 @@ const RequestTabPanel = () => {
|
||||
<div className="pt-4 pb-3 px-4">
|
||||
<QueryUrl item={item} collection={collection} handleRun={handleRun} />
|
||||
</div>
|
||||
<section className="main flex flex-grow pb-4">
|
||||
<section className="main flex flex-grow pb-4 relative">
|
||||
<section className="request-pane">
|
||||
<div className="px-4" style={{ width: `${Math.max(leftPaneWidth, MIN_LEFT_PANE_WIDTH)}px`, height: `calc(100% - ${DEFAULT_PADDING}px)` }}>
|
||||
{item.type === 'graphql-request' ? (
|
||||
@ -121,6 +138,9 @@ const RequestTabPanel = () => {
|
||||
item={item}
|
||||
collection={collection}
|
||||
leftPaneWidth={leftPaneWidth}
|
||||
onSchemaLoad={onSchemaLoad}
|
||||
toggleDocs={toggleDocs}
|
||||
handleGqlClickReference={handleGqlClickReference}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
@ -136,6 +156,20 @@ const RequestTabPanel = () => {
|
||||
<ResponsePane item={item} collection={collection} rightPaneWidth={rightPaneWidth} response={item.response} />
|
||||
</section>
|
||||
</section>
|
||||
|
||||
{item.type === 'graphql-request' ? (
|
||||
<div className={`graphql-docs-explorer-container ${showGqlDocs ? '' : 'hidden'}`}>
|
||||
<DocExplorer schema={schema} ref={(r) => docExplorerRef.current = r}>
|
||||
<button
|
||||
className='mr-2'
|
||||
onClick={toggleDocs}
|
||||
aria-label="Close Documentation Explorer"
|
||||
>
|
||||
{'\u2715'}
|
||||
</button>
|
||||
</DocExplorer>
|
||||
</div>
|
||||
): null}
|
||||
</StyledWrapper>
|
||||
);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user