mirror of
https://github.com/usebruno/bruno.git
synced 2025-08-06 20:09:20 +02:00
feat: Header keys autocomplete added
This commit is contained in:
@ -3,5 +3,5 @@
|
||||
"tabWidth": 2,
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"printWidth": 180
|
||||
"printWidth": 130
|
||||
}
|
||||
|
@ -1,6 +1,33 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
.mousetrap {
|
||||
position: relative;
|
||||
}
|
||||
.suggestions {
|
||||
z-index: 99;
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
background-color: white;
|
||||
border: 1px solid #ececec;
|
||||
border-top-width: 0;
|
||||
list-style: none;
|
||||
font-weight: 500;
|
||||
margin-top: 0;
|
||||
max-height: 143px;
|
||||
max-width: 17rem;
|
||||
overflow-y: auto;
|
||||
padding-left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.suggestion-active,
|
||||
.suggestions li:hover {
|
||||
background-color: #d6d6d6;
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
|
@ -1,13 +1,20 @@
|
||||
import React from 'react';
|
||||
import React, { useState, useRef } from 'react';
|
||||
import get from 'lodash/get';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import { IconTrash } from '@tabler/icons';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { addRequestHeader, updateRequestHeader, deleteRequestHeader } from 'providers/ReduxStore/slices/collections';
|
||||
import { suggestions } from './suggestionList';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
|
||||
const RequestHeaders = ({ item, collection }) => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [showSuggestions, setShowSuggestions] = useState(false);
|
||||
const [activeSuggestion, setActiveSuggestion] = useState(0);
|
||||
const [activeHeader, setActiveHeader] = useState();
|
||||
const [filteredSuggestions, setFilteredSuggestions] = useState([]);
|
||||
|
||||
const headers = item.draft ? get(item, 'draft.request.headers') : get(item, 'request.headers');
|
||||
|
||||
const addHeader = () => {
|
||||
@ -19,11 +26,38 @@ const RequestHeaders = ({ item, collection }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const handleOnClick = (e, _header, type) => {
|
||||
const header = cloneDeep(_header);
|
||||
header.name = e.target.innerText;
|
||||
|
||||
setShowSuggestions(false);
|
||||
setFilteredSuggestions([]);
|
||||
|
||||
dispatch(
|
||||
updateRequestHeader({
|
||||
header: header,
|
||||
itemUid: item.uid,
|
||||
collectionUid: collection.uid
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const handleActiveHeader = (e, index) => {
|
||||
setActiveHeader(index);
|
||||
};
|
||||
|
||||
const handleHeaderValueChange = (e, _header, type) => {
|
||||
const header = cloneDeep(_header);
|
||||
switch (type) {
|
||||
case 'name': {
|
||||
header.name = e.target.value;
|
||||
const userInput = e.target.value;
|
||||
const filteredSuggestions = suggestions.filter(
|
||||
(suggestion) => suggestion.toLowerCase().indexOf(userInput.toLowerCase()) > -1
|
||||
);
|
||||
setActiveSuggestion(0);
|
||||
setShowSuggestions(true);
|
||||
setFilteredSuggestions(filteredSuggestions);
|
||||
header.name = userInput;
|
||||
break;
|
||||
}
|
||||
case 'value': {
|
||||
@ -83,8 +117,30 @@ const RequestHeaders = ({ item, collection }) => {
|
||||
spellCheck="false"
|
||||
value={header.name}
|
||||
className="mousetrap"
|
||||
onFocus={(e) => handleActiveHeader(e, index)}
|
||||
onChange={(e) => handleHeaderValueChange(e, header, 'name')}
|
||||
/>
|
||||
{showSuggestions && Boolean(header.name) && activeHeader == index ? (
|
||||
filteredSuggestions.length ? (
|
||||
<ul className="suggestions">
|
||||
{filteredSuggestions.map((suggestionItem, idx) => {
|
||||
return (
|
||||
<li
|
||||
key={idx}
|
||||
className={idx === activeSuggestion ? 'suggestion-active' : null}
|
||||
onClick={(e) => handleOnClick(e, header, 'name')}
|
||||
>
|
||||
{suggestionItem}
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
) : (
|
||||
<div className="suggestions">
|
||||
<em>No suggestions</em>
|
||||
</div>
|
||||
)
|
||||
) : null}
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
@ -112,7 +168,12 @@ const RequestHeaders = ({ item, collection }) => {
|
||||
</td>
|
||||
<td>
|
||||
<div className="flex items-center">
|
||||
<input type="checkbox" checked={header.enabled} className="mr-3 mousetrap" onChange={(e) => handleHeaderValueChange(e, header, 'enabled')} />
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={header.enabled}
|
||||
className="mr-3 mousetrap"
|
||||
onChange={(e) => handleHeaderValueChange(e, header, 'enabled')}
|
||||
/>
|
||||
<button onClick={() => handleRemoveHeader(header)}>
|
||||
<IconTrash strokeWidth={1.5} size={20} />
|
||||
</button>
|
||||
|
@ -0,0 +1,33 @@
|
||||
export const suggestions = [
|
||||
'Accept',
|
||||
'Accept-Charset',
|
||||
'Accept-Encoding',
|
||||
'Accept-Language',
|
||||
'Accept-Datetime',
|
||||
'Access-Control-Allow-Origin',
|
||||
'Access-Control-Request-Method',
|
||||
'Access-Control-Request-Headers',
|
||||
'Authorization',
|
||||
'Cache-Control',
|
||||
'Connection',
|
||||
'Content-Length',
|
||||
'Content-Type',
|
||||
'Cookie',
|
||||
'Date',
|
||||
'Expect',
|
||||
'Forwarded',
|
||||
'Host',
|
||||
'If-Match',
|
||||
'If-Modified-Since',
|
||||
'If-None-Match',
|
||||
'If-Range',
|
||||
'If-Unmodified-Since',
|
||||
'Max-Forwards',
|
||||
'Origin',
|
||||
'Pragma',
|
||||
'Proxy-Authorization',
|
||||
'Range',
|
||||
'Referer',
|
||||
'User-Agent',
|
||||
'Upgrade-Insecure-Requests'
|
||||
];
|
Reference in New Issue
Block a user