mirror of
https://github.com/usebruno/bruno.git
synced 2024-11-07 16:44:27 +01:00
feat: connect environments to redux store
This commit is contained in:
parent
c6ac90a9f8
commit
7ca6270f2b
@ -1,25 +0,0 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { IconEdit, IconTrash } from "@tabler/icons";
|
|
||||||
import RenameEnvironment from "../../RenameEnvironment";
|
|
||||||
import DeleteEnvironment from "../../DeleteEnvironment";
|
|
||||||
// import StyledWrapper from "./StyledWrapper";
|
|
||||||
|
|
||||||
const EnvironmentDetails = ({selected}) => {
|
|
||||||
const [ openEditModal, setOpenEditModal] = useState(false);
|
|
||||||
const [ openDeleteModal, setOpenDeleteModal] = useState(false);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="ml-10 flex-grow flex pt-4" style={{maxWidth: '700px'}}>
|
|
||||||
<span>{selected.name}</span>
|
|
||||||
<div className="flex gap-x-4 pl-4" >
|
|
||||||
<IconEdit className="cursor-pointer" size={20} strokeWidth={1.5} onClick={() => setOpenEditModal(true)}/>
|
|
||||||
<IconTrash className="cursor-pointer" size={20} strokeWidth={1.5} onClick={() => setOpenDeleteModal(true)}/>
|
|
||||||
</div>
|
|
||||||
{openEditModal && <RenameEnvironment onClose={() => setOpenEditModal(false)} environment={selected} />}
|
|
||||||
{openDeleteModal && <DeleteEnvironment onClose={() => setOpenDeleteModal(false)} environment={selected} />}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default EnvironmentDetails;
|
|
@ -1,43 +0,0 @@
|
|||||||
import Modal from "components/Modal/index";
|
|
||||||
import React, { useState } from "react";
|
|
||||||
import CreateEnvironment from "./CreateEnvironment";
|
|
||||||
import Layout from "./Layout";
|
|
||||||
|
|
||||||
const EnvironmentSettings = ({onClose}) => {
|
|
||||||
const environments = [
|
|
||||||
{name: "My env", uid: 123},
|
|
||||||
{name: "hjdgfh dj", uid: 3876},
|
|
||||||
];
|
|
||||||
const [openCreateModal, setOpenCreateModal] = useState(false)
|
|
||||||
|
|
||||||
if(!environments.length) {
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
size="lg"
|
|
||||||
title="Environment"
|
|
||||||
confirmText={"Close"}
|
|
||||||
handleConfirm={onClose}
|
|
||||||
hideCancel={true}
|
|
||||||
>
|
|
||||||
<p>No environment found!</p>
|
|
||||||
<button className="btn-add-param text-link pr-2 py-3 mt-2 select-none" onClick={() => setOpenCreateModal(true)}>+ Create Environment</button>
|
|
||||||
{openCreateModal && <CreateEnvironment onClose={() => setOpenCreateModal(false)}/>}
|
|
||||||
</Modal>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
size="lg"
|
|
||||||
title="Environment"
|
|
||||||
confirmText={"Close"}
|
|
||||||
handleCancel={onClose}
|
|
||||||
hideFooter={true}
|
|
||||||
>
|
|
||||||
<Layout />
|
|
||||||
</Modal>
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export default EnvironmentSettings;
|
|
@ -1,10 +1,10 @@
|
|||||||
import React, { useRef, forwardRef, useState } from 'react';
|
import React, { useRef, forwardRef, useState } from 'react';
|
||||||
import Dropdown from 'components/Dropdown';
|
import Dropdown from 'components/Dropdown';
|
||||||
import { IconAdjustmentsHorizontal, IconCaretDown } from '@tabler/icons';
|
import { IconAdjustmentsHorizontal, IconCaretDown } from '@tabler/icons';
|
||||||
import EnvironmentSettings from "./EnvironmentSettings";
|
import EnvironmentSettings from "../EnvironmentSettings";
|
||||||
import StyledWrapper from './StyledWrapper';
|
import StyledWrapper from './StyledWrapper';
|
||||||
|
|
||||||
const EnvironmentSelector = () => {
|
const EnvironmentSelector = ({collection}) => {
|
||||||
const dropdownTippyRef = useRef();
|
const dropdownTippyRef = useRef();
|
||||||
const [openSettingsModal, setOpenSettingsModal] = useState(false);
|
const [openSettingsModal, setOpenSettingsModal] = useState(false);
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ const EnvironmentSelector = () => {
|
|||||||
</div>
|
</div>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</div>
|
</div>
|
||||||
{openSettingsModal && <EnvironmentSettings onClose={() => setOpenSettingsModal(false)}/>}
|
{openSettingsModal && <EnvironmentSettings collection={collection} onClose={() => setOpenSettingsModal(false)}/>}
|
||||||
</StyledWrapper>
|
</StyledWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
@ -1,12 +1,13 @@
|
|||||||
import React, { useEffect, useRef } from 'react';
|
import React, { useEffect, useRef } from 'react';
|
||||||
import Portal from "components/Portal/index";
|
import Portal from "components/Portal/index";
|
||||||
import Modal from "components/Modal/index";
|
import Modal from "components/Modal/index";
|
||||||
|
import toast from 'react-hot-toast';
|
||||||
import { useFormik } from 'formik';
|
import { useFormik } from 'formik';
|
||||||
import { addWorkspace } from 'providers/ReduxStore/slices/workspaces';
|
import { addEnvironment } from 'providers/ReduxStore/slices/collections/actions';
|
||||||
import * as Yup from 'yup';
|
import * as Yup from 'yup';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
|
|
||||||
const CreateEnvironment = ({onClose}) => {
|
const CreateEnvironment = ({collection, onClose}) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const inputRef = useRef();
|
const inputRef = useRef();
|
||||||
const formik = useFormik({
|
const formik = useFormik({
|
||||||
@ -17,12 +18,16 @@ const CreateEnvironment = ({onClose}) => {
|
|||||||
validationSchema: Yup.object({
|
validationSchema: Yup.object({
|
||||||
name: Yup.string()
|
name: Yup.string()
|
||||||
.min(1, 'must be atleast 1 characters')
|
.min(1, 'must be atleast 1 characters')
|
||||||
.max(30, 'must be 30 characters or less')
|
.max(50, 'must be 50 characters or less')
|
||||||
.required('name is required')
|
.required('name is required')
|
||||||
}),
|
}),
|
||||||
onSubmit: (values) => {
|
onSubmit: (values) => {
|
||||||
// dispatch(addWorkspace({name: values.name}));
|
dispatch(addEnvironment(values.name, collection.uid))
|
||||||
// onClose();
|
.then(() => {
|
||||||
|
toast.success("Environment created in collection");
|
||||||
|
onClose();
|
||||||
|
})
|
||||||
|
.catch(() => toast.error("An error occured while created the environment"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -1,15 +1,20 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Portal from "components/Portal/index";
|
import Portal from "components/Portal/index";
|
||||||
|
import toast from 'react-hot-toast';
|
||||||
import Modal from "components/Modal/index";
|
import Modal from "components/Modal/index";
|
||||||
// import { deleteWorkspace } from 'providers/ReduxStore/slices/workspaces';
|
import { deleteEnvironment } from 'providers/ReduxStore/slices/collections/actions';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import StyledWrapper from './StyledWrapper';
|
import StyledWrapper from './StyledWrapper';
|
||||||
|
|
||||||
const DeleteEnvironment = ({onClose, environment}) => {
|
const DeleteEnvironment = ({onClose, environment, collection}) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const onConfirm = () =>{
|
const onConfirm = () =>{
|
||||||
// dispatch(deleteWorkspace({workspaceUid: workspace.uid}))
|
dispatch(deleteEnvironment(environment.uid, collection.uid))
|
||||||
onClose();
|
.then(() => {
|
||||||
|
toast.success("Environment deleted successfully");
|
||||||
|
onClose();
|
||||||
|
})
|
||||||
|
.catch(() => toast.error("An error occured while deleting the environment"));
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
@ -0,0 +1,26 @@
|
|||||||
|
import React, {useState } from "react";
|
||||||
|
import { IconEdit, IconTrash } from "@tabler/icons";
|
||||||
|
import RenameEnvironment from "../../RenameEnvironment";
|
||||||
|
import DeleteEnvironment from "../../DeleteEnvironment";
|
||||||
|
|
||||||
|
const EnvironmentDetails = ({environment, collection}) => {
|
||||||
|
const [ openEditModal, setOpenEditModal] = useState(false);
|
||||||
|
const [ openDeleteModal, setOpenDeleteModal] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="ml-6 flex-grow flex pt-6" style={{maxWidth: '700px'}}>
|
||||||
|
{openEditModal && <RenameEnvironment onClose={() => setOpenEditModal(false)} environment={environment} collection={collection}/>}
|
||||||
|
{openDeleteModal && <DeleteEnvironment onClose={() => setOpenDeleteModal(false)} environment={environment} collection={collection}/>}
|
||||||
|
<div className="flex flex-grow">
|
||||||
|
<div className="flex-grow font-medium">{environment.name}</div>
|
||||||
|
<div className="flex gap-x-4 pl-4 pr-6">
|
||||||
|
<IconEdit className="cursor-pointer" size={20} strokeWidth={1.5} onClick={() => setOpenEditModal(true)}/>
|
||||||
|
<IconTrash className="cursor-pointer" size={20} strokeWidth={1.5} onClick={() => setOpenDeleteModal(true)}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default EnvironmentDetails;
|
@ -1,12 +1,12 @@
|
|||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
|
|
||||||
const StyledWrapper = styled.div`
|
const StyledWrapper = styled.div`
|
||||||
margin-left: -1rem;
|
margin-inline: -1rem;
|
||||||
margin-block: -1.5rem;
|
margin-block: -1.5rem;
|
||||||
|
|
||||||
.environments-sidebar {
|
.environments-sidebar {
|
||||||
margin-bottom: 8px;
|
background-color: #eaeaea;
|
||||||
background-color: #ffffff;
|
min-height: 400px;
|
||||||
min-height: 300px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.environment-item {
|
.environment-item {
|
||||||
@ -15,28 +15,34 @@ const StyledWrapper = styled.div`
|
|||||||
position: relative;
|
position: relative;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 8px 10px;
|
padding: 8px 10px;
|
||||||
color: rgb(35, 35, 35);
|
border-left: solid 2px transparent;
|
||||||
border-bottom: 1px solid #eaecef;
|
text-decoration: none;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
background-color: #f6f8fa;
|
background-color: #e4e4e4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.active {
|
.active {
|
||||||
background-color: #e1e4e8;
|
background-color: #dcdcdc !important;
|
||||||
|
border-left: solid 2px var(--color-brand);
|
||||||
&:hover {
|
&:hover {
|
||||||
text-decoration: none;
|
background-color: #dcdcdc !important;
|
||||||
background-color: #e1e4e8;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.create-env {
|
.btn-create-environment {
|
||||||
padding: 8px 10px;
|
padding: 8px 10px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
color: var(--color-text-link);
|
color: var(--color-text-link);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
span {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
@ -3,38 +3,43 @@ import EnvironmentDetails from "./EnvironmentDetails";
|
|||||||
import CreateEnvironment from "../CreateEnvironment/index";
|
import CreateEnvironment from "../CreateEnvironment/index";
|
||||||
import StyledWrapper from "./StyledWrapper";
|
import StyledWrapper from "./StyledWrapper";
|
||||||
|
|
||||||
const environments = [
|
const EnvironmentList = ({collection}) => {
|
||||||
{name: "My env", uid: 123},
|
const { environments } = collection;
|
||||||
{name: "hjdgfh dj", uid: 3876},
|
const [selectedEnvironment, setSelectedEnvironment] = useState(null);
|
||||||
{name: "hjdgfer dj", uid: 4678},
|
|
||||||
];
|
|
||||||
|
|
||||||
const Layout = () => {
|
|
||||||
const [selectedEnvironment, setSelectedEnvironment] = useState({});
|
|
||||||
const [openCreateModal, setOpenCreateModal] = useState(false);
|
const [openCreateModal, setOpenCreateModal] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setSelectedEnvironment(environments[0]);
|
setSelectedEnvironment(environments[0]);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
if(!selectedEnvironment) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledWrapper>
|
<StyledWrapper>
|
||||||
|
{openCreateModal && <CreateEnvironment collection={collection} onClose={() => setOpenCreateModal(false)}/>}
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
<div style={{borderRight: "1px solid #ccc"}}>
|
<div>
|
||||||
<div className="environments-sidebar">
|
<div className="environments-sidebar">
|
||||||
{environments && environments.length && environments.map((env) => (
|
{environments && environments.length && environments.map((env) => (
|
||||||
<div className={selectedEnvironment.uid === env.uid ? "environment-item active": "environment-item"} onClick={() => setSelectedEnvironment(env)}>
|
<div
|
||||||
|
key={env.uid}
|
||||||
|
className={selectedEnvironment.uid === env.uid ? "environment-item active": "environment-item"}
|
||||||
|
onClick={() => setSelectedEnvironment(env)}
|
||||||
|
>
|
||||||
<span>{env.name}</span>
|
<span>{env.name}</span>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
<p className="create-env" onClick={() => setOpenCreateModal(true)}> + Create</p>
|
<div className="btn-create-environment" onClick={() => setOpenCreateModal(true)}>
|
||||||
|
+ <span>Create</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<EnvironmentDetails selected={selectedEnvironment}/>
|
<EnvironmentDetails environment={selectedEnvironment} collection={collection}/>
|
||||||
</div>
|
</div>
|
||||||
{openCreateModal && <CreateEnvironment onClose={() => setOpenCreateModal(false)}/>}
|
|
||||||
</StyledWrapper>
|
</StyledWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Layout;
|
export default EnvironmentList;
|
@ -1,13 +1,14 @@
|
|||||||
import React, { useEffect, useRef } from 'react';
|
import React, { useEffect, useRef } from 'react';
|
||||||
import Portal from "components/Portal/index";
|
import Portal from "components/Portal/index";
|
||||||
import Modal from "components/Modal/index";
|
import Modal from "components/Modal/index";
|
||||||
|
import toast from 'react-hot-toast';
|
||||||
import { useFormik } from 'formik';
|
import { useFormik } from 'formik';
|
||||||
// import { rename } from 'providers/ReduxStore/slices/environments';
|
import { renameEnvironment } from 'providers/ReduxStore/slices/collections/actions';
|
||||||
import * as Yup from 'yup';
|
import * as Yup from 'yup';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
|
|
||||||
const RenameEnvironment = ({onClose, environment}) => {
|
const RenameEnvironment = ({onClose, environment, collection}) => {
|
||||||
// const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const inputRef = useRef();
|
const inputRef = useRef();
|
||||||
const formik = useFormik({
|
const formik = useFormik({
|
||||||
enableReinitialize: true,
|
enableReinitialize: true,
|
||||||
@ -17,12 +18,16 @@ const RenameEnvironment = ({onClose, environment}) => {
|
|||||||
validationSchema: Yup.object({
|
validationSchema: Yup.object({
|
||||||
name: Yup.string()
|
name: Yup.string()
|
||||||
.min(1, 'must be atleast 1 characters')
|
.min(1, 'must be atleast 1 characters')
|
||||||
.max(30, 'must be 30 characters or less')
|
.max(50, 'must be 50 characters or less')
|
||||||
.required('name is required')
|
.required('name is required')
|
||||||
}),
|
}),
|
||||||
onSubmit: (values) => {
|
onSubmit: (values) => {
|
||||||
// dispatch(rename({name: values.name, uid: environment.uid}));
|
dispatch(renameEnvironment(values.name, environment.uid, collection.uid))
|
||||||
onClose();
|
.then(() => {
|
||||||
|
toast.success("Environment renamed successfully");
|
||||||
|
onClose();
|
||||||
|
})
|
||||||
|
.catch(() => toast.error("An error occured while renaming the environment"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -0,0 +1,13 @@
|
|||||||
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
const StyledWrapper = styled.div`
|
||||||
|
button.btn-create-environment {
|
||||||
|
&:hover {
|
||||||
|
span {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default StyledWrapper;
|
@ -0,0 +1,50 @@
|
|||||||
|
import Modal from "components/Modal/index";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import CreateEnvironment from "./CreateEnvironment";
|
||||||
|
import EnvironmentList from "./EnvironmentList";
|
||||||
|
import StyledWrapper from "./StyledWrapper";
|
||||||
|
|
||||||
|
const EnvironmentSettings = ({collection, onClose}) => {
|
||||||
|
const { environments } = collection;
|
||||||
|
const [openCreateModal, setOpenCreateModal] = useState(false)
|
||||||
|
|
||||||
|
if(!environments || !environments.length) {
|
||||||
|
return (
|
||||||
|
<StyledWrapper>
|
||||||
|
<Modal
|
||||||
|
size="md"
|
||||||
|
title="Environments"
|
||||||
|
confirmText={"Close"}
|
||||||
|
handleConfirm={onClose}
|
||||||
|
handleCancel={onClose}
|
||||||
|
hideCancel={true}
|
||||||
|
>
|
||||||
|
{openCreateModal && <CreateEnvironment collection={collection} onClose={() => setOpenCreateModal(false)}/>}
|
||||||
|
<div className="text-center">
|
||||||
|
<p>No environments found!</p>
|
||||||
|
<button
|
||||||
|
className="btn-create-environment text-link pr-2 py-3 mt-2 select-none"
|
||||||
|
onClick={() => setOpenCreateModal(true)}
|
||||||
|
>
|
||||||
|
+ <span>Create Environment</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
</StyledWrapper>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
size="lg"
|
||||||
|
title="Environments"
|
||||||
|
handleCancel={onClose}
|
||||||
|
hideFooter={true}
|
||||||
|
>
|
||||||
|
<EnvironmentList collection={collection}/>
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EnvironmentSettings;
|
@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { IconFiles } from '@tabler/icons';
|
import { IconFiles } from '@tabler/icons';
|
||||||
import EnvironmentSelector from 'components/EnvironmentSelector';
|
import EnvironmentSelector from 'components/Environments/EnvironmentSelector';
|
||||||
import StyledWrapper from './StyledWrapper';
|
import StyledWrapper from './StyledWrapper';
|
||||||
|
|
||||||
const CollectionToolBar = ({collection}) => {
|
const CollectionToolBar = ({collection}) => {
|
||||||
@ -12,7 +12,7 @@ const CollectionToolBar = ({collection}) => {
|
|||||||
<span className="ml-2 mr-4 font-semibold">{collection.name}</span>
|
<span className="ml-2 mr-4 font-semibold">{collection.name}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-1 items-center justify-end">
|
<div className="flex flex-1 items-center justify-end">
|
||||||
<EnvironmentSelector />
|
<EnvironmentSelector collection={collection}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</StyledWrapper>
|
</StyledWrapper>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import axios from 'axios';
|
import filter from 'lodash/filter';
|
||||||
import each from 'lodash/each';
|
import each from 'lodash/each';
|
||||||
import trim from 'lodash/trim';
|
import trim from 'lodash/trim';
|
||||||
import toast from 'react-hot-toast';
|
import toast from 'react-hot-toast';
|
||||||
@ -13,6 +13,7 @@ import {
|
|||||||
transformRequestToSaveToFilesystem,
|
transformRequestToSaveToFilesystem,
|
||||||
deleteItemInCollection,
|
deleteItemInCollection,
|
||||||
findParentItemInCollection,
|
findParentItemInCollection,
|
||||||
|
findEnvironmentInCollection,
|
||||||
isItemAFolder,
|
isItemAFolder,
|
||||||
refreshUidsInItem
|
refreshUidsInItem
|
||||||
} from 'utils/collections';
|
} from 'utils/collections';
|
||||||
@ -31,6 +32,9 @@ import {
|
|||||||
cloneItem as _cloneItem,
|
cloneItem as _cloneItem,
|
||||||
deleteItem as _deleteItem,
|
deleteItem as _deleteItem,
|
||||||
saveRequest as _saveRequest,
|
saveRequest as _saveRequest,
|
||||||
|
addEnvironment as _addEnvironment,
|
||||||
|
renameEnvironment as _renameEnvironment,
|
||||||
|
deleteEnvironment as _deleteEnvironment,
|
||||||
createCollection as _createCollection,
|
createCollection as _createCollection,
|
||||||
renameCollection as _renameCollection,
|
renameCollection as _renameCollection,
|
||||||
deleteCollection as _deleteCollection,
|
deleteCollection as _deleteCollection,
|
||||||
@ -71,7 +75,8 @@ export const createCollection = (collectionName) => (dispatch, getState) => {
|
|||||||
const newCollection = {
|
const newCollection = {
|
||||||
uid: uuid(),
|
uid: uuid(),
|
||||||
name: collectionName,
|
name: collectionName,
|
||||||
items: []
|
items: [],
|
||||||
|
environments: []
|
||||||
};
|
};
|
||||||
|
|
||||||
const requestItem = {
|
const requestItem = {
|
||||||
@ -606,6 +611,88 @@ export const newHttpRequest = (params) => (dispatch, getState) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const addEnvironment = (name, 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 environment = {
|
||||||
|
uid: uuid(),
|
||||||
|
name: name,
|
||||||
|
variables: []
|
||||||
|
};
|
||||||
|
|
||||||
|
const collectionCopy = cloneDeep(collection);
|
||||||
|
const collectionToSave = transformCollectionToSaveToIdb(collectionCopy);
|
||||||
|
collectionToSave.environments = collectionToSave.environments || [];
|
||||||
|
collectionToSave.environments.push(environment);
|
||||||
|
|
||||||
|
collectionSchema
|
||||||
|
.validate(collectionToSave)
|
||||||
|
.then(() => saveCollectionToIdb(window.__idb, collectionToSave))
|
||||||
|
.then(() => dispatch(_addEnvironment({environment, collectionUid})))
|
||||||
|
.then(resolve)
|
||||||
|
.catch(reject);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const renameEnvironment = (newName, 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'));
|
||||||
|
}
|
||||||
|
|
||||||
|
environment.name = newName;
|
||||||
|
|
||||||
|
const collectionToSave = transformCollectionToSaveToIdb(collectionCopy);
|
||||||
|
|
||||||
|
collectionSchema
|
||||||
|
.validate(collectionToSave)
|
||||||
|
.then(() => saveCollectionToIdb(window.__idb, collectionToSave))
|
||||||
|
.then(() => dispatch(_renameEnvironment({newName, environmentUid, collectionUid})))
|
||||||
|
.then(resolve)
|
||||||
|
.catch(reject);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteEnvironment = (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'));
|
||||||
|
}
|
||||||
|
|
||||||
|
collectionCopy.environments = filter(collectionCopy.environments, (e) => e.uid !== environmentUid);
|
||||||
|
|
||||||
|
const collectionToSave = transformCollectionToSaveToIdb(collectionCopy);
|
||||||
|
|
||||||
|
collectionSchema
|
||||||
|
.validate(collectionToSave)
|
||||||
|
.then(() => saveCollectionToIdb(window.__idb, collectionToSave))
|
||||||
|
.then(() => dispatch(_deleteEnvironment({environmentUid, collectionUid})))
|
||||||
|
.then(resolve)
|
||||||
|
.catch(reject);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export const removeLocalCollection = (collectionUid) => (dispatch, getState) => {
|
export const removeLocalCollection = (collectionUid) => (dispatch, getState) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
|
@ -11,6 +11,7 @@ import splitOnFirst from 'split-on-first';
|
|||||||
import {
|
import {
|
||||||
findCollectionByUid,
|
findCollectionByUid,
|
||||||
findItemInCollection,
|
findItemInCollection,
|
||||||
|
findEnvironmentInCollection,
|
||||||
findItemInCollectionByPathname,
|
findItemInCollectionByPathname,
|
||||||
addDepth,
|
addDepth,
|
||||||
collapseCollection,
|
collapseCollection,
|
||||||
@ -69,6 +70,39 @@ export const collectionsSlice = createSlice({
|
|||||||
deleteCollection: (state, action) => {
|
deleteCollection: (state, action) => {
|
||||||
state.collections = filter(state.collections, c => c.uid !== action.payload.collectionUid);
|
state.collections = filter(state.collections, c => c.uid !== action.payload.collectionUid);
|
||||||
},
|
},
|
||||||
|
addEnvironment: (state, action) => {
|
||||||
|
const { environment, collectionUid } = action.payload;
|
||||||
|
const collection = findCollectionByUid(state.collections, collectionUid);
|
||||||
|
|
||||||
|
if(collection) {
|
||||||
|
collection.environments = collection.environments || [];
|
||||||
|
collection.environments.push(environment);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
renameEnvironment: (state, action) => {
|
||||||
|
const { newName, environmentUid, collectionUid } = action.payload;
|
||||||
|
const collection = findCollectionByUid(state.collections, collectionUid);
|
||||||
|
|
||||||
|
if(collection) {
|
||||||
|
const environment = findEnvironmentInCollection(collection, environmentUid);
|
||||||
|
|
||||||
|
if(environment) {
|
||||||
|
environment.name = newName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
deleteEnvironment: (state, action) => {
|
||||||
|
const { environmentUid, collectionUid } = action.payload;
|
||||||
|
const collection = findCollectionByUid(state.collections, collectionUid);
|
||||||
|
|
||||||
|
if(collection) {
|
||||||
|
const environment = findEnvironmentInCollection(collection, environmentUid);
|
||||||
|
|
||||||
|
if(environment) {
|
||||||
|
collection.environments = filter(collection.environments, (e) => e.uid !== environmentUid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
newItem: (state, action) => {
|
newItem: (state, action) => {
|
||||||
const collection = findCollectionByUid(state.collections, action.payload.collectionUid);
|
const collection = findCollectionByUid(state.collections, action.payload.collectionUid);
|
||||||
|
|
||||||
@ -690,6 +724,9 @@ export const {
|
|||||||
renameCollection,
|
renameCollection,
|
||||||
deleteCollection,
|
deleteCollection,
|
||||||
loadCollections,
|
loadCollections,
|
||||||
|
addEnvironment,
|
||||||
|
renameEnvironment,
|
||||||
|
deleteEnvironment,
|
||||||
newItem,
|
newItem,
|
||||||
deleteItem,
|
deleteItem,
|
||||||
renameItem,
|
renameItem,
|
||||||
|
@ -117,6 +117,10 @@ export const recursivelyGetAllItemUids = (items = []) => {
|
|||||||
return map(flattenedItems, (i) => i.uid);
|
return map(flattenedItems, (i) => i.uid);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const findEnvironmentInCollection = (collection, envUid) => {
|
||||||
|
return find(collection.environments, (e) => e.uid === envUid);
|
||||||
|
}
|
||||||
|
|
||||||
export const transformCollectionToSaveToIdb = (collection, options = {}) => {
|
export const transformCollectionToSaveToIdb = (collection, options = {}) => {
|
||||||
const copyHeaders = (headers) => {
|
const copyHeaders = (headers) => {
|
||||||
return map(headers, (header) => {
|
return map(headers, (header) => {
|
||||||
@ -233,6 +237,7 @@ export const transformCollectionToSaveToIdb = (collection, options = {}) => {
|
|||||||
collectionToSave.name = collection.name;
|
collectionToSave.name = collection.name;
|
||||||
collectionToSave.uid = collection.uid;
|
collectionToSave.uid = collection.uid;
|
||||||
collectionToSave.items = [];
|
collectionToSave.items = [];
|
||||||
|
collectionToSave.environments = collection.environments || [];
|
||||||
|
|
||||||
copyItems(collection.items, collectionToSave.items);
|
copyItems(collection.items, collectionToSave.items);
|
||||||
|
|
||||||
|
@ -1,6 +1,21 @@
|
|||||||
const Yup = require('yup');
|
const Yup = require('yup');
|
||||||
const { uidSchema } = require("../common");
|
const { uidSchema } = require("../common");
|
||||||
|
|
||||||
|
const environmentVariablesSchema = Yup.object({
|
||||||
|
uid: uidSchema,
|
||||||
|
name: Yup.string().nullable().max(256, 'name must be 256 characters or less').defined(),
|
||||||
|
value: Yup.string().nullable().max(2048, 'value must be 2048 characters or less').defined(),
|
||||||
|
type: Yup.string().oneOf(['text']).required('type is required'),
|
||||||
|
enabled: Yup.boolean().defined()
|
||||||
|
}).noUnknown(true).strict();
|
||||||
|
|
||||||
|
|
||||||
|
const environmentSchema = Yup.object({
|
||||||
|
uid: uidSchema,
|
||||||
|
name: Yup.string().min(1).max(50, 'name must be 50 characters or less').required('name is required'),
|
||||||
|
variables: Yup.array().of(environmentVariablesSchema).required('variables are required')
|
||||||
|
}).noUnknown(true).strict();
|
||||||
|
|
||||||
const keyValueSchema = Yup.object({
|
const keyValueSchema = Yup.object({
|
||||||
uid: uidSchema,
|
uid: uidSchema,
|
||||||
name: Yup.string().nullable().max(256, 'name must be 256 characters or less').defined(),
|
name: Yup.string().nullable().max(256, 'name must be 256 characters or less').defined(),
|
||||||
@ -55,6 +70,7 @@ const collectionSchema = Yup.object({
|
|||||||
.max(50, 'name must be 100 characters or less')
|
.max(50, 'name must be 100 characters or less')
|
||||||
.required('name is required'),
|
.required('name is required'),
|
||||||
items: Yup.array().of(itemSchema),
|
items: Yup.array().of(itemSchema),
|
||||||
|
environments: Yup.array().of(environmentSchema),
|
||||||
pathname: Yup.string().max(1024, 'pathname cannot be more than 1024 characters').nullable()
|
pathname: Yup.string().max(1024, 'pathname cannot be more than 1024 characters').nullable()
|
||||||
}).noUnknown(true).strict();
|
}).noUnknown(true).strict();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user