From b3a317dc4d8d3f457cff1e858c1687feba1f984c Mon Sep 17 00:00:00 2001 From: anusreesubash <65728079+anusreesubash@users.noreply.github.com> Date: Sun, 9 Oct 2022 12:45:48 +0530 Subject: [PATCH] feat: workspaces crud (resolves #15) (#19) feat: workspaces crud (resolves #15) --- renderer/components/Modal/index.js | 10 +-- renderer/components/Portal/index.js | 8 +++ .../WorkspaceConfigurer/AddWorkspace/index.js | 70 +++++++++++++++++++ .../DeleteWorkspace/StyledWrapper.js | 15 ++++ .../DeleteWorkspace/index.js | 34 +++++++++ .../EditWorkspace/index.js | 70 +++++++++++++++++++ .../WorkspaceItem/StyledWrapper.js | 17 +++++ .../WorkspaceItem/index.js | 27 +++++++ .../Workspaces/WorkspaceConfigurer/index.js | 32 ++++----- renderer/pages/_document.js | 2 +- .../providers/ReduxStore/slices/workspaces.js | 27 ++++++- 11 files changed, 285 insertions(+), 27 deletions(-) create mode 100644 renderer/components/Portal/index.js create mode 100644 renderer/components/Workspaces/WorkspaceConfigurer/AddWorkspace/index.js create mode 100644 renderer/components/Workspaces/WorkspaceConfigurer/DeleteWorkspace/StyledWrapper.js create mode 100644 renderer/components/Workspaces/WorkspaceConfigurer/DeleteWorkspace/index.js create mode 100644 renderer/components/Workspaces/WorkspaceConfigurer/EditWorkspace/index.js create mode 100644 renderer/components/Workspaces/WorkspaceConfigurer/WorkspaceItem/StyledWrapper.js create mode 100644 renderer/components/Workspaces/WorkspaceConfigurer/WorkspaceItem/index.js diff --git a/renderer/components/Modal/index.js b/renderer/components/Modal/index.js index 58423f52d..486f98e93 100644 --- a/renderer/components/Modal/index.js +++ b/renderer/components/Modal/index.js @@ -18,18 +18,18 @@ const ModalContent = ({children}) => ( ); -const ModalFooter = ({confirmText, cancelText, handleSubmit, handleCancel, confirmDisabled}) => { +const ModalFooter = ({confirmText, cancelText, handleSubmit, handleCancel, confirmDisabled, hideCancel}) => { confirmText = confirmText || 'Save'; cancelText = cancelText || 'Cancel'; return (
- + - + @@ -46,7 +46,8 @@ const Modal = ({ handleCancel, handleConfirm, children, - confirmDisabled + confirmDisabled, + hideCancel }) => { const [isClosing, setIsClosing] = useState(false); const escFunction = (event) => { @@ -84,6 +85,7 @@ const Modal = ({ handleCancel={() => closeModal()} handleSubmit={handleConfirm} confirmDisabled={confirmDisabled} + hideCancel={hideCancel} />
closeModal()} /> diff --git a/renderer/components/Portal/index.js b/renderer/components/Portal/index.js new file mode 100644 index 000000000..9029fc175 --- /dev/null +++ b/renderer/components/Portal/index.js @@ -0,0 +1,8 @@ +import { createPortal } from 'react-dom'; + +function Portal({ children, wrapperId }) { + wrapperId = wrapperId || "bruno-app-body"; + + return createPortal(children, document.getElementById(wrapperId)); +} +export default Portal; diff --git a/renderer/components/Workspaces/WorkspaceConfigurer/AddWorkspace/index.js b/renderer/components/Workspaces/WorkspaceConfigurer/AddWorkspace/index.js new file mode 100644 index 000000000..da3f242c4 --- /dev/null +++ b/renderer/components/Workspaces/WorkspaceConfigurer/AddWorkspace/index.js @@ -0,0 +1,70 @@ +import React, { useEffect, useRef } from 'react'; +import Portal from "components/Portal/index"; +import Modal from "components/Modal/index"; +import { useFormik } from 'formik'; +import { addWorkspace } from 'providers/ReduxStore/slices/workspaces'; +import * as Yup from 'yup'; +import { useDispatch } from 'react-redux'; + +const AddWorkspace = ({onClose}) => { + const dispatch = useDispatch(); + const inputRef = useRef(); + const formik = useFormik({ + enableReinitialize: true, + initialValues: { + name: "" + }, + validationSchema: Yup.object({ + name: Yup.string() + .min(1, 'must be atleast 1 characters') + .max(30, 'must be 30 characters or less') + .required('name is required') + }), + onSubmit: (values) => { + dispatch(addWorkspace({name: values.name})); + onClose(); + } + }); + + useEffect(() => { + if(inputRef && inputRef.current) { + inputRef.current.focus(); + } + }, [inputRef]); + + const onSubmit = () => { + formik.handleSubmit(); + } + + return ( + + +
+
+ + + {formik.touched.name && formik.errors.name ? ( +
{formik.errors.name}
+ ) : null} +
+
+
+
+ ); +} + +export default AddWorkspace; + diff --git a/renderer/components/Workspaces/WorkspaceConfigurer/DeleteWorkspace/StyledWrapper.js b/renderer/components/Workspaces/WorkspaceConfigurer/DeleteWorkspace/StyledWrapper.js new file mode 100644 index 000000000..48b874214 --- /dev/null +++ b/renderer/components/Workspaces/WorkspaceConfigurer/DeleteWorkspace/StyledWrapper.js @@ -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; diff --git a/renderer/components/Workspaces/WorkspaceConfigurer/DeleteWorkspace/index.js b/renderer/components/Workspaces/WorkspaceConfigurer/DeleteWorkspace/index.js new file mode 100644 index 000000000..79c94fb51 --- /dev/null +++ b/renderer/components/Workspaces/WorkspaceConfigurer/DeleteWorkspace/index.js @@ -0,0 +1,34 @@ +import React from 'react'; +import Portal from "components/Portal/index"; +import Modal from "components/Modal/index"; +import { deleteWorkspace } from 'providers/ReduxStore/slices/workspaces'; +import { useDispatch } from 'react-redux'; +import StyledWrapper from './StyledWrapper'; + +const DeleteWorkspace = ({onClose, workspace}) => { + const dispatch = useDispatch(); + const onConfirm = () =>{ + dispatch(deleteWorkspace({workspaceUid: workspace.uid})) + onClose(); + }; + + return ( + + + + Are you sure you want to delete {workspace.name} ? + + + + + ); +} + +export default DeleteWorkspace; + diff --git a/renderer/components/Workspaces/WorkspaceConfigurer/EditWorkspace/index.js b/renderer/components/Workspaces/WorkspaceConfigurer/EditWorkspace/index.js new file mode 100644 index 000000000..b5880da5a --- /dev/null +++ b/renderer/components/Workspaces/WorkspaceConfigurer/EditWorkspace/index.js @@ -0,0 +1,70 @@ +import React, { useEffect, useRef } from 'react'; +import Portal from "components/Portal/index"; +import Modal from "components/Modal/index"; +import { useFormik } from 'formik'; +import { renameWorkspace } from 'providers/ReduxStore/slices/workspaces'; +import * as Yup from 'yup'; +import { useDispatch } from 'react-redux'; + +const EditWorkspace = ({onClose, workspace}) => { + const dispatch = useDispatch(); + const inputRef = useRef(); + const formik = useFormik({ + enableReinitialize: true, + initialValues: { + name: workspace.name + }, + validationSchema: Yup.object({ + name: Yup.string() + .min(1, 'must be atleast 1 characters') + .max(30, 'must be 30 characters or less') + .required('name is required') + }), + onSubmit: (values) => { + dispatch(renameWorkspace({name: values.name, uid: workspace.uid})); + onClose(); + } + }); + + useEffect(() => { + if(inputRef && inputRef.current) { + inputRef.current.focus(); + } + }, [inputRef]); + + const onSubmit = () => { + formik.handleSubmit(); + } + + return ( + + +
+
+ + + {formik.touched.name && formik.errors.name ? ( +
{formik.errors.name}
+ ) : null} +
+
+
+
+ ); +} + +export default EditWorkspace; + diff --git a/renderer/components/Workspaces/WorkspaceConfigurer/WorkspaceItem/StyledWrapper.js b/renderer/components/Workspaces/WorkspaceConfigurer/WorkspaceItem/StyledWrapper.js new file mode 100644 index 000000000..feada928d --- /dev/null +++ b/renderer/components/Workspaces/WorkspaceConfigurer/WorkspaceItem/StyledWrapper.js @@ -0,0 +1,17 @@ +import styled from 'styled-components'; + +const Wrapper = styled.div` + div { + padding: 4px 6px; + padding-left: 8px; + display: flex; + align-items: center; + border-radius: 3px; + } + + div:hover { + background-color: #f4f4f4; + } +`; + +export default Wrapper; diff --git a/renderer/components/Workspaces/WorkspaceConfigurer/WorkspaceItem/index.js b/renderer/components/Workspaces/WorkspaceConfigurer/WorkspaceItem/index.js new file mode 100644 index 000000000..cb1d3e84e --- /dev/null +++ b/renderer/components/Workspaces/WorkspaceConfigurer/WorkspaceItem/index.js @@ -0,0 +1,27 @@ +import React, { useState } from "react"; +import EditModal from "../EditModal"; +import DeleteModal from "../DeleteModal"; +import { IconEdit, IconTrash } from "@tabler/icons"; +import StyledWrapper from "./StyledWrapper"; + +const WorkspaceItem = ({workspace}) => { + const [openEditModal, setOpenEditModal] = useState(false); + const [openDeleteModal, setOpenDeleteModal] = useState(false); + + return ( + +
+
  • {workspace.name}
  • +
    + setOpenEditModal(true)}/> + setOpenDeleteModal(true)}/> +
    + {openEditModal && setOpenEditModal(false)} workspace={workspace} />} + {openDeleteModal && setOpenDeleteModal(false)} workspace={workspace} />} +
    +
    + ) + +} + +export default WorkspaceItem; diff --git a/renderer/components/Workspaces/WorkspaceConfigurer/index.js b/renderer/components/Workspaces/WorkspaceConfigurer/index.js index 25ea54d8a..cf9fa4d11 100644 --- a/renderer/components/Workspaces/WorkspaceConfigurer/index.js +++ b/renderer/components/Workspaces/WorkspaceConfigurer/index.js @@ -1,36 +1,28 @@ import Modal from "components/Modal/index"; -import React from "react"; +import React, { useState } from "react"; import { useSelector } from "react-redux"; +import WorkspaceItem from "./WorkspaceItem/index"; +import AddModal from "./AddModal"; const WorkspaceConfigurer = ({onClose}) => { const { workspaces } = useSelector((state) => state.workspaces); - - const onSubmit = () => { - onClose(); - } + const [openAddModal, setOpenAddModal] = useState(false); return ( setOpenAddModal(true)} handleCancel={onClose} + hideCancel={true} > -