diff --git a/packages/bruno-app/src/components/Icons/OpenCollectionIcon/index.js b/packages/bruno-app/src/components/Icons/OpenCollectionIcon/index.js new file mode 100644 index 000000000..67ec875bd --- /dev/null +++ b/packages/bruno-app/src/components/Icons/OpenCollectionIcon/index.js @@ -0,0 +1,47 @@ +import React, { useId } from 'react'; +import styled from 'styled-components'; + +const StyledSvg = styled.svg` + .icon-stroke { + stroke: ${(props) => props.theme.text}; + } + .icon-fill { + fill: ${(props) => props.theme.text}; + } +`; + +const OpenCollectionIcon = ({ size = 28 }) => { + const clipId = useId(); + + return ( + + + + + + + + + + + + ); +}; + +export default OpenCollectionIcon; diff --git a/packages/bruno-app/src/components/ShareCollection/StyledWrapper.js b/packages/bruno-app/src/components/ShareCollection/StyledWrapper.js index 2cdb681be..b4613cba5 100644 --- a/packages/bruno-app/src/components/ShareCollection/StyledWrapper.js +++ b/packages/bruno-app/src/components/ShareCollection/StyledWrapper.js @@ -27,7 +27,22 @@ const StyledWrapper = styled.div` } } } - + + .beta-badge-corner { + position: absolute; + top: 0; + right: 0; + padding: 0.25rem 0.5rem; + font-size: 0.625rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.025em; + background-color: ${(props) => rgba(props.theme.colors.text.yellow, 0.15)}; + color: ${(props) => props.theme.colors.text.yellow}; + border-top-right-radius: ${(props) => props.theme.border.radius.base}; + border-bottom-left-radius: ${(props) => props.theme.border.radius.base}; + } + .share-button { display: flex; border-radius: ${(props) => props.theme.border.radius.base}; diff --git a/packages/bruno-app/src/components/ShareCollection/index.js b/packages/bruno-app/src/components/ShareCollection/index.js index 86f28ca16..11a461000 100644 --- a/packages/bruno-app/src/components/ShareCollection/index.js +++ b/packages/bruno-app/src/components/ShareCollection/index.js @@ -1,8 +1,9 @@ import React, { useMemo } from 'react'; import Modal from 'components/Modal'; -import { IconUpload, IconLoader2, IconAlertTriangle, IconFileExport } from '@tabler/icons'; +import { IconUpload, IconLoader2, IconAlertTriangle } from '@tabler/icons'; import StyledWrapper from './StyledWrapper'; import Bruno from 'components/Bruno'; +import OpenCollectionIcon from 'components/Icons/OpenCollectionIcon'; import exportBrunoCollection from 'utils/collections/export'; import exportPostmanCollection from 'utils/exporters/postman-collection'; import exportOpenCollection from 'utils/exporters/opencollection'; @@ -86,18 +87,19 @@ const ShareCollection = ({ onClose, collectionUid }) => {
+ Beta
{isCollectionLoading ? ( ) : ( - + )}
diff --git a/packages/bruno-app/src/components/Sidebar/CreateCollection/StyledWrapper.js b/packages/bruno-app/src/components/Sidebar/CreateCollection/StyledWrapper.js index 4f8bad5d0..8be5446dd 100644 --- a/packages/bruno-app/src/components/Sidebar/CreateCollection/StyledWrapper.js +++ b/packages/bruno-app/src/components/Sidebar/CreateCollection/StyledWrapper.js @@ -1,10 +1,35 @@ import styled from 'styled-components'; +import { rgba } from 'polished'; const StyledWrapper = styled.div` - .advanced-options { - .caret { - color: ${(props) => props.theme.textLink}; - fill: ${(props) => props.theme.textLink}; + .beta-badge { + margin-left: 0.5rem; + padding: 0.125rem 0.5rem; + font-size: 0.625rem; + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.025em; + background-color: ${(props) => rgba(props.theme.colors.text.yellow, 0.15)}; + color: ${(props) => props.theme.colors.text.yellow}; + border-radius: ${(props) => props.theme.border.radius.sm}; + } + + .report-issue-link { + display: inline-flex; + align-items: center; + gap: 0.375rem; + font-size: ${(props) => props.theme.font.size.sm}; + color: ${(props) => props.theme.textLink}; + cursor: pointer; + transition: opacity 0.15s ease; + + &:hover { + opacity: 0.8; + text-decoration: underline; + } + + svg { + flex-shrink: 0; } } `; diff --git a/packages/bruno-app/src/components/Sidebar/CreateCollection/index.js b/packages/bruno-app/src/components/Sidebar/CreateCollection/index.js index 19ad612ea..d7d1933b0 100644 --- a/packages/bruno-app/src/components/Sidebar/CreateCollection/index.js +++ b/packages/bruno-app/src/components/Sidebar/CreateCollection/index.js @@ -1,8 +1,7 @@ -import React, { useRef, useEffect, forwardRef } from 'react'; +import React, { useRef, useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useFormik } from 'formik'; import * as Yup from 'yup'; -import path from 'path'; import { browseDirectory, createCollection } from 'providers/ReduxStore/slices/collections/actions'; import toast from 'react-hot-toast'; import Portal from 'components/Portal'; @@ -10,12 +9,10 @@ import Modal from 'components/Modal'; import { sanitizeName, validateName, validateNameError } from 'utils/common/regex'; import PathDisplay from 'components/PathDisplay/index'; import { useState } from 'react'; -import { IconArrowBackUp, IconEdit, IconCaretDown } from '@tabler/icons'; +import { IconArrowBackUp, IconEdit, IconExternalLink } from '@tabler/icons'; import Help from 'components/Help'; import { multiLineMsg } from 'utils/common'; import { formatIpcError } from 'utils/common/error'; -import { toggleSidebarCollapse } from 'providers/ReduxStore/slices/app'; -import Dropdown from 'components/Dropdown'; import StyledWrapper from './StyledWrapper'; import get from 'lodash/get'; import Button from 'ui/Button'; @@ -27,21 +24,11 @@ const CreateCollection = ({ onClose, defaultLocation: propDefaultLocation }) => const workspaceUid = useSelector((state) => state.workspaces?.activeWorkspaceUid); const [isEditing, toggleEditing] = useState(false); const preferences = useSelector((state) => state.app.preferences); - const [showExternalLocation, setShowExternalLocation] = useState(false); - const [showAdvanced, setShowAdvanced] = useState(true); - const dropdownTippyRef = useRef(); - const onDropdownCreate = (ref) => (dropdownTippyRef.current = ref); - const activeWorkspace = workspaces.find((w) => w.uid === workspaceUid); const isDefaultWorkspace = activeWorkspace?.type === 'default'; - const hideLocationInput = activeWorkspace && activeWorkspace.type !== 'default' && !!activeWorkspace?.pathname; - const defaultLocation = isDefaultWorkspace ? get(preferences, 'general.defaultCollectionLocation', '') : (activeWorkspace?.pathname ? `${activeWorkspace.pathname}/collections` : ''); - const shouldShowAccordion = workspaceUid && hideLocationInput && !isDefaultWorkspace; - const actuallyHideLocationInput = hideLocationInput && !showExternalLocation && !isDefaultWorkspace; - const formik = useFormik({ enableReinitialize: true, initialValues: { @@ -63,36 +50,16 @@ const CreateCollection = ({ onClose, defaultLocation: propDefaultLocation }) => return isValid ? true : this.createError({ message: validateNameError(value) }); }) .required('folder name is required'), - collectionLocation: actuallyHideLocationInput - ? Yup.string() // Optional for workspaces when not using external location - : Yup.string().min(1, 'location is required').required('location is required'), + collectionLocation: Yup.string().min(1, 'location is required').required('location is required'), format: Yup.string().oneOf(['bru', 'yml'], 'invalid format').required('format is required') }), onSubmit: async (values) => { try { - const currentWorkspace = workspaces.find((w) => w.uid === workspaceUid); - const useExternalLocation = workspaceUid && showExternalLocation && values.collectionLocation; - - let collectionLocation = values.collectionLocation; - if (workspaceUid && !useExternalLocation && currentWorkspace && currentWorkspace.type !== 'default') { - collectionLocation = path.join(currentWorkspace.pathname, 'collections'); - } - await dispatch(createCollection(values.collectionName, values.collectionFolderName, - collectionLocation, + values.collectionLocation, { format: values.format })); - if (useExternalLocation && currentWorkspace) { - const { ipcRenderer } = window; - const collectionPath = path.join(values.collectionLocation, values.collectionFolderName); - const workspaceCollection = { - name: values.collectionName, - path: collectionPath - }; - await ipcRenderer.invoke('renderer:add-collection-to-workspace', currentWorkspace.pathname, workspaceCollection); - } - toast.success('Collection created!'); onClose(); } catch (e) { @@ -119,20 +86,6 @@ const CreateCollection = ({ onClose, defaultLocation: propDefaultLocation }) => } }, [inputRef]); - const AdvancedOptions = forwardRef((props, ref) => { - return ( -
- - -
- ); - }); - return ( @@ -162,47 +115,43 @@ const CreateCollection = ({ onClose, defaultLocation: propDefaultLocation }) =>
{formik.errors.collectionName}
) : null} - {!actuallyHideLocationInput && ( - <> - - { - formik.setFieldValue('collectionLocation', e.target.value); - }} - /> - {formik.touched.collectionLocation && formik.errors.collectionLocation ? ( -
{formik.errors.collectionLocation}
- ) : null} -
- - Browse - -
- - )} + + { + formik.setFieldValue('collectionLocation', e.target.value); + }} + /> + {formik.touched.collectionLocation && formik.errors.collectionLocation ? ( +
{formik.errors.collectionLocation}
+ ) : null} +
+ + Browse + +
{formik.values.collectionName?.trim()?.length > 0 && (
@@ -259,78 +208,66 @@ const CreateCollection = ({ onClose, defaultLocation: propDefaultLocation }) =>
)} - {showAdvanced && ( -
- - - {formik.touched.format && formik.errors.format ? ( -
{formik.errors.format}
- ) : null} -
- )} -
-
-
- } placement="bottom-start"> - {shouldShowAccordion && ( -
+ + + {formik.touched.format && formik.errors.format ? ( +
{formik.errors.format}
+ ) : null} + {formik.values.format === 'yml' && ( + - )} - - -
-
- - - - - - + )}
+
+ + + + + + +