mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-24 05:05:39 +00:00
feature/autoSave (#582)
This commit is contained in:
@@ -10,12 +10,14 @@ import SingleLineEditor from 'components/SingleLineEditor';
|
||||
import { isMacOS } from 'utils/common/platform';
|
||||
import { hasRequestChanges } from 'utils/collections';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import { usePreferences } from 'providers/Preferences/index';
|
||||
import GenerateCodeItem from 'components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/index';
|
||||
import toast from 'react-hot-toast';
|
||||
|
||||
const QueryUrl = ({ item, collection, handleRun }) => {
|
||||
const { theme, storedTheme } = useTheme();
|
||||
const dispatch = useDispatch();
|
||||
const autoSavePreference = usePreferences().preferences.request.autoSave;
|
||||
const method = item.draft ? get(item, 'draft.request.method') : get(item, 'request.method');
|
||||
const url = item.draft ? get(item, 'draft.request.url', '') : get(item, 'request.url', '');
|
||||
const isMac = isMacOS();
|
||||
@@ -33,8 +35,8 @@ const QueryUrl = ({ item, collection, handleRun }) => {
|
||||
setMethodSelectorWidth(el.offsetWidth);
|
||||
}, [method]);
|
||||
|
||||
const onSave = (finalValue) => {
|
||||
dispatch(saveRequest(item.uid, collection.uid));
|
||||
const onSave = (notify = 1) => {
|
||||
dispatch(saveRequest(item.uid, collection.uid, notify));
|
||||
};
|
||||
|
||||
const onUrlChange = (value) => {
|
||||
@@ -118,6 +120,7 @@ const QueryUrl = ({ item, collection, handleRun }) => {
|
||||
highlightPathParams={true}
|
||||
item={item}
|
||||
showNewlineArrow={true}
|
||||
autoSave={autoSavePreference}
|
||||
/>
|
||||
<div className="flex items-center h-full mr-2 cursor-pointer" id="send-request" onClick={handleRun}>
|
||||
<div
|
||||
|
||||
@@ -5,6 +5,7 @@ import { defineCodeMirrorBrunoVariablesMode } from 'utils/common/codemirror';
|
||||
import { MaskedEditor } from 'utils/common/masked-editor';
|
||||
import { setupAutoComplete } from 'utils/codemirror/autocomplete';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import { usePreferences } from 'providers/Preferences/index';
|
||||
import { IconEye, IconEyeOff } from '@tabler/icons';
|
||||
import { setupLinkAware } from 'utils/codemirror/linkAware';
|
||||
|
||||
@@ -19,6 +20,7 @@ class SingleLineEditor extends Component {
|
||||
this.cachedValue = props.value || '';
|
||||
this.editorRef = React.createRef();
|
||||
this.variables = {};
|
||||
this.autoSaveInterval = null;
|
||||
this.readOnly = props.readOnly || false;
|
||||
|
||||
this.state = {
|
||||
@@ -100,6 +102,7 @@ class SingleLineEditor extends Component {
|
||||
this.editor.on('change', this._onEdit);
|
||||
this.editor.on('paste', this._onPaste);
|
||||
this.addOverlay(variables);
|
||||
this.startAutosave();
|
||||
this._enableMaskedEditor(this.props.isSecret);
|
||||
this.setState({ maskInput: this.props.isSecret });
|
||||
|
||||
@@ -140,6 +143,26 @@ class SingleLineEditor extends Component {
|
||||
}
|
||||
};
|
||||
|
||||
startAutosave = () => {
|
||||
if (this.props.autoSave && this.props.onSave) {
|
||||
this.autoSaveInterval = setInterval(this.saveEditorContent, this.props.autoSaveInterval || 15000); // Default to 15 sec
|
||||
}
|
||||
};
|
||||
|
||||
clearAutosave = () => {
|
||||
if (this.autoSaveInterval) {
|
||||
clearInterval(this.autoSaveInterval);
|
||||
}
|
||||
};
|
||||
|
||||
saveEditorContent = () => {
|
||||
if (this.props.onSave) {
|
||||
const content = this.editor.getValue();
|
||||
console.log(content);
|
||||
this.props.onSave(content, 0);
|
||||
}
|
||||
};
|
||||
|
||||
_onPaste = (_, event) => this.props.onPaste?.(event);
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
@@ -190,6 +213,7 @@ class SingleLineEditor extends Component {
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.clearAutosave();
|
||||
if (this.editor) {
|
||||
if (this.editor?._destroyLinkAware) {
|
||||
this.editor._destroyLinkAware();
|
||||
|
||||
@@ -94,28 +94,32 @@ export const renameCollection = (newName, collectionUid) => (dispatch, getState)
|
||||
});
|
||||
};
|
||||
|
||||
export const saveRequest = (itemUid, collectionUid, saveSilently) => (dispatch, getState) => {
|
||||
|
||||
export const saveRequest = (itemUid, collectionUid, saveSilently, notify = 1) => (dispatch, getState) => {
|
||||
const state = getState();
|
||||
const collection = findCollectionByUid(state.collections.collections, collectionUid);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!collection) {
|
||||
return reject(new Error('Collection not found'));
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!collection) {
|
||||
return reject(new Error('Collection not found'));
|
||||
}
|
||||
|
||||
const collectionCopy = cloneDeep(collection);
|
||||
const item = findItemInCollection(collectionCopy, itemUid);
|
||||
if (!item) {
|
||||
return reject(new Error('Not able to locate item'));
|
||||
}
|
||||
const collectionCopy = cloneDeep(collection);
|
||||
const item = findItemInCollection(collectionCopy, itemUid);
|
||||
if (!item) {
|
||||
return reject(new Error('Not able to locate item'));
|
||||
}
|
||||
|
||||
const itemToSave = transformRequestToSaveToFilesystem(item);
|
||||
const { ipcRenderer } = window;
|
||||
const itemToSave = transformRequestToSaveToFilesystem(item);
|
||||
const { ipcRenderer } = window;
|
||||
|
||||
itemSchema
|
||||
.validate(itemToSave)
|
||||
.then(() => ipcRenderer.invoke('renderer:save-request', item.pathname, itemToSave))
|
||||
.then(() => {
|
||||
if (notify === 1) {
|
||||
toast.success('Request saved successfully');
|
||||
}
|
||||
if (!saveSilently) {
|
||||
toast.success('Request saved successfully');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user