forked from usebruno/bruno
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request usebruno#3222 from lohxt1/feat/global-environments
feat: global env
- Loading branch information
Showing
43 changed files
with
1,705 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
packages/bruno-app/src/components/GlobalEnvironments/EnvironmentSelector/StyledWrapper.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import styled from 'styled-components'; | ||
|
||
const Wrapper = styled.div` | ||
.current-environment { | ||
} | ||
.environment-active { | ||
padding: 0.3rem 0.4rem; | ||
color: ${(props) => props.theme.colors.text.yellow}; | ||
border: solid 1px ${(props) => props.theme.colors.text.yellow} !important; | ||
} | ||
.environment-selector { | ||
.active: { | ||
color: ${(props) => props.theme.colors.text.yellow}; | ||
} | ||
} | ||
`; | ||
|
||
export default Wrapper; |
94 changes: 94 additions & 0 deletions
94
packages/bruno-app/src/components/GlobalEnvironments/EnvironmentSelector/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import React, { useRef, forwardRef, useState } from 'react'; | ||
import find from 'lodash/find'; | ||
import Dropdown from 'components/Dropdown'; | ||
import { IconSettings, IconWorld, IconDatabase, IconDatabaseOff, IconCheck } from '@tabler/icons'; | ||
import EnvironmentSettings from '../EnvironmentSettings'; | ||
import toast from 'react-hot-toast'; | ||
import { useDispatch, useSelector } from 'react-redux'; | ||
import StyledWrapper from './StyledWrapper'; | ||
import { selectGlobalEnvironment } from 'providers/ReduxStore/slices/global-environments'; | ||
|
||
const EnvironmentSelector = () => { | ||
const dispatch = useDispatch(); | ||
const dropdownTippyRef = useRef(); | ||
const globalEnvironments = useSelector((state) => state.globalEnvironments.globalEnvironments); | ||
const activeGlobalEnvironmentUid = useSelector((state) => state.globalEnvironments.activeGlobalEnvironmentUid); | ||
const [openSettingsModal, setOpenSettingsModal] = useState(false); | ||
const activeEnvironment = activeGlobalEnvironmentUid ? find(globalEnvironments, (e) => e.uid === activeGlobalEnvironmentUid) : null; | ||
|
||
const Icon = forwardRef((props, ref) => { | ||
return ( | ||
<div ref={ref} className={`current-environment flex flex-row gap-1 rounded-xl text-xs cursor-pointer items-center justify-center select-none ${activeGlobalEnvironmentUid? 'environment-active': ''}`}> | ||
<IconWorld className="globe" size={16} strokeWidth={1.5} /> | ||
{ | ||
activeEnvironment ? <div>{activeEnvironment?.name}</div> : null | ||
} | ||
</div> | ||
); | ||
}); | ||
|
||
const handleSettingsIconClick = () => { | ||
setOpenSettingsModal(true); | ||
}; | ||
|
||
const handleModalClose = () => { | ||
setOpenSettingsModal(false); | ||
}; | ||
|
||
const onDropdownCreate = (ref) => (dropdownTippyRef.current = ref); | ||
|
||
const onSelect = (environment) => { | ||
dispatch(selectGlobalEnvironment({ environmentUid: environment ? environment.uid : null })) | ||
.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 occurred while selecting the environment')); | ||
}; | ||
|
||
return ( | ||
<StyledWrapper> | ||
<div className="flex items-center cursor-pointer environment-selector mr-3"> | ||
<Dropdown onCreate={onDropdownCreate} icon={<Icon />} placement="bottom-end" transparent={true}> | ||
<div className="label-item font-medium">Global Environments</div> | ||
{globalEnvironments && globalEnvironments.length | ||
? globalEnvironments.map((e) => ( | ||
<div | ||
className={`dropdown-item ${e?.uid === activeGlobalEnvironmentUid ? 'active' : ''}`} | ||
key={e.uid} | ||
onClick={() => { | ||
onSelect(e); | ||
dropdownTippyRef.current.hide(); | ||
}} | ||
> | ||
<IconDatabase size={18} strokeWidth={1.5} /> <span className="ml-2 break-all">{e.name}</span> | ||
</div> | ||
)) | ||
: null} | ||
<div | ||
className="dropdown-item" | ||
onClick={() => { | ||
dropdownTippyRef.current.hide(); | ||
onSelect(null); | ||
}} | ||
> | ||
<IconDatabaseOff size={18} strokeWidth={1.5} /> | ||
<span className="ml-2">No Environment</span> | ||
</div> | ||
<div className="dropdown-item border-top" onClick={handleSettingsIconClick}> | ||
<div className="pr-2 text-gray-600"> | ||
<IconSettings size={18} strokeWidth={1.5} /> | ||
</div> | ||
<span>Configure</span> | ||
</div> | ||
</Dropdown> | ||
</div> | ||
{openSettingsModal && <EnvironmentSettings globalEnvironments={globalEnvironments} activeGlobalEnvironmentUid={activeGlobalEnvironmentUid} onClose={handleModalClose} />} | ||
</StyledWrapper> | ||
); | ||
}; | ||
|
||
export default EnvironmentSelector; |
78 changes: 78 additions & 0 deletions
78
.../bruno-app/src/components/GlobalEnvironments/EnvironmentSettings/CopyEnvironment/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import Modal from 'components/Modal/index'; | ||
import Portal from 'components/Portal/index'; | ||
import { useFormik } from 'formik'; | ||
import { copyGlobalEnvironment } from 'providers/ReduxStore/slices/global-environments'; | ||
import { useEffect, useRef } from 'react'; | ||
import toast from 'react-hot-toast'; | ||
import { useDispatch } from 'react-redux'; | ||
import * as Yup from 'yup'; | ||
|
||
const CopyEnvironment = ({ environment, onClose }) => { | ||
const dispatch = useDispatch(); | ||
const inputRef = useRef(); | ||
const formik = useFormik({ | ||
enableReinitialize: true, | ||
initialValues: { | ||
name: environment.name + ' - Copy' | ||
}, | ||
validationSchema: Yup.object({ | ||
name: Yup.string() | ||
.min(1, 'must be at least 1 character') | ||
.max(50, 'must be 50 characters or less') | ||
.required('name is required') | ||
}), | ||
onSubmit: (values) => { | ||
dispatch(copyGlobalEnvironment({ name: values.name, environmentUid: environment.uid })) | ||
.then(() => { | ||
toast.success('Global environment created!'); | ||
onClose(); | ||
}) | ||
.catch((error) => { | ||
toast.error('An error occurred while created the environment'); | ||
console.error(error); | ||
}); | ||
} | ||
}); | ||
|
||
useEffect(() => { | ||
if (inputRef && inputRef.current) { | ||
inputRef.current.focus(); | ||
} | ||
}, [inputRef]); | ||
|
||
const onSubmit = () => { | ||
formik.handleSubmit(); | ||
}; | ||
|
||
return ( | ||
<Portal> | ||
<Modal size="sm" title={'Copy Global Environment'} confirmText="Copy" handleConfirm={onSubmit} handleCancel={onClose}> | ||
<form className="bruno-form" onSubmit={e => e.preventDefault()}> | ||
<div> | ||
<label htmlFor="name" className="block font-semibold"> | ||
New Environment Name | ||
</label> | ||
<input | ||
id="environment-name" | ||
type="text" | ||
name="name" | ||
ref={inputRef} | ||
className="block textbox mt-2 w-full" | ||
autoComplete="off" | ||
autoCorrect="off" | ||
autoCapitalize="off" | ||
spellCheck="false" | ||
onChange={formik.handleChange} | ||
value={formik.values.name || ''} | ||
/> | ||
{formik.touched.name && formik.errors.name ? ( | ||
<div className="text-red-500">{formik.errors.name}</div> | ||
) : null} | ||
</div> | ||
</form> | ||
</Modal> | ||
</Portal> | ||
); | ||
}; | ||
|
||
export default CopyEnvironment; |
83 changes: 83 additions & 0 deletions
83
...runo-app/src/components/GlobalEnvironments/EnvironmentSettings/CreateEnvironment/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import React, { useEffect, useRef } from 'react'; | ||
import toast from 'react-hot-toast'; | ||
import { useFormik } from 'formik'; | ||
import * as Yup from 'yup'; | ||
import { useDispatch } from 'react-redux'; | ||
import Portal from 'components/Portal'; | ||
import Modal from 'components/Modal'; | ||
import { addGlobalEnvironment } from 'providers/ReduxStore/slices/global-environments'; | ||
|
||
const CreateEnvironment = ({ onClose }) => { | ||
const dispatch = useDispatch(); | ||
const inputRef = useRef(); | ||
const formik = useFormik({ | ||
enableReinitialize: true, | ||
initialValues: { | ||
name: '' | ||
}, | ||
validationSchema: Yup.object({ | ||
name: Yup.string() | ||
.min(1, 'must be at least 1 character') | ||
.max(50, 'must be 50 characters or less') | ||
.required('name is required') | ||
}), | ||
onSubmit: (values) => { | ||
dispatch(addGlobalEnvironment({ name: values.name })) | ||
.then(() => { | ||
toast.success('Global environment created!'); | ||
onClose(); | ||
}) | ||
.catch(() => toast.error('An error occurred while creating the environment')); | ||
} | ||
}); | ||
|
||
useEffect(() => { | ||
if (inputRef && inputRef.current) { | ||
inputRef.current.focus(); | ||
} | ||
}, [inputRef]); | ||
|
||
const onSubmit = () => { | ||
formik.handleSubmit(); | ||
}; | ||
|
||
return ( | ||
<Portal> | ||
<Modal | ||
size="sm" | ||
title={'Create Global Environment'} | ||
confirmText="Create" | ||
handleConfirm={onSubmit} | ||
handleCancel={onClose} | ||
> | ||
<form className="bruno-form" onSubmit={e => e.preventDefault()}> | ||
<div> | ||
<label htmlFor="name" className="block font-semibold"> | ||
Environment Name | ||
</label> | ||
<div className="flex items-center mt-2"> | ||
<input | ||
id="environment-name" | ||
type="text" | ||
name="name" | ||
ref={inputRef} | ||
className="block textbox w-full" | ||
autoComplete="off" | ||
autoCorrect="off" | ||
autoCapitalize="off" | ||
spellCheck="false" | ||
onChange={formik.handleChange} | ||
value={formik.values.name || ''} | ||
/> | ||
</div> | ||
{formik.touched.name && formik.errors.name ? ( | ||
<div className="text-red-500">{formik.errors.name}</div> | ||
) : null} | ||
</div> | ||
</form> | ||
</Modal> | ||
</Portal> | ||
); | ||
}; | ||
|
||
export default CreateEnvironment; |
15 changes: 15 additions & 0 deletions
15
.../src/components/GlobalEnvironments/EnvironmentSettings/DeleteEnvironment/StyledWrapper.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import styled from 'styled-components'; | ||
|
||
const Wrapper = styled.div` | ||
button.submit { | ||
color: white; | ||
background-color: var(--color-background-danger) !important; | ||
border: inherit !important; | ||
&:hover { | ||
border: inherit !important; | ||
} | ||
} | ||
`; | ||
|
||
export default Wrapper; |
37 changes: 37 additions & 0 deletions
37
...runo-app/src/components/GlobalEnvironments/EnvironmentSettings/DeleteEnvironment/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import React from 'react'; | ||
import Portal from 'components/Portal/index'; | ||
import toast from 'react-hot-toast'; | ||
import Modal from 'components/Modal/index'; | ||
import { useDispatch } from 'react-redux'; | ||
import StyledWrapper from './StyledWrapper'; | ||
import { deleteGlobalEnvironment } from 'providers/ReduxStore/slices/global-environments'; | ||
|
||
const DeleteEnvironment = ({ onClose, environment }) => { | ||
const dispatch = useDispatch(); | ||
const onConfirm = () => { | ||
dispatch(deleteGlobalEnvironment({ environmentUid: environment.uid })) | ||
.then(() => { | ||
toast.success('Global Environment deleted successfully'); | ||
onClose(); | ||
}) | ||
.catch(() => toast.error('An error occurred while deleting the environment')); | ||
}; | ||
|
||
return ( | ||
<Portal> | ||
<StyledWrapper> | ||
<Modal | ||
size="sm" | ||
title={'Delete Global Environment'} | ||
confirmText="Delete" | ||
handleConfirm={onConfirm} | ||
handleCancel={onClose} | ||
> | ||
Are you sure you want to delete <span className="font-semibold">{environment.name}</span> ? | ||
</Modal> | ||
</StyledWrapper> | ||
</Portal> | ||
); | ||
}; | ||
|
||
export default DeleteEnvironment; |
Oops, something went wrong.