Merge pull request #4241 from usebruno/feat/file-location-ux-improvements

Feat/file location ux improvements
This commit is contained in:
lohit
2025-03-15 14:15:49 +05:30
committed by GitHub
9 changed files with 138 additions and 21 deletions

View File

@@ -0,0 +1,11 @@
import styled from 'styled-components';
const Wrapper = styled.div`
font-weight: 400;
font-size: 0.75rem;
background-color: ${props => props.theme.infoTip.bg};
border: 1px solid ${props => props.theme.infoTip.border};
box-shadow: ${props => props.theme.infoTip.boxShadow};
`;
export default Wrapper;

View File

@@ -0,0 +1,40 @@
/**
* The InfoTip components needs to be nuked
* This component will be the future replacement
* We should allow icon and placement props to be passed in
*/
import React, { useState } from 'react';
import HelpIcon from 'components/Icons/Help';
import StyledWrapper from './StyledWrapper';
const Help = ({ children, width = 200 }) => {
const [showTooltip, setShowTooltip] = useState(false);
return (
<div className="flex items-center relative">
<span
className="flex items-center"
onMouseEnter={() => setShowTooltip(true)}
onMouseLeave={() => setShowTooltip(false)}
>
<HelpIcon size={14}/>
</span>
{showTooltip && (
<StyledWrapper
className="absolute z-50 rounded-md p-3"
style={{
top: '50%',
left: 'calc(100% + 8px)',
transform: 'translateY(-50%)',
width: `${width}px`
}}
>
{children}
</StyledWrapper>
)}
</div>
);
};
export default Help;

View File

@@ -0,0 +1,20 @@
import React from 'react';
const HelpIcon = ({ size = 14 }) => {
return (
<svg
tabIndex="-1"
xmlns="http://www.w3.org/2000/svg"
width={size}
height={size}
fill="currentColor"
className="inline-block ml-2 cursor-pointer"
viewBox="0 0 16 16"
>
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" />
<path d="M5.255 5.786a.237.237 0 0 0 .241.247h.825c.138 0 .248-.113.266-.25.09-.656.54-1.134 1.342-1.134.686 0 1.314.343 1.314 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.003.217a.25.25 0 0 0 .25.246h.811a.25.25 0 0 0 .25-.25v-.105c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.267 0-2.655.59-2.75 2.286zm1.557 5.763c0 .533.425.927 1.01.927.609 0 1.028-.394 1.028-.927 0-.552-.42-.94-1.029-.94-.584 0-1.009.388-1.009.94z" />
</svg>
)
}
export default HelpIcon;

View File

@@ -16,7 +16,7 @@ const ModalHeader = ({ title, handleCancel, customHeader, hideClose }) => (
</div>
);
const ModalContent = ({ children }) => <div className="bruno-modal-content px-4 py-6">{children}</div>;
const ModalContent = ({ children }) => <div className="bruno-modal-content px-4 py-4">{children}</div>;
const ModalFooter = ({
confirmText,

View File

@@ -5,16 +5,32 @@ const StyledWrapper = styled.div`
background: ${(props) => props.theme.requestTabPanel.url.bg};
border-radius: 4px;
padding: 8px 12px;
.filename {
color: ${(props) => props.theme.brand};
font-weight: 500;
min-height: 1.25rem;
font-size: 0.8125rem;
border: 1px solid rgba(0, 0, 0, 0.08);
.icon-column {
padding-right: 8px;
align-items: flex-start;
padding-top: 2px;
}
.file-extension {
.path-container {
flex-wrap: wrap;
}
.path-segment {
white-space: nowrap;
}
.filename, .file-extension {
color: ${(props) => props.theme.colors.text.yellow};
}
.separator {
color: ${(props) => props.theme.text};
opacity: 0.5;
opacity: 0.6;
margin: 0 1px;
}
}
`;

View File

@@ -19,7 +19,7 @@ const PathDisplay = ({
<StyledWrapper>
<div className="mt-4">
<div className="flex items-center justify-between mb-2">
<label className="block font-semibold">Location Path</label>
<label className="block font-medium">Location</label>
<IconEdit
className="cursor-pointer opacity-50 hover:opacity-80"
size={16}
@@ -28,19 +28,28 @@ const PathDisplay = ({
/>
</div>
<div className="path-display">
<div className="flex flex-wrap items-center gap-1 text-sm">
<div className="flex items-center gap-1">
{showExtension ? <IconFile size={16} className="text-gray-500" /> : <IconFolder size={16} className="text-gray-500" />}
<span className="font-medium">{collection?.name}</span>
<div className="path-layout flex">
<div className="icon-column flex">
{showExtension ? <IconFile size={16} /> : <IconFolder size={16} />}
</div>
{pathSegments?.length > 0 && pathSegments?.map((segment, index) => (
<div key={index} className="flex items-center gap-1">
<span className="text-gray-400">/</span>
<span>{segment}</span>
<div className="path-container flex font-mono items-center">
<div className="path-segment collection-segment">
{collection?.name}
</div>
))}
<div className="flex items-center gap-1">
{collection && <span className="text-gray-400">/</span>}
{pathSegments?.length > 0 && pathSegments?.map((segment, index) => (
<React.Fragment key={index}>
<span className="separator">/</span>
<div className="path-segment">
{segment}
</div>
</React.Fragment>
))}
{collection && (
<span className="separator">/</span>
)}
<span className="filename">
{filename}
{showExtension && filename?.length ? (

View File

@@ -10,6 +10,7 @@ import { sanitizeName, validateName, validateNameError } from 'utils/common/rege
import PathDisplay from 'components/PathDisplay/index';
import { useState } from 'react';
import { IconArrowBackUp } from '@tabler/icons';
import Help from 'components/Help';
const CreateCollection = ({ onClose }) => {
const inputRef = useRef();
@@ -97,8 +98,16 @@ const CreateCollection = ({ onClose }) => {
<div className="text-red-500">{formik.errors.collectionName}</div>
) : null}
<label htmlFor="collection-location" className="block font-semibold mt-3">
<label htmlFor="collection-location" className="block font-semibold mt-3 flex items-center">
Location
<Help>
<p>
Bruno stores your collections on your computer's filesystem.
</p>
<p className="mt-2">
Choose where you want to store this collection.
</p>
</Help>
</label>
<input
id="collection-location"

View File

@@ -279,6 +279,12 @@ const darkTheme = {
scrollbar: {
color: 'rgb(52 51 49)'
},
infoTip: {
bg: '#1f1f1f',
border: '#333333',
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.5)'
}
};

View File

@@ -280,6 +280,12 @@ const lightTheme = {
scrollbar: {
color: 'rgb(152 151 149)'
},
infoTip: {
bg: 'white',
border: '#e0e0e0',
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)'
}
};