mirror of
https://github.com/usebruno/bruno.git
synced 2024-12-22 23:02:40 +01:00
feat: persist selected environment inside collection
This commit is contained in:
parent
ecc2252e84
commit
42a60a3372
@ -1,17 +1,24 @@
|
||||
import React, { useRef, forwardRef, useState } from 'react';
|
||||
import find from 'lodash/find';
|
||||
import Dropdown from 'components/Dropdown';
|
||||
import { IconAdjustmentsHorizontal, IconCaretDown } from '@tabler/icons';
|
||||
import { selectEnvironment } from 'providers/ReduxStore/slices/collections/actions';
|
||||
import { IconSettings, IconCaretDown, IconDatabase } from '@tabler/icons';
|
||||
import EnvironmentSettings from "../EnvironmentSettings";
|
||||
import toast from 'react-hot-toast';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
|
||||
const EnvironmentSelector = ({collection}) => {
|
||||
const dispatch = useDispatch();
|
||||
const dropdownTippyRef = useRef();
|
||||
const [openSettingsModal, setOpenSettingsModal] = useState(false);
|
||||
const { environments, activeEnvironmentUid } = collection;
|
||||
const activeEnvironment = activeEnvironmentUid ? find(environments, e => e.uid === activeEnvironmentUid) : null;
|
||||
|
||||
const Icon = forwardRef((props, ref) => {
|
||||
return (
|
||||
<div ref={ref} className="current-enviroment flex items-center justify-center pl-3 pr-2 py-1 select-none">
|
||||
No Environment
|
||||
{activeEnvironment ? activeEnvironment.name : 'No Environment'}
|
||||
<IconCaretDown className="caret" size={14} strokeWidth={2}/>
|
||||
</div>
|
||||
);
|
||||
@ -19,28 +26,39 @@ const EnvironmentSelector = ({collection}) => {
|
||||
|
||||
const onDropdownCreate = (ref) => dropdownTippyRef.current = ref;
|
||||
|
||||
const onSelect = (environment) => {
|
||||
dispatch(selectEnvironment(environment ? environment.uid : null, collection.uid))
|
||||
.then(() => {
|
||||
if(environment) {
|
||||
toast.success(`Environment changed to ${environment.name}`);
|
||||
} else {
|
||||
toast.success(`No Environments are active now`);
|
||||
}
|
||||
})
|
||||
.catch((err) => console.log(err) && toast.error("An error occured while selecting the environment"));
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledWrapper>
|
||||
<div className="flex items-center cursor-pointer environment-selector">
|
||||
<Dropdown onCreate={onDropdownCreate} icon={<Icon />} placement='bottom-end'>
|
||||
{(environments && environments.length) ? environments.map((e) => (
|
||||
<div className="dropdown-item" key={e.uid} onClick={() => {
|
||||
onSelect(e);
|
||||
dropdownTippyRef.current.hide();
|
||||
}}>
|
||||
<IconDatabase size={18} strokeWidth={1.5}/> <span className="ml-2">{e.name}</span>
|
||||
</div>
|
||||
)) : null}
|
||||
<div className="dropdown-item" onClick={() => {
|
||||
dropdownTippyRef.current.hide();
|
||||
}}>
|
||||
<span>QA1</span>
|
||||
</div>
|
||||
<div className="dropdown-item" onClick={() => {
|
||||
dropdownTippyRef.current.hide();
|
||||
}}>
|
||||
<span>STG</span>
|
||||
</div>
|
||||
<div className="dropdown-item" onClick={() => {
|
||||
dropdownTippyRef.current.hide();
|
||||
onSelect(null);
|
||||
}}>
|
||||
<span>No Environment</span>
|
||||
</div>
|
||||
<div className="dropdown-item" style={{borderTop: 'solid 1px #e7e7e7'}} onClick={() => setOpenSettingsModal(true)}>
|
||||
<div className="pr-2 text-gray-600">
|
||||
<IconAdjustmentsHorizontal size={18} strokeWidth={1.5}/>
|
||||
<IconSettings size={18} strokeWidth={1.5}/>
|
||||
</div>
|
||||
<span>Settings</span>
|
||||
</div>
|
||||
|
@ -36,6 +36,7 @@ import {
|
||||
renameEnvironment as _renameEnvironment,
|
||||
deleteEnvironment as _deleteEnvironment,
|
||||
saveEnvironment as _saveEnvironment,
|
||||
selectEnvironment as _selectEnvironment,
|
||||
createCollection as _createCollection,
|
||||
renameCollection as _renameCollection,
|
||||
deleteCollection as _deleteCollection,
|
||||
@ -719,6 +720,34 @@ export const saveEnvironment = (variables, environmentUid, collectionUid) => (di
|
||||
});
|
||||
};
|
||||
|
||||
export const selectEnvironment = (environmentUid, collectionUid) => (dispatch, getState) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const state = getState();
|
||||
const collection = findCollectionByUid(state.collections.collections, collectionUid);
|
||||
if(!collection) {
|
||||
return reject(new Error('Collection not found'));
|
||||
}
|
||||
|
||||
const collectionCopy = cloneDeep(collection);
|
||||
if(environmentUid) {
|
||||
const environment = findEnvironmentInCollection(collectionCopy, environmentUid);
|
||||
if(!environment) {
|
||||
return reject(new Error('Environment not found'));
|
||||
}
|
||||
}
|
||||
|
||||
collectionCopy.activeEnvironmentUid = environmentUid;
|
||||
const collectionToSave = transformCollectionToSaveToIdb(collectionCopy);
|
||||
|
||||
collectionSchema
|
||||
.validate(collectionToSave)
|
||||
.then(() => saveCollectionToIdb(window.__idb, collectionToSave))
|
||||
.then(() => dispatch(_selectEnvironment({environmentUid, collectionUid})))
|
||||
.then(resolve)
|
||||
.catch(reject);
|
||||
});
|
||||
};
|
||||
|
||||
export const removeLocalCollection = (collectionUid) => (dispatch, getState) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const state = getState();
|
||||
|
@ -115,6 +115,22 @@ export const collectionsSlice = createSlice({
|
||||
}
|
||||
}
|
||||
},
|
||||
selectEnvironment: (state, action) => {
|
||||
const { environmentUid, collectionUid } = action.payload;
|
||||
const collection = findCollectionByUid(state.collections, collectionUid);
|
||||
|
||||
if(collection) {
|
||||
if(environmentUid) {
|
||||
const environment = findEnvironmentInCollection(collection, environmentUid);
|
||||
|
||||
if(environment) {
|
||||
collection.activeEnvironmentUid = environmentUid;
|
||||
}
|
||||
} else {
|
||||
collection.activeEnvironmentUid = null;
|
||||
}
|
||||
}
|
||||
},
|
||||
newItem: (state, action) => {
|
||||
const collection = findCollectionByUid(state.collections, action.payload.collectionUid);
|
||||
|
||||
@ -740,6 +756,7 @@ export const {
|
||||
renameEnvironment,
|
||||
deleteEnvironment,
|
||||
saveEnvironment,
|
||||
selectEnvironment,
|
||||
newItem,
|
||||
deleteItem,
|
||||
renameItem,
|
||||
|
@ -237,6 +237,7 @@ export const transformCollectionToSaveToIdb = (collection, options = {}) => {
|
||||
collectionToSave.name = collection.name;
|
||||
collectionToSave.uid = collection.uid;
|
||||
collectionToSave.items = [];
|
||||
collectionToSave.activeEnvironmentUid = collection.activeEnvironmentUid;
|
||||
collectionToSave.environments = collection.environments || [];
|
||||
|
||||
copyItems(collection.items, collectionToSave.items);
|
||||
|
@ -70,6 +70,10 @@ const collectionSchema = Yup.object({
|
||||
.max(50, 'name must be 100 characters or less')
|
||||
.required('name is required'),
|
||||
items: Yup.array().of(itemSchema),
|
||||
activeEnvironmentUid: Yup.string()
|
||||
.length(21, 'activeEnvironmentUid must be 21 characters in length')
|
||||
.matches(/^[a-zA-Z0-9]*$/, 'uid must be alphanumeric')
|
||||
.nullable(),
|
||||
environments: Yup.array().of(environmentSchema),
|
||||
pathname: Yup.string().max(1024, 'pathname cannot be more than 1024 characters').nullable()
|
||||
}).noUnknown(true).strict();
|
||||
|
Loading…
Reference in New Issue
Block a user