Skip to content

Commit

Permalink
associate environment to a color
Browse files Browse the repository at this point in the history
Signed-off-by: mathieu <mathieu.dreano@gmail.com>
  • Loading branch information
MathieuDreano committed Nov 26, 2023
1 parent f0d5cde commit 0bf21d1
Show file tree
Hide file tree
Showing 14 changed files with 298 additions and 105 deletions.
165 changes: 110 additions & 55 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
"@faker-js/faker": "^7.6.0",
"@jest/globals": "^29.2.0",
"@playwright/test": "^1.27.1",
"fs-extra": "^11.1.1",
"husky": "^8.0.3",
"jest": "^29.2.0",
"pretty-quick": "^3.1.3",
"randomstring": "^1.2.2",
"ts-jest": "^29.0.5",
"fs-extra": "^11.1.1"
"react-color": "^2.19.3",
"ts-jest": "^29.0.5"
},
"scripts": {
"dev:web": "npm run dev --workspace=packages/bruno-app",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import styled from 'styled-components';

const Wrapper = styled.div`
.current-enviroment {
.current-environment {
background-color: ${(props) => props.theme.sidebar.badge.bg};
border-radius: 15px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,27 @@ import toast from 'react-hot-toast';
import { useDispatch } from 'react-redux';
import StyledWrapper from './StyledWrapper';

const EnvironmentSelector = ({ collection }) => {
const EnvironmentSelector = (props) => {
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 { activeEnvironmentUid } = props.collection;
const [collection, setCollection] = useState(props.collection);
const setEnvironments = (environments) => {
setCollection({ ...collection, environments: environments });
};

const activeEnvironment = activeEnvironmentUid
? find(collection.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">
<div
ref={ref}
style={{ background: activeEnvironment?.color }}
className="current-environment flex items-center justify-center pl-3 pr-2 py-1 select-none"
>
{activeEnvironment ? activeEnvironment.name : 'No Environment'}
<IconCaretDown className="caret" size={14} strokeWidth={2} />
</div>
Expand All @@ -42,8 +53,8 @@ const EnvironmentSelector = ({ collection }) => {
<StyledWrapper>
<div className="flex items-center cursor-pointer environment-selector">
<Dropdown onCreate={onDropdownCreate} icon={<Icon />} placement="bottom-end">
{environments && environments.length
? environments.map((e) => (
{collection.environments?.length
? collection.environments.map((e) => (
<div
className="dropdown-item"
key={e.uid}
Expand All @@ -52,7 +63,8 @@ const EnvironmentSelector = ({ collection }) => {
dropdownTippyRef.current.hide();
}}
>
<IconDatabase size={18} strokeWidth={1.5} /> <span className="ml-2">{e.name}</span>
<IconDatabase color={e.color} size={18} strokeWidth={1.5} />
<span className="ml-2">{e.name}</span>
</div>
))
: null}
Expand All @@ -74,7 +86,13 @@ const EnvironmentSelector = ({ collection }) => {
</div>
</Dropdown>
</div>
{openSettingsModal && <EnvironmentSettings collection={collection} onClose={() => setOpenSettingsModal(false)} />}
{openSettingsModal && (
<EnvironmentSettings
collection={collection}
setEnvironments={setEnvironments}
onClose={() => setOpenSettingsModal(false)}
/>
)}
</StyledWrapper>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React from 'react';
import { useRef, useEffect } from 'react';
import toast from 'react-hot-toast';
import { useTheme } from 'providers/Theme';
import { useDispatch } from 'react-redux';
import { saveEnvironmentColor } from 'providers/ReduxStore/slices/collections/actions';
import { useFormik } from 'formik';
import * as Yup from 'yup';
import { CirclePicker } from 'react-color';
import { selectEnvironment as _selectEnvironment } from 'providers/ReduxStore/slices/collections';

const EnvironmentColor = ({ environment, onColorChange, collectionUid }) => {
const dispatch = useDispatch();

const formik = useFormik({
enableReinitialize: true,
initialValues: {
color: environment.color || ''
},
validationSchema: Yup.object({
color: Yup.string().optional()
}),
onSubmit: (values) => {
if (!formik.dirty) {
toast.error('Nothing to save');
return;
}
dispatch(saveEnvironmentColor(values.color, environment.uid, collectionUid))
.then(() => {
toast.success('Environment color changed successfully');
onColorChange(values.color);
})
.catch((e) => {
console.log(e);
toast.error('An error occurred while changing the environment color');
});
}
});

useEffect(() => {
if (formik.dirty) {
formik.handleSubmit();
}
}, [formik.values.color]);

return (
<CirclePicker
id="environment-color"
circleSize={12}
circleSpacing={5}
colors={[
'#9c27b0',
'#3f51b5',
'#03a9f4',
'#009688',
'#8bc34a',
'#ffeb3b',
'#ff9800',
'#ff5722',
'#795548',
'#607d8b'
]}
color={environment.color}
onChangeComplete={(color) => formik.setFieldValue('color', color.hex)}
value={formik.values.color || ''}
/>
);
};
export default EnvironmentColor;
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ const EnvironmentVariables = ({ environment, collection }) => {

const ErrorMessage = ({ name }) => {
const meta = formik.getFieldMeta(name);
console.log(name, meta);
if (!meta.error) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ import CopyEnvironment from '../../CopyEnvironment';
import DeleteEnvironment from '../../DeleteEnvironment';
import RenameEnvironment from '../../RenameEnvironment';
import EnvironmentVariables from './EnvironmentVariables';
import EnvironmentColor from '../EnvironmentDetails/EnvironmentColor';

const EnvironmentDetails = ({ environment, collection }) => {
const EnvironmentDetails = ({ environment, onColorChange, collection }) => {
const [openEditModal, setOpenEditModal] = useState(false);
const [openDeleteModal, setOpenDeleteModal] = useState(false);
const [openCopyModal, setOpenCopyModal] = useState(false);

return (
<div className="px-6 flex-grow flex flex-col pt-6" style={{ maxWidth: '700px' }}>
<div
className="px-6 flex-grow flex flex-col pt-6"
style={{ maxWidth: '700px', flexDirection: 'column', rowGap: '0.5em' }}
>
{openEditModal && (
<RenameEnvironment onClose={() => setOpenEditModal(false)} environment={environment} collection={collection} />
)}
Expand All @@ -27,7 +31,7 @@ const EnvironmentDetails = ({ environment, collection }) => {
)}
<div className="flex">
<div className="flex flex-grow items-center">
<IconDatabase className="cursor-pointer" size={20} strokeWidth={1.5} />
<IconDatabase className="cursor-pointer" color={environment.color} size={20} strokeWidth={1.5} />
<span className="ml-1 font-semibold">{environment.name}</span>
</div>
<div className="flex gap-x-4 pl-4">
Expand All @@ -37,9 +41,8 @@ const EnvironmentDetails = ({ environment, collection }) => {
</div>
</div>

<div>
<EnvironmentVariables key={environment.uid} environment={environment} collection={collection} />
</div>
<EnvironmentColor onColorChange={onColorChange} environment={environment} collectionUid={collection.uid} />
<EnvironmentVariables environment={environment} collection={collection} />
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,23 @@ import ImportEnvironment from '../ImportEnvironment';
import ManageSecrets from '../ManageSecrets';
import StyledWrapper from './StyledWrapper';

const EnvironmentList = ({ collection }) => {
const { environments } = collection;
const EnvironmentList = ({ collection, setEnvironments }) => {
const [selectedEnvironment, setSelectedEnvironment] = useState(null);
const [openCreateModal, setOpenCreateModal] = useState(false);
const [openImportModal, setOpenImportModal] = useState(false);
const [openManageSecretsModal, setOpenManageSecretsModal] = useState(false);

const envUids = environments ? environments.map((env) => env.uid) : [];
const envUids = collection?.environments?.map((env) => env.uid) ?? [];
const prevEnvUids = usePrevious(envUids);

const onColorChange = (environment, color) => {
const updatedEnvironments = collection.environments.map((e) =>
e.uid === environment.uid ? { ...e, color: color } : e
);
setSelectedEnvironment({ ...selectedEnvironment, color: color });
setEnvironments(updatedEnvironments);
};

useEffect(() => {
if (selectedEnvironment) {
return;
Expand All @@ -27,24 +34,24 @@ const EnvironmentList = ({ collection }) => {
if (environment) {
setSelectedEnvironment(environment);
} else {
setSelectedEnvironment(environments && environments.length ? environments[0] : null);
setSelectedEnvironment(collection?.environments?.length ? collection.environments[0] : null);
}
}, [collection, environments, selectedEnvironment]);
}, [collection, selectedEnvironment]);

useEffect(() => {
// check env add
if (prevEnvUids && prevEnvUids.length && envUids.length > prevEnvUids.length) {
const newEnv = environments.find((env) => !prevEnvUids.includes(env.uid));
if (prevEnvUids?.length && envUids.length > prevEnvUids.length) {
const newEnv = collection.environments.find((env) => !prevEnvUids.includes(env.uid));
if (newEnv) {
setSelectedEnvironment(newEnv);
}
}

// check env delete
if (prevEnvUids && prevEnvUids.length && envUids.length < prevEnvUids.length) {
setSelectedEnvironment(environments && environments.length ? environments[0] : null);
if (prevEnvUids?.length && envUids.length < prevEnvUids.length) {
setSelectedEnvironment(collection.environments?.length ? collection.environments[0] : null);
}
}, [envUids, environments, prevEnvUids]);
}, [envUids, collection, prevEnvUids]);

if (!selectedEnvironment) {
return null;
Expand All @@ -58,17 +65,15 @@ const EnvironmentList = ({ collection }) => {
<div className="flex">
<div>
<div className="environments-sidebar flex flex-col">
{environments &&
environments.length &&
environments.map((env) => (
<div
key={env.uid}
className={selectedEnvironment.uid === env.uid ? 'environment-item active' : 'environment-item'}
onClick={() => setSelectedEnvironment(env)}
>
<span>{env.name}</span>
</div>
))}
{collection?.environments?.map((env) => (
<div
key={env.uid}
className={selectedEnvironment.uid === env.uid ? 'environment-item active' : 'environment-item'}
onClick={() => setSelectedEnvironment(env)}
>
<span>{env.name}</span>
</div>
))}
<div className="btn-create-environment" onClick={() => setOpenCreateModal(true)}>
+ <span>Create</span>
</div>
Expand All @@ -85,7 +90,11 @@ const EnvironmentList = ({ collection }) => {
</div>
</div>
</div>
<EnvironmentDetails environment={selectedEnvironment} collection={collection} />
<EnvironmentDetails
environment={selectedEnvironment}
onColorChange={(color) => onColorChange(selectedEnvironment, color)}
collection={collection}
/>
</div>
</StyledWrapper>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@ import EnvironmentList from './EnvironmentList';
import StyledWrapper from './StyledWrapper';
import ImportEnvironment from './ImportEnvironment';

const EnvironmentSettings = ({ collection, onClose }) => {
const { environments } = collection;
const EnvironmentSettings = ({ collection, setEnvironments, onClose }) => {
const [openCreateModal, setOpenCreateModal] = useState(false);
const [openImportModal, setOpenImportModal] = useState(false);

if (!environments || !environments.length) {
if (!collection.environments?.length) {
return (
<StyledWrapper>
<Modal
Expand Down Expand Up @@ -48,7 +47,7 @@ const EnvironmentSettings = ({ collection, onClose }) => {

return (
<Modal size="lg" title="Environments" handleCancel={onClose} hideFooter={true}>
<EnvironmentList collection={collection} />
<EnvironmentList collection={collection} setEnvironments={setEnvironments} />
</Modal>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -826,6 +826,29 @@ export const saveEnvironment = (variables, environmentUid, collectionUid) => (di
});
};

export const saveEnvironmentColor = (color, 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);
const environment = findEnvironmentInCollection(collectionCopy, environmentUid);
if (!environment) {
return reject(new Error('Environment not found'));
}

const updatedEnvironment = { ...environment, color: color };
environmentSchema
.validate(updatedEnvironment)
.then(() => ipcRenderer.invoke('renderer:save-environment', collection.pathname, updatedEnvironment))
.then(resolve)
.catch(reject);
});
};

export const selectEnvironment = (environmentUid, collectionUid) => (dispatch, getState) => {
return new Promise((resolve, reject) => {
const state = getState();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,15 @@ export const collectionsSlice = createSlice({
}
},
saveEnvironment: (state, action) => {
const { variables, environmentUid, collectionUid } = action.payload;
const { variables, color, environmentUid, collectionUid } = action.payload;
const collection = findCollectionByUid(state.collections, collectionUid);

if (collection) {
const environment = findEnvironmentInCollection(collection, environmentUid);

if (environment) {
environment.variables = variables;
environment.color = color;
}
}
},
Expand Down
Loading

0 comments on commit 0bf21d1

Please sign in to comment.