mirror of
https://github.com/usebruno/bruno.git
synced 2024-11-21 23:43:15 +01:00
feat: layout redesign
This commit is contained in:
parent
9c5d66e7db
commit
a54d6fe6d7
1
.gitignore
vendored
1
.gitignore
vendored
@ -27,5 +27,6 @@ yarn-error.log*
|
|||||||
.env.production.local
|
.env.production.local
|
||||||
|
|
||||||
# next.js
|
# next.js
|
||||||
|
/renderer
|
||||||
/renderer/.next/
|
/renderer/.next/
|
||||||
/renderer/out/
|
/renderer/out/
|
||||||
|
4
packages/bruno-app/public/send.svg
Normal file
4
packages/bruno-app/public/send.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48">
|
||||||
|
<path fill="#515151" d="M4.02 42l41.98-18-41.98-18-.02 14 30 4-30 4z"/>
|
||||||
|
<path d="M0 0h48v48h-48z" fill="none"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 211 B |
@ -7,6 +7,8 @@ import QueryParams from 'components/RequestPane/QueryParams';
|
|||||||
import RequestHeaders from 'components/RequestPane/RequestHeaders';
|
import RequestHeaders from 'components/RequestPane/RequestHeaders';
|
||||||
import RequestBody from 'components/RequestPane/RequestBody';
|
import RequestBody from 'components/RequestPane/RequestBody';
|
||||||
import RequestBodyMode from 'components/RequestPane/RequestBody/RequestBodyMode';
|
import RequestBodyMode from 'components/RequestPane/RequestBody/RequestBodyMode';
|
||||||
|
import QueryUrl from 'components/RequestPane/QueryUrl';
|
||||||
|
import { sendRequest } from 'providers/ReduxStore/slices/collections';
|
||||||
import StyledWrapper from './StyledWrapper';
|
import StyledWrapper from './StyledWrapper';
|
||||||
|
|
||||||
const HttpRequestPane = ({item, collection, leftPaneWidth}) => {
|
const HttpRequestPane = ({item, collection, leftPaneWidth}) => {
|
||||||
@ -14,6 +16,8 @@ const HttpRequestPane = ({item, collection, leftPaneWidth}) => {
|
|||||||
const tabs = useSelector((state) => state.tabs.tabs);
|
const tabs = useSelector((state) => state.tabs.tabs);
|
||||||
const activeTabUid = useSelector((state) => state.tabs.activeTabUid);
|
const activeTabUid = useSelector((state) => state.tabs.activeTabUid);
|
||||||
|
|
||||||
|
const sendNetworkRequest = async () => dispatch(sendRequest(item, collection.uid));
|
||||||
|
|
||||||
const selectTab = (tab) => {
|
const selectTab = (tab) => {
|
||||||
dispatch(updateRequestPaneTab({
|
dispatch(updateRequestPaneTab({
|
||||||
uid: item.uid,
|
uid: item.uid,
|
||||||
@ -59,6 +63,13 @@ const HttpRequestPane = ({item, collection, leftPaneWidth}) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledWrapper className="flex flex-col h-full relativ">
|
<StyledWrapper className="flex flex-col h-full relativ">
|
||||||
|
<div className="pt-2 pb-3">
|
||||||
|
<QueryUrl
|
||||||
|
item = {item}
|
||||||
|
collection={collection}
|
||||||
|
handleRun={sendNetworkRequest}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div className="flex items-center tabs" role="tablist">
|
<div className="flex items-center tabs" role="tablist">
|
||||||
<div className={getTabClassname('params')} role="tab" onClick={() => selectTab('params')}>Params</div>
|
<div className={getTabClassname('params')} role="tab" onClick={() => selectTab('params')}>Params</div>
|
||||||
<div className={getTabClassname('body')} role="tab" onClick={() => selectTab('body')}>Body</div>
|
<div className={getTabClassname('body')} role="tab" onClick={() => selectTab('body')}>Body</div>
|
||||||
|
@ -4,15 +4,12 @@ const Wrapper = styled.div`
|
|||||||
height: 2.3rem;
|
height: 2.3rem;
|
||||||
|
|
||||||
div.method-selector-container {
|
div.method-selector-container {
|
||||||
border: solid 1px var(--color-layout-border);
|
|
||||||
border-right: none;
|
|
||||||
background-color: var(--color-sidebar-background);
|
background-color: var(--color-sidebar-background);
|
||||||
border-top-left-radius: 3px;
|
border-top-left-radius: 3px;
|
||||||
border-bottom-left-radius: 3px;
|
border-bottom-left-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.input-container {
|
div.input-container {
|
||||||
border: solid 1px var(--color-layout-border);
|
|
||||||
background-color: var(--color-sidebar-background);
|
background-color: var(--color-sidebar-background);
|
||||||
border-top-right-radius: 3px;
|
border-top-right-radius: 3px;
|
||||||
border-bottom-right-radius: 3px;
|
border-bottom-right-radius: 3px;
|
||||||
|
@ -38,14 +38,10 @@ const QueryUrl = ({item, collection, handleRun}) => {
|
|||||||
autoComplete="off" autoCorrect="off" autoCapitalize="off" spellCheck="false"
|
autoComplete="off" autoCorrect="off" autoCapitalize="off" spellCheck="false"
|
||||||
onChange={(event) => onUrlChange(event.target.value)}
|
onChange={(event) => onUrlChange(event.target.value)}
|
||||||
/>
|
/>
|
||||||
|
<div className="flex items-center h-full mr-2 cursor-pointer" onClick={handleRun}>
|
||||||
|
<img src='/send.svg' style={{width: '22px'}}/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
|
||||||
style={{backgroundColor: 'var(--color-brand)'}}
|
|
||||||
className="flex items-center h-full text-white active:bg-blue-600 font-bold text-xs px-4 py-2 ml-2 uppercase rounded shadow hover:shadow-md outline-none focus:outline-none ease-linear transition-all duration-150"
|
|
||||||
onClick={handleRun}
|
|
||||||
>
|
|
||||||
<span style={{marginLeft: 5}}>Send</span>
|
|
||||||
</button>
|
|
||||||
</StyledWrapper>
|
</StyledWrapper>
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import find from 'lodash/find';
|
import find from 'lodash/find';
|
||||||
import { useSelector, useDispatch } from 'react-redux';
|
import { useSelector, useDispatch } from 'react-redux';
|
||||||
import QueryUrl from 'components/RequestPane/QueryUrl';
|
|
||||||
import GraphQLRequestPane from 'components/RequestPane/GraphQLRequestPane';
|
import GraphQLRequestPane from 'components/RequestPane/GraphQLRequestPane';
|
||||||
import HttpRequestPane from 'components/RequestPane/HttpRequestPane';
|
import HttpRequestPane from 'components/RequestPane/HttpRequestPane';
|
||||||
import ResponsePane from 'components/ResponsePane';
|
import ResponsePane from 'components/ResponsePane';
|
||||||
import Welcome from 'components/Welcome';
|
import Welcome from 'components/Welcome';
|
||||||
import { findItemInCollection } from 'utils/collections';
|
import { findItemInCollection } from 'utils/collections';
|
||||||
import { sendRequest } from 'providers/ReduxStore/slices/collections';
|
|
||||||
import { updateRequestPaneTabWidth } from 'providers/ReduxStore/slices/tabs';
|
import { updateRequestPaneTabWidth } from 'providers/ReduxStore/slices/tabs';
|
||||||
import RequestNotFound from './RequestNotFound';
|
import RequestNotFound from './RequestNotFound';
|
||||||
import useGraphqlSchema from '../../hooks/useGraphqlSchema';
|
import useGraphqlSchema from '../../hooks/useGraphqlSchema';
|
||||||
@ -104,22 +102,9 @@ const RequestTabPanel = () => {
|
|||||||
|
|
||||||
const onGraphqlQueryChange = (value) => {};
|
const onGraphqlQueryChange = (value) => {};
|
||||||
const runQuery = async () => {};
|
const runQuery = async () => {};
|
||||||
const sendNetworkRequest = async () => dispatch(sendRequest(item, collection.uid));
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledWrapper className={`flex flex-col flex-grow ${dragging ? 'dragging' : ''}`}>
|
<StyledWrapper className={`flex flex-col flex-grow ${dragging ? 'dragging' : ''}`}>
|
||||||
<div
|
|
||||||
className="px-4 pt-6 pb-4"
|
|
||||||
style={{
|
|
||||||
borderBottom: 'solid 1px var(--color-request-dragbar-background)'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<QueryUrl
|
|
||||||
item = {item}
|
|
||||||
collection={collection}
|
|
||||||
handleRun={sendNetworkRequest}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<section className="main flex flex-grow">
|
<section className="main flex flex-grow">
|
||||||
<section className="request-pane mt-2">
|
<section className="request-pane mt-2">
|
||||||
<div
|
<div
|
||||||
|
@ -13,6 +13,8 @@ const StyledWrapper = styled.div`
|
|||||||
|
|
||||||
.close-icon-container {
|
.close-icon-container {
|
||||||
min-height: 20px;
|
min-height: 20px;
|
||||||
|
min-width: 24px;
|
||||||
|
margin-left: 4px;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
|
||||||
.close-icon {
|
.close-icon {
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
|
||||||
const Wrapper = styled.div`
|
const Wrapper = styled.div`
|
||||||
border-bottom: 1px solid var(--color-layout-border);
|
border-bottom: 1px solid var(--color-request-dragbar-background);
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
bottom: -1px;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
|
|
||||||
@ -17,11 +16,8 @@ const Wrapper = styled.div`
|
|||||||
|
|
||||||
li {
|
li {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
width: 150px;
|
|
||||||
min-width: 150px;
|
|
||||||
max-width: 150px;
|
max-width: 150px;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
border-bottom: none;
|
|
||||||
list-style: none;
|
list-style: none;
|
||||||
padding-top: 8px;
|
padding-top: 8px;
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
@ -31,20 +27,17 @@ const Wrapper = styled.div`
|
|||||||
font-size: 0.8125rem;
|
font-size: 0.8125rem;
|
||||||
height: 38px;
|
height: 38px;
|
||||||
|
|
||||||
|
margin-right: 6px;
|
||||||
|
background: #f7f7f7;
|
||||||
|
border-radius: 0;
|
||||||
|
|
||||||
.tab-container {
|
.tab-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-left: 1px solid #dcdcdc;
|
|
||||||
border-right: 1px solid transparent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
border-color: var(--color-layout-border);
|
background: #e7e7e7;
|
||||||
background: #fff;
|
font-weight: 500;
|
||||||
border-radius: 5px 5px 0 0;
|
|
||||||
|
|
||||||
.tab-container {
|
|
||||||
border-left: 1px solid transparent;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
@ -98,30 +91,6 @@ const Wrapper = styled.div`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
li.last-tab {
|
|
||||||
.tab-container {
|
|
||||||
border-right: 1px solid #dcdcdc;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
.tab-container {
|
|
||||||
border-right: 1px solid transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
li.active + li {
|
|
||||||
.tab-container {
|
|
||||||
border-left: 1px solid transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
li:first-child {
|
|
||||||
.tab-container {
|
|
||||||
border-left: 1px solid transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.has-chevrons {
|
&.has-chevrons {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
--color-sidebar-collection-item-active-indent-border: #d0d0d0;
|
--color-sidebar-collection-item-active-indent-border: #d0d0d0;
|
||||||
--color-sidebar-collection-item-active-background: #dddddd;
|
--color-sidebar-collection-item-active-background: #dddddd;
|
||||||
--color-sidebar-background: #f3f3f3;
|
--color-sidebar-background: #f3f3f3;
|
||||||
--color-request-dragbar-background: #f3f3f3;
|
--color-request-dragbar-background: #efefef;
|
||||||
--color-request-dragbar-background-active: rgb(200, 200, 200);
|
--color-request-dragbar-background-active: rgb(200, 200, 200);
|
||||||
--color-tab-inactive: rgb(155 155 155);
|
--color-tab-inactive: rgb(155 155 155);
|
||||||
--color-tab-active-border: #546de5;
|
--color-tab-active-border: #546de5;
|
||||||
|
40
packages/bruno-app/src/utils/network/browser.js
Normal file
40
packages/bruno-app/src/utils/network/browser.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
const axios = require('axios');
|
||||||
|
const FormData = require('form-data');
|
||||||
|
const { forOwn, extend } = require('lodash');
|
||||||
|
|
||||||
|
export const sendHttpRequestInBrowser = async (request) => {
|
||||||
|
try {
|
||||||
|
// make axios work in node using form data
|
||||||
|
// reference: https://github.com/axios/axios/issues/1006#issuecomment-320165427
|
||||||
|
if(request.headers && request.headers['content-type'] === 'multipart/form-data') {
|
||||||
|
const form = new FormData();
|
||||||
|
forOwn(request.data, (value, key) => {
|
||||||
|
form.append(key, value);
|
||||||
|
});
|
||||||
|
extend(request.headers, form.getHeaders());
|
||||||
|
request.data = form;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await axios(request);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: result.status,
|
||||||
|
headers: result.headers,
|
||||||
|
data: result.data
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
if(error.response) {
|
||||||
|
return {
|
||||||
|
status: error.response.status,
|
||||||
|
headers: error.response.headers,
|
||||||
|
data: error.response.data
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: -1,
|
||||||
|
headers: [],
|
||||||
|
data: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
@ -2,6 +2,7 @@ import each from 'lodash/each';
|
|||||||
import filter from 'lodash/filter';
|
import filter from 'lodash/filter';
|
||||||
import qs from 'qs';
|
import qs from 'qs';
|
||||||
import { rawRequest, gql } from 'graphql-request';
|
import { rawRequest, gql } from 'graphql-request';
|
||||||
|
import { sendHttpRequestInBrowser } from './browser';
|
||||||
|
|
||||||
const sendNetworkRequest = async (item) => {
|
const sendNetworkRequest = async (item) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -79,10 +80,15 @@ const sendHttpRequest = async (request) => {
|
|||||||
console.log('>>> Sending Request');
|
console.log('>>> Sending Request');
|
||||||
console.log(options);
|
console.log(options);
|
||||||
|
|
||||||
ipcRenderer
|
// Todo: Choose based on platform (web/desktop)
|
||||||
.invoke('send-http-request', options)
|
sendHttpRequestInBrowser(options)
|
||||||
.then(resolve)
|
.then(resolve)
|
||||||
.catch(reject);
|
.catch(reject);
|
||||||
|
|
||||||
|
// ipcRenderer
|
||||||
|
// .invoke('send-http-request', options)
|
||||||
|
// .then(resolve)
|
||||||
|
// .catch(reject);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user