mirror of
https://github.com/usebruno/bruno.git
synced 2026-07-09 06:55:03 +00:00
feat: support newlines in headers, params, and variables (#5795)
* feat: support newlines in headers, params, and variables * add: collectin unit test * fix: assertion and additional header multiline * fix: assert * rm: useEffect for header validation * rm: comments * fix: already encoded url * rm: new line changes * handle new line in url * fix: lint error * add: unit test for multi line test * change: unit test * mv: functions in util * fix: drag icon position * improve: arrow height * improvements * rm: getKeyString from assert * fix: single line editor * fix: import MultiLineEditor * import getKeyString and getValueUrl * add: getTableCell in utils * rm: multiline key logic * fix * mv: getTableCell in locators.ts
This commit is contained in:
@@ -99,6 +99,11 @@ class SingleLineEditor extends Component {
|
||||
this.addOverlay(variables);
|
||||
this._enableMaskedEditor(this.props.isSecret);
|
||||
this.setState({ maskInput: this.props.isSecret });
|
||||
|
||||
// Add newline arrow markers if enabled
|
||||
if (this.props.showNewlineArrow) {
|
||||
this._updateNewlineMarkers();
|
||||
}
|
||||
}
|
||||
|
||||
/** Enable or disable masking the rendered content of the editor */
|
||||
@@ -123,6 +128,11 @@ class SingleLineEditor extends Component {
|
||||
if (this.props.onChange && (this.props.value !== this.cachedValue)) {
|
||||
this.props.onChange(this.cachedValue);
|
||||
}
|
||||
|
||||
// Update newline markers after edit
|
||||
if (this.props.showNewlineArrow) {
|
||||
this._updateNewlineMarkers();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -145,6 +155,11 @@ class SingleLineEditor extends Component {
|
||||
if (this.props.value !== prevProps.value && this.props.value !== this.cachedValue && this.editor) {
|
||||
this.cachedValue = String(this.props.value);
|
||||
this.editor.setValue(String(this.props.value ?? ''));
|
||||
|
||||
// Update newline markers after value change
|
||||
if (this.props.showNewlineArrow) {
|
||||
this._updateNewlineMarkers();
|
||||
}
|
||||
}
|
||||
if (!isEqual(this.props.isSecret, prevProps.isSecret)) {
|
||||
// If the secret flag has changed, update the editor to reflect the change
|
||||
@@ -162,6 +177,7 @@ class SingleLineEditor extends Component {
|
||||
if (this.editor) {
|
||||
this.editor.off('change', this._onEdit);
|
||||
this.editor.off('paste', this._onPaste);
|
||||
this._clearNewlineMarkers();
|
||||
this.editor.getWrapperElement().remove();
|
||||
this.editor = null;
|
||||
}
|
||||
@@ -180,6 +196,63 @@ class SingleLineEditor extends Component {
|
||||
this.editor.setOption('mode', 'brunovariables');
|
||||
};
|
||||
|
||||
/**
|
||||
* Update markers to show arrows for newlines
|
||||
*/
|
||||
_updateNewlineMarkers = () => {
|
||||
if (!this.editor) return;
|
||||
|
||||
// Clear existing markers
|
||||
this._clearNewlineMarkers();
|
||||
|
||||
this.newlineMarkers = [];
|
||||
const content = this.editor.getValue();
|
||||
|
||||
// Find all newlines and replace them with arrow widgets
|
||||
for (let i = 0; i < content.length; i++) {
|
||||
if (content[i] === '\n') {
|
||||
const pos = this.editor.posFromIndex(i);
|
||||
const nextPos = this.editor.posFromIndex(i + 1);
|
||||
|
||||
// Create a widget to display the arrow
|
||||
const arrow = document.createElement('span');
|
||||
arrow.className = 'newline-arrow';
|
||||
arrow.textContent = '↲';
|
||||
arrow.style.cssText = `
|
||||
color: #888;
|
||||
font-size: 8px;
|
||||
margin: 0 2px;
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
`;
|
||||
|
||||
// Mark the newline character and replace it with the arrow widget
|
||||
const marker = this.editor.markText(pos, nextPos, {
|
||||
replacedWith: arrow,
|
||||
handleMouseEvents: true
|
||||
});
|
||||
|
||||
this.newlineMarkers.push(marker);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear all newline markers
|
||||
*/
|
||||
_clearNewlineMarkers = () => {
|
||||
if (this.newlineMarkers) {
|
||||
this.newlineMarkers.forEach((marker) => {
|
||||
try {
|
||||
marker.clear();
|
||||
} catch (e) {
|
||||
// Marker might already be cleared
|
||||
}
|
||||
});
|
||||
this.newlineMarkers = [];
|
||||
}
|
||||
};
|
||||
|
||||
toggleVisibleSecret = () => {
|
||||
const isVisible = !this.state.maskInput;
|
||||
this.setState({ maskInput: isVisible });
|
||||
@@ -204,13 +277,15 @@ class SingleLineEditor extends Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className={`flex flex-row justify-between w-full overflow-x-auto ${this.props.className}`}>
|
||||
<div className={`flex flex-row items-center w-full overflow-x-auto ${this.props.className}`}>
|
||||
<StyledWrapper
|
||||
ref={this.editorRef}
|
||||
className={`single-line-editor grow ${this.props.readOnly ? 'read-only' : ''}`}
|
||||
{...(this.props['data-testid'] ? { 'data-testid': this.props['data-testid'] } : {})}
|
||||
/>
|
||||
{this.secretEye(this.props.isSecret)}
|
||||
<div className="flex items-center">
|
||||
{this.secretEye(this.props.isSecret)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user