mirror of
https://github.com/usebruno/bruno.git
synced 2025-06-21 04:08:01 +02:00
feat: show current env vars
This commit is contained in:
parent
a45628dd85
commit
4a403a253e
@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { IconFiles } from '@tabler/icons';
|
import { IconFiles } from '@tabler/icons';
|
||||||
import EnvironmentSelector from 'components/Environments/EnvironmentSelector';
|
import EnvironmentSelector from 'components/Environments/EnvironmentSelector';
|
||||||
|
import VariablesView from 'components/VariablesView';
|
||||||
import StyledWrapper from './StyledWrapper';
|
import StyledWrapper from './StyledWrapper';
|
||||||
|
|
||||||
const CollectionToolBar = ({ collection }) => {
|
const CollectionToolBar = ({ collection }) => {
|
||||||
@ -12,6 +13,7 @@ const CollectionToolBar = ({ collection }) => {
|
|||||||
<span className="ml-2 mr-4 font-semibold">{collection.name}</span>
|
<span className="ml-2 mr-4 font-semibold">{collection.name}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-1 items-center justify-end">
|
<div className="flex flex-1 items-center justify-end">
|
||||||
|
<VariablesView collection={collection}/>
|
||||||
<EnvironmentSelector collection={collection} />
|
<EnvironmentSelector collection={collection} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const Wrapper = styled.div`
|
||||||
|
position: absolute;
|
||||||
|
min-width: fit-content;
|
||||||
|
font-size: 14px;
|
||||||
|
top: 36px;
|
||||||
|
right: 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
z-index: 1000;
|
||||||
|
background-color: ${(props) => props.theme.variables.bg};
|
||||||
|
|
||||||
|
.popover {
|
||||||
|
border-radius: 2px;
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default Wrapper;
|
@ -0,0 +1,30 @@
|
|||||||
|
import React, {useRef} from 'react';
|
||||||
|
import StyledWrapper from './StyledWrapper';
|
||||||
|
import useOnClickOutside from 'hooks/useOnClickOutside';
|
||||||
|
|
||||||
|
const PopOver = ({
|
||||||
|
children,
|
||||||
|
iconRef,
|
||||||
|
handleClose
|
||||||
|
}) => {
|
||||||
|
const popOverRef = useRef(null);
|
||||||
|
|
||||||
|
useOnClickOutside(popOverRef, (e) => {
|
||||||
|
if(iconRef && iconRef.current) {
|
||||||
|
if (e.target == iconRef.current || iconRef.current.contains(e.target)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handleClose();
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledWrapper>
|
||||||
|
<div className="popover" ref={popOverRef}>
|
||||||
|
<div className="popover-content">{children}</div>
|
||||||
|
</div>
|
||||||
|
</StyledWrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PopOver;
|
@ -0,0 +1,15 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const StyledWrapper = styled.div`
|
||||||
|
position: relative;
|
||||||
|
align-self: stretch;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.view-environment {
|
||||||
|
width: 1rem;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export default StyledWrapper;
|
@ -0,0 +1,9 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const StyledWrapper = styled.div`
|
||||||
|
.variable-name {
|
||||||
|
color: ${(props) => props.theme.variables.name.color};
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export default StyledWrapper;
|
@ -0,0 +1,21 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import StyledWrapper from './StyledWrapper';
|
||||||
|
|
||||||
|
const VariablesTable = ({ variables }) => {
|
||||||
|
return (
|
||||||
|
<StyledWrapper>
|
||||||
|
<table className="w-full">
|
||||||
|
<tbody>
|
||||||
|
{variables.map((variable) => (
|
||||||
|
<tr key={variable.uid}>
|
||||||
|
<td className='variable-name text-yellow-600'>{variable.name}</td>
|
||||||
|
<td className='pl-2'>{variable.value}</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</StyledWrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default VariablesTable;
|
46
packages/bruno-app/src/components/VariablesView/index.js
Normal file
46
packages/bruno-app/src/components/VariablesView/index.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import React, { useState, useRef } from 'react';
|
||||||
|
import get from 'lodash/get';
|
||||||
|
import filter from 'lodash/filter';
|
||||||
|
import { findEnvironmentInCollection } from 'utils/collections';
|
||||||
|
import VariablesTable from './VariablesTable';
|
||||||
|
import StyledWrapper from './StyledWrapper';
|
||||||
|
import PopOver from './PopOver';
|
||||||
|
import { IconEye } from '@tabler/icons';
|
||||||
|
|
||||||
|
const VariablesView = ({collection}) => {
|
||||||
|
const iconRef = useRef(null);
|
||||||
|
const [popOverOpen, setPopOverOpen] = useState(false);
|
||||||
|
|
||||||
|
const environment = findEnvironmentInCollection(collection, collection.activeEnvironmentUid);
|
||||||
|
const variables = get(environment, 'variables', []);
|
||||||
|
const enabledVariables = filter(variables, (variable) => variable.enabled);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledWrapper
|
||||||
|
className="mr-2 server-syncstatus-icon"
|
||||||
|
ref={iconRef}
|
||||||
|
>
|
||||||
|
<div className="flex p-1 items-center"
|
||||||
|
onClick={() => setPopOverOpen(true)}
|
||||||
|
onMouseEnter={() => setPopOverOpen(true)}
|
||||||
|
onMouseLeave={() => setPopOverOpen(false)}
|
||||||
|
>
|
||||||
|
<div className='cursor-pointer view-environment'>
|
||||||
|
<IconEye size={18} strokeWidth={1.5} />
|
||||||
|
</div>
|
||||||
|
{popOverOpen && (
|
||||||
|
<PopOver
|
||||||
|
iconRef={iconRef}
|
||||||
|
handleClose={() => setPopOverOpen(false)}
|
||||||
|
>
|
||||||
|
<div className="px-2 py-1">
|
||||||
|
{(enabledVariables && enabledVariables.length) ? <VariablesTable variables={enabledVariables} /> : 'No variables found'}
|
||||||
|
</div>
|
||||||
|
</PopOver>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</StyledWrapper>
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
export default VariablesView;
|
34
packages/bruno-app/src/hooks/useOnClickOutside/index.js
Normal file
34
packages/bruno-app/src/hooks/useOnClickOutside/index.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// See https://usehooks.com/useOnClickOutside/
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
|
const useOnClickOutside = (ref, handler) => {
|
||||||
|
useEffect(
|
||||||
|
() => {
|
||||||
|
const listener = event => {
|
||||||
|
// Do nothing if clicking ref's element or descendent elements
|
||||||
|
if (!ref.current || ref.current.contains(event.target)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handler(event);
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('mousedown', listener);
|
||||||
|
document.addEventListener('touchstart', listener);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('mousedown', listener);
|
||||||
|
document.removeEventListener('touchstart', listener);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
// Add ref and handler to effect dependencies
|
||||||
|
// It's worth noting that because passed in handler is a new ...
|
||||||
|
// ... function on every render that will cause this effect ...
|
||||||
|
// ... callback/cleanup to run every render. It's not a big deal ...
|
||||||
|
// ... but to optimize you can wrap handler in useCallback before ...
|
||||||
|
// ... passing it into this hook.
|
||||||
|
[ref, handler]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useOnClickOutside;
|
@ -16,6 +16,14 @@ const darkTheme = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
variables: {
|
||||||
|
bg: 'rgb(48, 48, 49)',
|
||||||
|
|
||||||
|
name: {
|
||||||
|
color: '#569cd6',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
menubar: {
|
menubar: {
|
||||||
bg: '#333333'
|
bg: '#333333'
|
||||||
},
|
},
|
||||||
|
@ -20,6 +20,14 @@ const lightTheme = {
|
|||||||
bg: 'rgb(44, 44, 44)'
|
bg: 'rgb(44, 44, 44)'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
variables: {
|
||||||
|
bg: '#fff',
|
||||||
|
|
||||||
|
name: {
|
||||||
|
color: '#546de5',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
sidebar: {
|
sidebar: {
|
||||||
color: 'rgb(52, 52, 52)',
|
color: 'rgb(52, 52, 52)',
|
||||||
muted: '#4b5563',
|
muted: '#4b5563',
|
||||||
|
@ -6,6 +6,7 @@ const { ScriptRuntime } = require('@usebruno/js');
|
|||||||
const prepareRequest = require('./prepare-request');
|
const prepareRequest = require('./prepare-request');
|
||||||
const { cancelTokens, saveCancelToken, deleteCancelToken } = require('../../utils/cancel-token');
|
const { cancelTokens, saveCancelToken, deleteCancelToken } = require('../../utils/cancel-token');
|
||||||
const { uuid } = require('../../utils/common');
|
const { uuid } = require('../../utils/common');
|
||||||
|
const interpolateVars = require('./interpolate-vars');
|
||||||
|
|
||||||
const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
|
const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
|
||||||
// handler for sending http request
|
// handler for sending http request
|
||||||
@ -34,7 +35,7 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
|
|||||||
if(request.script && request.script.length) {
|
if(request.script && request.script.length) {
|
||||||
request.script = request.script += '\n onRequest(brunoRequest);';
|
request.script = request.script += '\n onRequest(brunoRequest);';
|
||||||
const scriptRuntime = new ScriptRuntime();
|
const scriptRuntime = new ScriptRuntime();
|
||||||
scriptRuntime.run(request.script, request);
|
scriptRuntime.run(request.script, request, environment);
|
||||||
}
|
}
|
||||||
|
|
||||||
mainWindow.webContents.send('main:http-request-sent', {
|
mainWindow.webContents.send('main:http-request-sent', {
|
||||||
@ -49,6 +50,8 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
|
|||||||
cancelTokenUid
|
cancelTokenUid
|
||||||
});
|
});
|
||||||
|
|
||||||
|
interpolateVars(request, environment);
|
||||||
|
|
||||||
const result = await axios(request);
|
const result = await axios(request);
|
||||||
|
|
||||||
deleteCancelToken(cancelTokenUid);
|
deleteCancelToken(cancelTokenUid);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
const Mustache = require('mustache');
|
const Mustache = require('mustache');
|
||||||
const { each } = require('lodash');
|
const { each, get } = require('lodash');
|
||||||
|
|
||||||
// override the default escape function to prevent escaping
|
// override the default escape function to prevent escaping
|
||||||
Mustache.escape = function (value) {
|
Mustache.escape = function (value) {
|
||||||
@ -39,7 +39,8 @@ const interpolateVars = (request, environment) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Todo: Make interpolation work with body mode json
|
// Todo: Make interpolation work with body mode json
|
||||||
switch (request.body.mode) {
|
const mode = get(request, 'body.mode');
|
||||||
|
switch (mode) {
|
||||||
case 'text': {
|
case 'text': {
|
||||||
request.body.text = interpolate(request.body.text);
|
request.body.text = interpolate(request.body.text);
|
||||||
break;
|
break;
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
const { get, each, filter } = require('lodash');
|
const { get, each, filter } = require('lodash');
|
||||||
const qs = require('qs');
|
const qs = require('qs');
|
||||||
const interpolateVars = require('./interpolate-vars');
|
|
||||||
|
|
||||||
const prepareRequest = (request, environment) => {
|
const prepareRequest = (request, environment) => {
|
||||||
interpolateVars(request, environment);
|
|
||||||
const headers = {};
|
const headers = {};
|
||||||
each(request.headers, (h) => {
|
each(request.headers, (h) => {
|
||||||
if (h.enabled) {
|
if (h.enabled) {
|
||||||
|
10
packages/bruno-js/src/scripts/bru.js
Normal file
10
packages/bruno-js/src/scripts/bru.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
class Bru {
|
||||||
|
constructor(environment) {
|
||||||
|
this._environment = environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
setVar(key, value) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Bru;
|
@ -1,14 +1,17 @@
|
|||||||
const { NodeVM } = require('vm2');
|
const { NodeVM } = require('vm2');
|
||||||
|
const Bru = require('./bru');
|
||||||
const BrunoRequest = require('./bruno-request');
|
const BrunoRequest = require('./bruno-request');
|
||||||
|
|
||||||
class ScriptRuntime {
|
class ScriptRuntime {
|
||||||
constructor() {
|
constructor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
run(script, request) {
|
run(script, request, environment) {
|
||||||
|
const bru = new Bru(environment);
|
||||||
const brunoRequest = new BrunoRequest(request);
|
const brunoRequest = new BrunoRequest(request);
|
||||||
|
|
||||||
const context = {
|
const context = {
|
||||||
|
bru,
|
||||||
brunoRequest
|
brunoRequest
|
||||||
};
|
};
|
||||||
const vm = new NodeVM({
|
const vm = new NodeVM({
|
||||||
|
Loading…
x
Reference in New Issue
Block a user