From 1be0e8d31c051076c1e530148c22d1969eed99df Mon Sep 17 00:00:00 2001 From: Anoop M D Date: Tue, 18 Mar 2025 00:42:43 +0530 Subject: [PATCH] feat: custom filename can be shown by clicking advanced options --- .../components/PathDisplay/StyledWrapper.js | 2 +- .../src/components/PathDisplay/index.js | 27 +- .../CloneCollectionItem/StyledWrapper.js | 12 + .../CloneCollectionItem/index.js | 249 ++++++---- .../CollectionItemInfo/index.js | 2 +- .../RenameCollectionItem/StyledWrapper.js | 12 + .../RenameCollectionItem/index.js | 247 ++++++---- .../Sidebar/NewFolder/StyledWrapper.js | 12 + .../src/components/Sidebar/NewFolder/index.js | 223 +++++---- .../components/Sidebar/NewRequest/index.js | 446 ++++++++++-------- 10 files changed, 731 insertions(+), 501 deletions(-) create mode 100644 packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/CloneCollectionItem/StyledWrapper.js create mode 100644 packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RenameCollectionItem/StyledWrapper.js create mode 100644 packages/bruno-app/src/components/Sidebar/NewFolder/StyledWrapper.js diff --git a/packages/bruno-app/src/components/PathDisplay/StyledWrapper.js b/packages/bruno-app/src/components/PathDisplay/StyledWrapper.js index f5e174b78..326e9f8da 100644 --- a/packages/bruno-app/src/components/PathDisplay/StyledWrapper.js +++ b/packages/bruno-app/src/components/PathDisplay/StyledWrapper.js @@ -24,7 +24,7 @@ const StyledWrapper = styled.div` } - .filename, .file-extension { + .name-container, .file-extension { color: ${(props) => props.theme.colors.text.yellow}; } diff --git a/packages/bruno-app/src/components/PathDisplay/index.js b/packages/bruno-app/src/components/PathDisplay/index.js index 5e4add37d..7413d5748 100644 --- a/packages/bruno-app/src/components/PathDisplay/index.js +++ b/packages/bruno-app/src/components/PathDisplay/index.js @@ -4,36 +4,17 @@ import path from 'utils/common/path'; import StyledWrapper from './StyledWrapper'; const PathDisplay = ({ - collection, - dirName = '', - baseName = '' + baseName = '', + iconType = 'file' }) => { - const extName = path.extname(baseName) - const hasExtension = Boolean(extName); - const pathSegments = dirName?.split(path.sep).filter(Boolean); - return (
- {hasExtension ? : } + {iconType === 'file' ? : }
- {collection?.name && ( -
- {collection.name} - / -
- )} - {pathSegments?.map((segment, index) => ( - -
- {segment} -
- / -
- ))} - + {baseName}
diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/CloneCollectionItem/StyledWrapper.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/CloneCollectionItem/StyledWrapper.js new file mode 100644 index 000000000..d46e186d2 --- /dev/null +++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/CloneCollectionItem/StyledWrapper.js @@ -0,0 +1,12 @@ +import styled from 'styled-components'; + +const StyledWrapper = styled.div` + .advanced-options { + .caret { + color: ${(props) => props.theme.textLink}; + fill: ${(props) => props.theme.textLink}; + } + } +`; + +export default StyledWrapper; \ No newline at end of file diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/CloneCollectionItem/index.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/CloneCollectionItem/index.js index 296051a97..6edaf33b9 100644 --- a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/CloneCollectionItem/index.js +++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/CloneCollectionItem/index.js @@ -1,4 +1,4 @@ -import React, { useState, useRef, useEffect } from 'react'; +import React, { useState, useRef, useEffect, forwardRef } from 'react'; import toast from 'react-hot-toast'; import { useFormik } from 'formik'; import * as Yup from 'yup'; @@ -6,11 +6,14 @@ import Modal from 'components/Modal'; import { useDispatch } from 'react-redux'; import { isItemAFolder } from 'utils/tabs'; import { cloneItem } from 'providers/ReduxStore/slices/collections/actions'; -import { IconArrowBackUp, IconEdit } from "@tabler/icons"; +import { IconArrowBackUp, IconEdit, IconCaretDown } from "@tabler/icons"; import { sanitizeName, validateName, validateNameError } from 'utils/common/regex'; import Help from 'components/Help'; import PathDisplay from 'components/PathDisplay/index'; import path from 'utils/common/path'; +import Portal from 'components/Portal'; +import Dropdown from 'components/Dropdown'; +import StyledWrapper from './StyledWrapper'; const CloneCollectionItem = ({ collection, item, onClose }) => { const dispatch = useDispatch(); @@ -19,6 +22,11 @@ const CloneCollectionItem = ({ collection, item, onClose }) => { const [isEditing, toggleEditing] = useState(false); const itemName = item?.name; const itemType = item?.type; + const [showFilesystemName, toggleShowFilesystemName] = useState(false); + + const dropdownTippyRef = useRef(); + const onDropdownCreate = (ref) => (dropdownTippyRef.current = ref); + const formik = useFormik({ enableReinitialize: true, initialValues: { @@ -58,112 +66,159 @@ const CloneCollectionItem = ({ collection, item, onClose }) => { } }, [inputRef]); - const onSubmit = () => formik.handleSubmit(); + const AdvancedOptions = forwardRef((props, ref) => { + return ( +
+ + +
+ ); + }); return ( - -
e.preventDefault()}> -
- - { - formik.setFieldValue('name', e.target.value); - !isEditing && formik.setFieldValue('filename', sanitizeName(e.target.value)); - }} - value={formik.values.name || ''} - /> - {formik.touched.name && formik.errors.name ?
{formik.errors.name}
: null} -
-
-
- - {isEditing ? ( - toggleEditing(false)} - /> - ) : ( - toggleEditing(true)} - /> - )} -
- {isEditing ? ( -
+ + + + +
+ { + formik.setFieldValue('name', e.target.value); + !isEditing && formik.setFieldValue('filename', sanitizeName(e.target.value)); + }} + value={formik.values.name || ''} /> - {itemType !== 'folder' && .bru} + {formik.touched.name && formik.errors.name ?
{formik.errors.name}
: null}
- ) : ( -
- + + {showFilesystemName && ( +
+
+ + {isEditing ? ( + toggleEditing(false)} + /> + ) : ( + toggleEditing(true)} + /> + )} +
+ {isEditing ? ( +
+ + {itemType !== 'folder' && .bru} +
+ ) : ( +
+ +
+ )} + {formik.touched.filename && formik.errors.filename ? ( +
{formik.errors.filename}
+ ) : null} +
+ )} + +
+
+ } placement="bottom-start"> +
{ + dropdownTippyRef.current.hide(); + toggleShowFilesystemName(!showFilesystemName); + }} + > + {showFilesystemName ? 'Hide Filesystem Name' : 'Show Filesystem Name'} +
+
+
+
+ + + + + + +
- )} - {formik.touched.filename && formik.errors.filename ? ( -
{formik.errors.filename}
- ) : null} -
- -
+ + +
+
); }; diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/CollectionItemInfo/index.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/CollectionItemInfo/index.js index 22d546326..d2aef1e21 100644 --- a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/CollectionItemInfo/index.js +++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/CollectionItemInfo/index.js @@ -22,7 +22,7 @@ const CollectionItemInfo = ({ collection, item, onClose }) => { {name} - {type=='folder' ? 'Directory Name' : 'File Name'} : + {type=='folder' ? 'Folder Name' : 'File Name'} : {filename} diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RenameCollectionItem/StyledWrapper.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RenameCollectionItem/StyledWrapper.js new file mode 100644 index 000000000..d46e186d2 --- /dev/null +++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RenameCollectionItem/StyledWrapper.js @@ -0,0 +1,12 @@ +import styled from 'styled-components'; + +const StyledWrapper = styled.div` + .advanced-options { + .caret { + color: ${(props) => props.theme.textLink}; + fill: ${(props) => props.theme.textLink}; + } + } +`; + +export default StyledWrapper; \ No newline at end of file diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RenameCollectionItem/index.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RenameCollectionItem/index.js index 619778755..0b0350017 100644 --- a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RenameCollectionItem/index.js +++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RenameCollectionItem/index.js @@ -1,4 +1,4 @@ -import React, { useRef, useEffect, useState } from 'react'; +import React, { useRef, useEffect, useState, forwardRef } from 'react'; import { useFormik } from 'formik'; import * as Yup from 'yup'; import Modal from 'components/Modal'; @@ -6,12 +6,15 @@ import { useDispatch } from 'react-redux'; import { isItemAFolder } from 'utils/tabs'; import { renameItem, saveRequest } from 'providers/ReduxStore/slices/collections/actions'; import path from 'utils/common/path'; -import { IconArrowBackUp, IconEdit } from '@tabler/icons'; +import { IconArrowBackUp, IconEdit, IconCaretDown } from '@tabler/icons'; import { sanitizeName, validateName, validateNameError } from 'utils/common/regex'; import toast from 'react-hot-toast'; import { closeTabs } from 'providers/ReduxStore/slices/tabs'; import Help from 'components/Help'; import PathDisplay from 'components/PathDisplay'; +import Portal from 'components/Portal'; +import Dropdown from 'components/Dropdown'; +import StyledWrapper from './StyledWrapper'; const RenameCollectionItem = ({ collection, item, onClose }) => { const dispatch = useDispatch(); @@ -21,6 +24,11 @@ const RenameCollectionItem = ({ collection, item, onClose }) => { const itemName = item?.name; const itemType = item?.type; const itemFilename = item?.filename ? path.parse(item?.filename).name : ''; + const [showFilesystemName, toggleShowFilesystemName] = useState(false); + + const dropdownTippyRef = useRef(); + const onDropdownCreate = (ref) => (dropdownTippyRef.current = ref); + const formik = useFormik({ enableReinitialize: true, initialValues: { @@ -78,112 +86,157 @@ const RenameCollectionItem = ({ collection, item, onClose }) => { } }, [inputRef]); - const onSubmit = () => formik.handleSubmit(); + const AdvancedOptions = forwardRef((props, ref) => { + return ( +
+ + +
+ ); + }); return ( - -
{e.preventDefault()}}> -
- - { - formik.setFieldValue('name', e.target.value); - !isEditing && formik.setFieldValue('filename', sanitizeName(e.target.value)); - }} - value={formik.values.name || ''} - /> - {formik.touched.name && formik.errors.name ?
{formik.errors.name}
: null} -
- -
-
- - {isEditing ? ( - toggleEditing(false)} - /> - ) : ( - toggleEditing(true)} - /> - )} -
- {isEditing ? ( -
+ + + + +
+ { + formik.setFieldValue('name', e.target.value); + !isEditing && formik.setFieldValue('filename', sanitizeName(e.target.value)); + }} + value={formik.values.name || ''} /> - {itemType !== 'folder' && .bru} + {formik.touched.name && formik.errors.name ?
{formik.errors.name}
: null}
- ) : ( -
- + + {showFilesystemName && ( +
+
+ + {isEditing ? ( + toggleEditing(false)} + /> + ) : ( + toggleEditing(true)} + /> + )} +
+ {isEditing ? ( +
+ + {itemType !== 'folder' && .bru} +
+ ) : ( +
+ +
+ )} + {formik.touched.filename && formik.errors.filename ? ( +
{formik.errors.filename}
+ ) : null} +
+ )} +
+
+ } placement="bottom-start"> +
{ + dropdownTippyRef.current.hide(); + toggleShowFilesystemName(!showFilesystemName); + }} + > + {showFilesystemName ? 'Hide Filesystem Name' : 'Show Filesystem Name'} +
+
+
+
+ + + + + + +
- )} - {formik.touched.filename && formik.errors.filename ? ( -
{formik.errors.filename}
- ) : null} -
- -
+ + +
+
); }; diff --git a/packages/bruno-app/src/components/Sidebar/NewFolder/StyledWrapper.js b/packages/bruno-app/src/components/Sidebar/NewFolder/StyledWrapper.js new file mode 100644 index 000000000..d46e186d2 --- /dev/null +++ b/packages/bruno-app/src/components/Sidebar/NewFolder/StyledWrapper.js @@ -0,0 +1,12 @@ +import styled from 'styled-components'; + +const StyledWrapper = styled.div` + .advanced-options { + .caret { + color: ${(props) => props.theme.textLink}; + fill: ${(props) => props.theme.textLink}; + } + } +`; + +export default StyledWrapper; \ No newline at end of file diff --git a/packages/bruno-app/src/components/Sidebar/NewFolder/index.js b/packages/bruno-app/src/components/Sidebar/NewFolder/index.js index 7989f806f..4ff681a86 100644 --- a/packages/bruno-app/src/components/Sidebar/NewFolder/index.js +++ b/packages/bruno-app/src/components/Sidebar/NewFolder/index.js @@ -1,19 +1,27 @@ -import React, { useRef, useEffect, useState } from 'react'; +import React, { useRef, useEffect, useState, forwardRef } from 'react'; import { useFormik } from 'formik'; import toast from 'react-hot-toast'; import * as Yup from 'yup'; +import Portal from 'components/Portal'; import Modal from 'components/Modal'; import { useDispatch } from 'react-redux'; import { newFolder } from 'providers/ReduxStore/slices/collections/actions'; import { IconArrowBackUp, IconEdit} from '@tabler/icons'; import { sanitizeName, validateName, validateNameError } from 'utils/common/regex'; import PathDisplay from 'components/PathDisplay/index'; -import path from "utils/common/path"; import Help from 'components/Help'; +import Dropdown from "components/Dropdown"; +import { IconCaretDown } from "@tabler/icons"; +import StyledWrapper from './StyledWrapper'; + const NewFolder = ({ collection, item, onClose }) => { const dispatch = useDispatch(); const inputRef = useRef(); const [isEditing, toggleEditing] = useState(false); + const [showFilesystemName, toggleShowFilesystemName] = useState(false); + + const dropdownTippyRef = useRef(); + const onDropdownCreate = (ref) => (dropdownTippyRef.current = ref); const formik = useFormik({ enableReinitialize: true, @@ -59,96 +67,139 @@ const NewFolder = ({ collection, item, onClose }) => { } }, [inputRef]); - const onSubmit = () => formik.handleSubmit(); + const AdvancedOptions = forwardRef((props, ref) => { + return ( +
+ + +
+ ); + }); return ( - -
-
- - { - formik.setFieldValue('folderName', e.target.value); - !isEditing && formik.setFieldValue('directoryName', sanitizeName(e.target.value)); - }} - value={formik.values.folderName || ''} - /> - {formik.touched.folderName && formik.errors.folderName ? ( -
{formik.errors.folderName}
- ) : null} -
- -
-
-
- {isEditing ? ( -
- +
+
+ } placement="bottom-start"> +
{ + dropdownTippyRef.current.hide(); + toggleShowFilesystemName(!showFilesystemName); + }} + > + {showFilesystemName ? 'Hide Filesystem Name' : 'Show Filesystem Name'} +
+
+
+
+ + + + + + +
- ) : ( -
- -
- )} - {formik.touched.directoryName && formik.errors.directoryName ? ( -
{formik.errors.directoryName}
- ) : null} -
- - + + + + ); }; diff --git a/packages/bruno-app/src/components/Sidebar/NewRequest/index.js b/packages/bruno-app/src/components/Sidebar/NewRequest/index.js index 9e8f32beb..f3ef32cba 100644 --- a/packages/bruno-app/src/components/Sidebar/NewRequest/index.js +++ b/packages/bruno-app/src/components/Sidebar/NewRequest/index.js @@ -16,6 +16,7 @@ import { IconArrowBackUp, IconCaretDown, IconEdit } from '@tabler/icons'; import { sanitizeName, validateName, validateNameError } from 'utils/common/regex'; import Dropdown from 'components/Dropdown'; import PathDisplay from 'components/PathDisplay'; +import Portal from 'components/Portal'; import Help from 'components/Help'; import StyledWrapper from './StyledWrapper'; @@ -26,10 +27,14 @@ const NewRequest = ({ collection, item, isEphemeral, onClose }) => { brunoConfig: { presets: collectionPresets = {} } } = collection; const [curlRequestTypeDetected, setCurlRequestTypeDetected] = useState(null); + const [showFilesystemName, toggleShowFilesystemName] = useState(false); const dropdownTippyRef = useRef(); const onDropdownCreate = (ref) => (dropdownTippyRef.current = ref); + const advancedDropdownTippyRef = useRef(); + const onAdvancedDropdownCreate = (ref) => (advancedDropdownTippyRef.current = ref); + const Icon = forwardRef((props, ref) => { return (
@@ -231,230 +236,279 @@ const NewRequest = ({ collection, item, isEphemeral, onClose }) => { } }; - return ( - - -
{ - if (e.key === 'Enter') { - e.preventDefault(); - formik.handleSubmit(); - } - }} + const AdvancedOptions = forwardRef((props, ref) => { + return ( +
+ + +
+ ); + }); -
- -
-
- - { - formik.setFieldValue('requestName', e.target.value); - !isEditing && formik.setFieldValue('filename', sanitizeName(e.target.value)); - }} - value={formik.values.requestName || ''} - /> - {formik.touched.requestName && formik.errors.requestName ? ( -
{formik.errors.requestName}
- ) : null} -
-
-
- - {isEditing ? ( - toggleEditing(false)} - /> - ) : ( - toggleEditing(true)} - /> - )} -
- {isEditing ? ( -
+
- .bru -
- ) : ( -
- -
- )} - {formik.touched.filename && formik.errors.filename ? ( -
{formik.errors.filename}
- ) : null} -
- {formik.values.requestType !== 'from-curl' ? ( - <> -
-
- - ) : ( -
-
- - } placement="bottom-end"> -
{ - dropdownTippyRef.current.hide(); - curlRequestTypeChange('http-request'); - }} - > - HTTP + )} + {formik.values.requestType !== 'from-curl' ? ( + <> +
+ +
+
+ formik.setFieldValue('requestMethod', val)} + /> +
+
+ +
-
{formik.errors.requestUrl}
+ ) : null} +
+ + ) : ( +
+
+ + } placement="bottom-end"> +
{ + dropdownTippyRef.current.hide(); + curlRequestTypeChange('http-request'); + }} + > + HTTP +
+
{ + dropdownTippyRef.current.hide(); + curlRequestTypeChange('graphql-request'); + }} + > + GraphQL +
+
+
+ + {formik.touched.curlCommand && formik.errors.curlCommand ? ( +
{formik.errors.curlCommand}
+ ) : null} +
+ )} +
+
+ } placement="bottom-start"> +
{ - dropdownTippyRef.current.hide(); - curlRequestTypeChange('graphql-request'); + key="show-filesystem-name" + onClick={(e) => { + advancedDropdownTippyRef.current.hide(); + toggleShowFilesystemName(!showFilesystemName); }} > - GraphQL + {showFilesystemName ? 'Hide Filesystem Name' : 'Show Filesystem Name'}
- - {formik.touched.curlCommand && formik.errors.curlCommand ? ( -
{formik.errors.curlCommand}
- ) : null} +
+ + + + + + +
- )} - - - + + + + ); };