feat(#589): polish importing postman env

This commit is contained in:
Anoop M D 2023-10-16 03:13:06 +05:30
parent 6c92ad22ef
commit 1f8c4431e0
8 changed files with 93 additions and 97 deletions

View File

@ -1,6 +1,6 @@
import React, { useEffect, useRef } from 'react'; import React, { useEffect, useRef } from 'react';
import Portal from 'components/Portal/index'; import Portal from 'components/Portal';
import Modal from 'components/Modal/index'; import Modal from 'components/Modal';
import toast from 'react-hot-toast'; import toast from 'react-hot-toast';
import { useFormik } from 'formik'; import { useFormik } from 'formik';
import { addEnvironment } from 'providers/ReduxStore/slices/collections/actions'; import { addEnvironment } from 'providers/ReduxStore/slices/collections/actions';

View File

@ -10,6 +10,7 @@ const StyledWrapper = styled.div`
background-color: ${(props) => props.theme.collection.environment.settings.sidebar.bg}; background-color: ${(props) => props.theme.collection.environment.settings.sidebar.bg};
border-right: solid 1px ${(props) => props.theme.collection.environment.settings.sidebar.borderRight}; border-right: solid 1px ${(props) => props.theme.collection.environment.settings.sidebar.borderRight};
min-height: 400px; min-height: 400px;
height: 100%;
} }
.environment-item { .environment-item {
@ -35,7 +36,8 @@ const StyledWrapper = styled.div`
} }
} }
.btn-create-environment { .btn-create-environment,
.btn-import-environment {
padding: 8px 10px; padding: 8px 10px;
cursor: pointer; cursor: pointer;
border-bottom: none; border-bottom: none;
@ -47,6 +49,10 @@ const StyledWrapper = styled.div`
} }
} }
} }
.btn-import-environment {
color: ${(props) => props.theme.colors.text.muted};
}
`; `;
export default StyledWrapper; export default StyledWrapper;

View File

@ -1,15 +1,19 @@
import React, { useEffect, useState, forwardRef, useRef } from 'react'; import React, { useEffect, useState, forwardRef, useRef } from 'react';
import { findEnvironmentInCollection } from 'utils/collections'; import { findEnvironmentInCollection } from 'utils/collections';
import toast from 'react-hot-toast';
import { toastError } from 'utils/common/error';
import usePrevious from 'hooks/usePrevious'; import usePrevious from 'hooks/usePrevious';
import EnvironmentDetails from './EnvironmentDetails'; import EnvironmentDetails from './EnvironmentDetails';
import CreateEnvironment from '../CreateEnvironment/index'; import CreateEnvironment from '../CreateEnvironment';
import { IconUpload } from '@tabler/icons';
import ImportEnvironment from '../ImportEnvironment';
import StyledWrapper from './StyledWrapper'; import StyledWrapper from './StyledWrapper';
import ImportEnvironment from "components/Environments/EnvironmentSettings/ImportEnvironment";
const EnvironmentList = ({ collection }) => { const EnvironmentList = ({ collection }) => {
const { environments } = collection; const { environments } = collection;
const [selectedEnvironment, setSelectedEnvironment] = useState(null); const [selectedEnvironment, setSelectedEnvironment] = useState(null);
const [openCreateModal, setOpenCreateModal] = useState(false); const [openCreateModal, setOpenCreateModal] = useState(false);
const [openImportModal, setOpenImportModal] = useState(false);
const envUids = environments ? environments.map((env) => env.uid) : []; const envUids = environments ? environments.map((env) => env.uid) : [];
const prevEnvUids = usePrevious(envUids); const prevEnvUids = usePrevious(envUids);
@ -49,9 +53,10 @@ const EnvironmentList = ({ collection }) => {
return ( return (
<StyledWrapper> <StyledWrapper>
{openCreateModal && <CreateEnvironment collection={collection} onClose={() => setOpenCreateModal(false)} />} {openCreateModal && <CreateEnvironment collection={collection} onClose={() => setOpenCreateModal(false)} />}
{openImportModal && <ImportEnvironment collection={collection} onClose={() => setOpenImportModal(false)} />}
<div className="flex"> <div className="flex">
<div> <div>
<div className="environments-sidebar"> <div className="environments-sidebar flex flex-col">
{environments && {environments &&
environments.length && environments.length &&
environments.map((env) => ( environments.map((env) => (
@ -66,7 +71,11 @@ const EnvironmentList = ({ collection }) => {
<div className="btn-create-environment" onClick={() => setOpenCreateModal(true)}> <div className="btn-create-environment" onClick={() => setOpenCreateModal(true)}>
+ <span>Create</span> + <span>Create</span>
</div> </div>
<ImportEnvironment title={"Import"} collectionUid={collection.uid}/>
<div className="mt-auto flex items-center btn-import-environment" onClick={() => setOpenImportModal(true)}>
<IconUpload size={12} strokeWidth={2} />
<span className="label ml-1 text-xs">Import</span>
</div>
</div> </div>
</div> </div>
<EnvironmentDetails environment={selectedEnvironment} collection={collection} /> <EnvironmentDetails environment={selectedEnvironment} collection={collection} />

View File

@ -1,33 +1,39 @@
import toast from "react-hot-toast"; import React from 'react';
import {toastError} from "utils/common/error"; import Portal from 'components/Portal';
import {useDispatch} from "react-redux"; import toast from 'react-hot-toast';
import {importEnvironment} from "providers/ReduxStore/slices/collections/actions"; import { useDispatch } from 'react-redux';
import importPostmanEnvironment from "utils/importers/postman-environment"; import importPostmanEnvironment from 'utils/importers/postman-environment';
import React from "react"; import { importEnvironment } from 'providers/ReduxStore/slices/collections/actions';
import { toastError } from 'utils/common/error';
import Modal from 'components/Modal';
const ImportEnvironment = ({title, collectionUid}) => { const ImportEnvironment = ({ onClose, collection }) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const handleImportPostmanEnvironment = () => { const handleImportPostmanEnvironment = () => {
importPostmanEnvironment() importPostmanEnvironment()
.then((environment) => { .then((environment) => {
dispatch(importEnvironment(environment.name, environment.variables, collectionUid)) dispatch(importEnvironment(environment.name, environment.variables, collection.uid))
.then(() => { .then(() => {
toast.success('Environment imported successfully'); toast.success('Environment imported successfully');
}) onClose();
.catch(() => toast.error('An error occurred while importing the environment')); })
}) .catch(() => toast.error('An error occurred while importing the environment'));
.catch((err) => toastError(err, 'Postman Import environment failed')); })
}; .catch((err) => toastError(err, 'Postman Import environment failed'));
};
return( return (
<button <Portal>
className="btn-create-environment text-link pr-2 py-2 mt-2 select-none" <Modal size="sm" title="Import Environment" hideFooter={true} handleConfirm={onClose} handleCancel={onClose}>
onClick={handleImportPostmanEnvironment} <div>
> <div className="text-link hover:underline cursor-pointer" onClick={handleImportPostmanEnvironment}>
+ <span>{title}</span> Postman Environment
</button> </div>
); </div>
</Modal>
</Portal>
);
}; };
export default ImportEnvironment; export default ImportEnvironment;

View File

@ -3,11 +3,12 @@ import React, { useState } from 'react';
import CreateEnvironment from './CreateEnvironment'; import CreateEnvironment from './CreateEnvironment';
import EnvironmentList from './EnvironmentList'; import EnvironmentList from './EnvironmentList';
import StyledWrapper from './StyledWrapper'; import StyledWrapper from './StyledWrapper';
import ImportEnvironment from "components/Environments/EnvironmentSettings/ImportEnvironment"; import ImportEnvironment from './ImportEnvironment';
const EnvironmentSettings = ({ collection, onClose }) => { const EnvironmentSettings = ({ collection, onClose }) => {
const { environments } = collection; const { environments } = collection;
const [openCreateModal, setOpenCreateModal] = useState(false); const [openCreateModal, setOpenCreateModal] = useState(false);
const [openImportModal, setOpenImportModal] = useState(false);
if (!environments || !environments.length) { if (!environments || !environments.length) {
return ( return (
@ -21,15 +22,24 @@ const EnvironmentSettings = ({ collection, onClose }) => {
hideCancel={true} hideCancel={true}
> >
{openCreateModal && <CreateEnvironment collection={collection} onClose={() => setOpenCreateModal(false)} />} {openCreateModal && <CreateEnvironment collection={collection} onClose={() => setOpenCreateModal(false)} />}
<div className="text-center"> {openImportModal && <ImportEnvironment collection={collection} onClose={() => setOpenImportModal(false)} />}
<div className="text-center flex flex-col">
<p>No environments found!</p> <p>No environments found!</p>
<button <button
className="btn-create-environment text-link pr-2 py-3 mt-2 select-none" className="btn-create-environment text-link pr-2 py-3 mt-2 select-none"
onClick={() => setOpenCreateModal(true)} onClick={() => setOpenCreateModal(true)}
> >
+ <span>Create Environment</span> <span>Create Environment</span>
</button>
<span>Or</span>
<button
className="btn-import-environment text-link pl-2 pr-2 py-3 select-none"
onClick={() => setOpenImportModal(true)}
>
<span>Import Environment</span>
</button> </button>
<ImportEnvironment title={"Import Postman Environment"} collectionUid={collection.uid}/>
</div> </div>
</Modal> </Modal>
</StyledWrapper> </StyledWrapper>

View File

@ -9,6 +9,7 @@ const StyledWrapper = styled.div`
background-color: ${(props) => props.theme.collection.environment.settings.sidebar.bg}; background-color: ${(props) => props.theme.collection.environment.settings.sidebar.bg};
border-right: solid 1px ${(props) => props.theme.collection.environment.settings.sidebar.borderRight}; border-right: solid 1px ${(props) => props.theme.collection.environment.settings.sidebar.borderRight};
min-height: 400px; min-height: 400px;
height: 100%;
} }
.generate-code-item { .generate-code-item {

View File

@ -731,20 +731,20 @@ export const importEnvironment = (name, variables, collectionUid) => (dispatch,
} }
ipcRenderer ipcRenderer
.invoke('renderer:import-environment', collection.pathname, name, variables) .invoke('renderer:create-environment', collection.pathname, name, variables)
.then( .then(
dispatch( dispatch(
updateLastAction({ updateLastAction({
collectionUid, collectionUid,
lastAction: { lastAction: {
type: 'ADD_ENVIRONMENT', type: 'ADD_ENVIRONMENT',
payload: name payload: name
} }
}) })
)
) )
.then(resolve) )
.catch(reject); .then(resolve)
.catch(reject);
}); });
}; };
@ -762,7 +762,7 @@ export const copyEnvironment = (name, baseEnvUid, collectionUid) => (dispatch, g
} }
ipcRenderer ipcRenderer
.invoke('renderer:copy-environment', collection.pathname, name, baseEnv.variables) .invoke('renderer:create-environment', collection.pathname, name, baseEnv.variables)
.then( .then(
dispatch( dispatch(
updateLastAction({ updateLastAction({

View File

@ -140,7 +140,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
}); });
// create environment // create environment
ipcMain.handle('renderer:create-environment', async (event, collectionPathname, name) => { ipcMain.handle('renderer:create-environment', async (event, collectionPathname, name, variables) => {
try { try {
const envDirPath = path.join(collectionPathname, 'environments'); const envDirPath = path.join(collectionPathname, 'environments');
if (!fs.existsSync(envDirPath)) { if (!fs.existsSync(envDirPath)) {
@ -152,53 +152,17 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
throw new Error(`environment: ${envFilePath} already exists`); throw new Error(`environment: ${envFilePath} already exists`);
} }
const content = envJsonToBru({ const environment = {
variables: [] name: name,
}); variables: variables || []
await writeFile(envFilePath, content); };
} catch (error) {
return Promise.reject(error);
}
});
// copy environment if (envHasSecrets(environment)) {
ipcMain.handle('renderer:copy-environment', async (event, collectionPathname, name, baseVariables) => { environmentSecretsStore.storeEnvSecrets(collectionPathname, environment);
try {
const envDirPath = path.join(collectionPathname, 'environments');
if (!fs.existsSync(envDirPath)) {
await createDirectory(envDirPath);
} }
const envFilePath = path.join(envDirPath, `${name}.bru`); const content = envJsonToBru(environment);
if (fs.existsSync(envFilePath)) {
throw new Error(`environment: ${envFilePath} already exists`);
}
const content = envJsonToBru({
variables: baseVariables
});
await writeFile(envFilePath, content);
} catch (error) {
return Promise.reject(error);
}
});
// copy environment
ipcMain.handle('renderer:import-environment', async (event, collectionPathname, name, variables) => {
try {
const envDirPath = path.join(collectionPathname, 'environments');
if (!fs.existsSync(envDirPath)) {
await createDirectory(envDirPath);
}
const envFilePath = path.join(envDirPath, `${name}.bru`);
if (fs.existsSync(envFilePath)) {
throw new Error(`environment: ${envFilePath} already exists`);
}
const content = envJsonToBru({
variables: variables
});
await writeFile(envFilePath, content); await writeFile(envFilePath, content);
} catch (error) { } catch (error) {
return Promise.reject(error); return Promise.reject(error);