mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-26 14:15:52 +00:00
fix: autosave for environment tabs and folder-level auth (#6510)
* feat: enhance autosave middleware to support environment draft and folder auth drafts * feat: extend autosave middleware to handle global and collection environment drafts * feat: update authentication components to use unified updateAuth function * refactor: rename updateAuth to updateFolderAuth for consistency in authentication components
This commit is contained in:
@@ -3,7 +3,7 @@ import get from 'lodash/get';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import { saveFolderRoot } from 'providers/ReduxStore/slices/collections/actions';
|
||||
import OAuth2AuthorizationCode from 'components/RequestPane/Auth/OAuth2/AuthorizationCode/index';
|
||||
import { updateFolderAuth } from 'providers/ReduxStore/slices/collections';
|
||||
import { updateFolderAuth as _updateFolderAuth } from 'providers/ReduxStore/slices/collections';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import OAuth2PasswordCredentials from 'components/RequestPane/Auth/OAuth2/PasswordCredentials/index';
|
||||
import OAuth2ClientCredentials from 'components/RequestPane/Auth/OAuth2/ClientCredentials/index';
|
||||
@@ -20,7 +20,7 @@ import AwsV4Auth from 'components/RequestPane/Auth/AwsV4Auth';
|
||||
import { humanizeRequestAuthMode, getTreePathFromCollectionToItem } from 'utils/collections/index';
|
||||
import Button from 'ui/Button';
|
||||
|
||||
const GrantTypeComponentMap = ({ collection, folder }) => {
|
||||
const GrantTypeComponentMap = ({ collection, folder, updateFolderAuth }) => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const save = () => {
|
||||
@@ -90,6 +90,13 @@ const Auth = ({ collection, folder }) => {
|
||||
dispatch(saveFolderRoot(collection.uid, folder.uid));
|
||||
};
|
||||
|
||||
const updateFolderAuth = ({ itemUid, ...rest }) => {
|
||||
return _updateFolderAuth({
|
||||
...rest,
|
||||
folderUid: folder.uid
|
||||
});
|
||||
};
|
||||
|
||||
const getAuthView = () => {
|
||||
switch (authMode) {
|
||||
case 'basic': {
|
||||
@@ -178,7 +185,7 @@ const Auth = ({ collection, folder }) => {
|
||||
collection={collection}
|
||||
item={folder}
|
||||
/>
|
||||
<GrantTypeComponentMap collection={collection} folder={folder} />
|
||||
<GrantTypeComponentMap collection={collection} folder={folder} updateFolderAuth={updateFolderAuth} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { saveRequest, saveCollectionSettings, saveFolderRoot } from '../../slices/collections/actions';
|
||||
import { saveRequest, saveCollectionSettings, saveFolderRoot, saveEnvironment } from '../../slices/collections/actions';
|
||||
import { saveGlobalEnvironment } from '../../slices/global-environments';
|
||||
import { flattenItems, isItemARequest, isItemAFolder } from 'utils/collections';
|
||||
|
||||
const actionsToIntercept = [
|
||||
@@ -85,7 +86,11 @@ const actionsToIntercept = [
|
||||
'collections/updateCollectionDocs',
|
||||
'collections/updateCollectionClientCertificates',
|
||||
'collections/updateCollectionProtobuf',
|
||||
'collections/updateCollectionProxy'
|
||||
'collections/updateCollectionProxy',
|
||||
|
||||
// Environment draft actions
|
||||
'collections/setEnvironmentsDraft',
|
||||
'globalEnvironments/setGlobalEnvironmentDraft'
|
||||
];
|
||||
|
||||
// Simple object to track pending save timers
|
||||
@@ -105,7 +110,8 @@ const scheduleAutoSave = (key, save, interval) => {
|
||||
|
||||
// Helper to find and schedule saves for all existing drafts
|
||||
const saveExistingDrafts = (dispatch, getState, interval) => {
|
||||
const collections = getState().collections.collections;
|
||||
const state = getState();
|
||||
const collections = state.collections.collections;
|
||||
|
||||
collections.forEach((collection) => {
|
||||
// Check collection-level draft
|
||||
@@ -114,6 +120,15 @@ const saveExistingDrafts = (dispatch, getState, interval) => {
|
||||
scheduleAutoSave(key, () => dispatch(saveCollectionSettings(collection.uid, null, true)), interval);
|
||||
}
|
||||
|
||||
// Check collection environment drafts
|
||||
if (collection.environmentsDraft) {
|
||||
const { environmentUid, variables } = collection.environmentsDraft;
|
||||
if (environmentUid && variables) {
|
||||
const key = `environment-${collection.uid}-${environmentUid}`;
|
||||
scheduleAutoSave(key, () => dispatch(saveEnvironment(variables, environmentUid, collection.uid)), interval);
|
||||
}
|
||||
}
|
||||
|
||||
// Check all items (requests and folders) for drafts
|
||||
const allItems = flattenItems(collection.items);
|
||||
allItems.forEach((item) => {
|
||||
@@ -128,6 +143,77 @@ const saveExistingDrafts = (dispatch, getState, interval) => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Check global environment drafts
|
||||
const globalEnvironmentDraft = state.globalEnvironments?.globalEnvironmentDraft;
|
||||
if (globalEnvironmentDraft) {
|
||||
const { environmentUid, variables } = globalEnvironmentDraft;
|
||||
if (environmentUid && variables) {
|
||||
const key = `global-environment-${environmentUid}`;
|
||||
scheduleAutoSave(key, () => dispatch(saveGlobalEnvironment({ variables, environmentUid })), interval);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Helper to determine entity type and create save handler
|
||||
const determineSaveHandler = (actionType, payload, dispatch, getState) => {
|
||||
const { itemUid, folderUid, collectionUid, environmentUid } = payload;
|
||||
|
||||
// Handle environment drafts
|
||||
if (actionType === 'collections/setEnvironmentsDraft') {
|
||||
if (!environmentUid || !collectionUid) return null;
|
||||
return {
|
||||
key: `environment-${collectionUid}-${environmentUid}`,
|
||||
save: () => {
|
||||
const state = getState();
|
||||
const collection = state.collections.collections.find((c) => c.uid === collectionUid);
|
||||
const draft = collection?.environmentsDraft;
|
||||
if (draft?.environmentUid === environmentUid && draft?.variables) {
|
||||
dispatch(saveEnvironment(draft.variables, environmentUid, collectionUid));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (actionType === 'globalEnvironments/setGlobalEnvironmentDraft') {
|
||||
if (!environmentUid) return null;
|
||||
return {
|
||||
key: `global-environment-${environmentUid}`,
|
||||
save: () => {
|
||||
const state = getState();
|
||||
const draft = state.globalEnvironments?.globalEnvironmentDraft;
|
||||
if (draft?.environmentUid === environmentUid && draft?.variables) {
|
||||
dispatch(saveGlobalEnvironment({ variables: draft.variables, environmentUid }));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Handle folder actions
|
||||
if (folderUid) {
|
||||
return {
|
||||
key: `folder-${folderUid}`,
|
||||
save: () => dispatch(saveFolderRoot(collectionUid, folderUid, true))
|
||||
};
|
||||
}
|
||||
|
||||
// Handle request actions
|
||||
if (itemUid) {
|
||||
return {
|
||||
key: `request-${itemUid}`,
|
||||
save: () => dispatch(saveRequest(itemUid, collectionUid, true))
|
||||
};
|
||||
}
|
||||
|
||||
// Handle collection-level changes
|
||||
if (collectionUid) {
|
||||
return {
|
||||
key: `collection-${collectionUid}`,
|
||||
save: () => dispatch(saveCollectionSettings(collectionUid, null, true))
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export const autosaveMiddleware = ({ dispatch, getState }) => (next) => (action) => {
|
||||
@@ -155,28 +241,9 @@ export const autosaveMiddleware = ({ dispatch, getState }) => (next) => (action)
|
||||
// Only handle actions that create dirty state
|
||||
if (!actionsToIntercept.includes(action.type)) return result;
|
||||
|
||||
const { itemUid, folderUid, collectionUid } = action.payload;
|
||||
const interval = autoSave.interval;
|
||||
|
||||
// Determine what to save based on what IDs are present
|
||||
let key, save;
|
||||
|
||||
if (itemUid) {
|
||||
// Request change
|
||||
key = `request-${itemUid}`;
|
||||
save = () => dispatch(saveRequest(itemUid, collectionUid, true));
|
||||
} else if (folderUid) {
|
||||
// Folder change
|
||||
key = `folder-${folderUid}`;
|
||||
save = () => dispatch(saveFolderRoot(collectionUid, folderUid, true));
|
||||
} else if (collectionUid) {
|
||||
// Collection change
|
||||
key = `collection-${collectionUid}`;
|
||||
save = () => dispatch(saveCollectionSettings(collectionUid, null, true));
|
||||
}
|
||||
|
||||
if (key && save) {
|
||||
scheduleAutoSave(key, save, interval);
|
||||
const handler = determineSaveHandler(action.type, action.payload, dispatch, getState);
|
||||
if (handler) {
|
||||
scheduleAutoSave(handler.key, handler.save, autoSave.interval);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -2338,7 +2338,7 @@ export const collectionsSlice = createSlice({
|
||||
const collection = findCollectionByUid(state.collections, action.payload.collectionUid);
|
||||
if (!collection) return;
|
||||
|
||||
const folder = collection ? findItemInCollection(collection, action.payload.itemUid) : null;
|
||||
const folder = collection ? findItemInCollection(collection, action.payload.folderUid) : null;
|
||||
if (!folder) return;
|
||||
|
||||
if (folder) {
|
||||
|
||||
Reference in New Issue
Block a user