Skip to content

Commit

Permalink
feat(sidebar): add toggle button to expand/collapse the organizations…
Browse files Browse the repository at this point in the history
… sidebar (#7275)

* add toggle button to expand/collapse the org sidebar

* cleanup testid
  • Loading branch information
gatzjames authored Apr 17, 2024
1 parent 2ed4069 commit 94737e0
Show file tree
Hide file tree
Showing 2 changed files with 178 additions and 118 deletions.
29 changes: 23 additions & 6 deletions packages/insomnia/src/ui/css/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,38 @@ html {
font-size: 11px;
}

.grid-template-app-layout-with-banner {
grid-template:
.grid-template-app-layout {
grid-template:
'Header Header' auto
'Content Content' 1fr
'Statusbar Statusbar' 30px [row-end]
/ 50px 1fr;

&.with-banner {
grid-template:
'Header Header' auto
'Banner Banner' 30px
'Navbar Content' 1fr
'Content Content' 1fr
'Statusbar Statusbar' 30px [row-end]
/ 50px 1fr;
}

.grid-template-app-layout {
grid-template:
&.with-navbar {
grid-template:
'Header Header' auto
'Banner Banner' 30px
'Navbar Content' 1fr
'Statusbar Statusbar' 30px [row-end]
/ 50px 1fr;
}
}

&.with-navbar {
grid-template:
'Header Header' auto
'Navbar Content' 1fr
'Statusbar Statusbar' 30px [row-end]
/ 50px 1fr;
}
}

input[type="search"]::-webkit-search-cancel-button {
Expand Down
267 changes: 155 additions & 112 deletions packages/insomnia/src/ui/routes/organization.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
MenuTrigger,
Popover,
ProgressBar,
ToggleButton,
Tooltip,
TooltipTrigger,
} from 'react-aria-components';
Expand Down Expand Up @@ -451,6 +452,8 @@ const OrganizationRoute = () => {
};
}, []);

const [isOrganizationSidebarOpen, setIsOganizationSidebarOpen] = useLocalStorage('organizationSidebarOpen', true);

const {
generating: loadingAI,
progress: loadingAIProgress,
Expand All @@ -459,8 +462,8 @@ const OrganizationRoute = () => {
return (
<InsomniaEventStreamProvider>
<div className="w-full h-full">
<div className={`w-full h-full divide-x divide-solid divide-y divide-[--hl-md] ${isScratchPadBannerVisible ? 'grid-template-app-layout-with-banner' : 'grid-template-app-layout'} grid relative bg-[--color-bg]`}>
<header className="[grid-area:Header] grid grid-cols-3 items-center">
<div className={`w-full h-full divide-x divide-solid divide-[--hl-md] ${isOrganizationSidebarOpen ? 'with-navbar' : ''} ${isScratchPadBannerVisible ? 'with-banner' : ''} grid-template-app-layout grid relative bg-[--color-bg]`}>
<header className="[grid-area:Header] grid grid-cols-3 items-center border-b border-solid border-[--hl-md]">
<div className="flex items-center gap-2">
<div className="flex shrink-0 w-[50px] justify-center py-2">
<InsomniaLogo loading={loadingAI} />
Expand Down Expand Up @@ -629,7 +632,7 @@ const OrganizationRoute = () => {
</Button>
</div>
) : null}
<div className="[grid-area:Navbar]">
{isOrganizationSidebarOpen && <div className={`[grid-area:Navbar] ${isOrganizationSidebarOpen ? '' : 'hidden'}`}>
<nav className="flex flex-col items-center place-content-stretch gap-[--padding-md] w-full h-full overflow-y-auto py-[--padding-md]">
{organizations.map(organization => (
<TooltipTrigger key={organization.id}>
Expand Down Expand Up @@ -713,116 +716,156 @@ const OrganizationRoute = () => {
</Popover>
</MenuTrigger>
</nav>
</div>}
<div className='[grid-area:Content] overflow-hidden border-b border-[--hl-md]'>
<Outlet />
</div>
<Outlet />
<div className="relative [grid-area:Statusbar] flex items-center justify-between overflow-hidden">
<div className="flex h-full">
<TooltipTrigger>
<Button
data-testid="settings-button"
className="px-4 py-1 h-full flex items-center justify-center gap-2 aria-pressed:bg-[--hl-sm] text-[--color-font] text-xs hover:bg-[--hl-xs] focus:ring-inset ring-1 ring-transparent focus:ring-[--hl-md] transition-all"
onPress={showSettingsModal}
>
<Icon icon="gear" /> Preferences
</Button>
<Tooltip
placement="top"
offset={8}
className="border flex items-center gap-2 select-none text-sm min-w-max border-solid border-[--hl-sm] shadow-lg bg-[--color-bg] text-[--color-font] px-4 py-2 rounded-md overflow-y-auto max-h-[85vh] focus:outline-none"
>
Preferences
<Hotkey
keyBindings={
settings.hotKeyRegistry.preferences_showGeneral
}
/>
</Tooltip>
</TooltipTrigger>
{hasUntrackedData ? <div>
<Button
className="px-4 py-1 h-full flex items-center justify-center gap-2 aria-pressed:bg-[--hl-sm] text-[--color-warning] text-xs hover:bg-[--hl-xs] focus:ring-inset ring-1 ring-transparent focus:ring-[--hl-md] transition-all"
onPress={() => showModal(SettingsModal, { tab: 'data' })}
>
<Icon icon="exclamation-circle" /> We have detected orphaned projects on your computer, click here to view them.
</Button>
</div> : null}
</div>
<div className='flex items-center gap-2 divide divide-y-[--hl-sm]'>
{loadingAI && (
<ProgressBar
className="flex items-center gap-2 h-full"
value={loadingAIProgress.progress}
maxValue={loadingAIProgress.total}
minValue={0}
aria-label='AI generation'
>
{({ percentage }) => (
<TooltipTrigger>
<Button className="px-4 py-1 h-full flex items-center justify-center gap-2 aria-pressed:bg-[--hl-sm] text-[--color-font] text-xs hover:bg-[--hl-xs] focus:ring-inset ring-1 ring-transparent focus:ring-[--hl-md] transition-all">
<InsomniaAI className='w-4 text-[--color-font] animate-pulse' />
<div className="h-1 w-32 rounded-full bg-[rgba(var(--color-surprise-rgb),var(--tw-bg-opacity))] bg-opacity-40">
<div
className="h-1 rounded-full bg-[rgba(var(--color-surprise-rgb),var(--tw-bg-opacity))] bg-opacity-100"
style={{ width: percentage + '%' }}
/>
</div>
</Button>
<Tooltip
placement="top"
offset={8}
className="border flex items-center gap-2 select-none text-sm min-w-max border-solid border-[--hl-sm] shadow-lg bg-[--color-bg] text-[--color-font] px-4 py-2 rounded-md overflow-y-auto max-h-[85vh] focus:outline-none"
>
Generating tests with Insomnia AI
</Tooltip>
</TooltipTrigger>
)}
</ProgressBar>
)}
<TooltipTrigger>
<Button
className="px-4 py-1 h-full flex items-center justify-center gap-2 aria-pressed:bg-[--hl-sm] text-[--color-font] text-xs hover:bg-[--hl-xs] focus:ring-inset ring-1 ring-transparent focus:ring-[--hl-md] transition-all"
onPress={() => {
!user && navigate('/auth/login');
}}
>
<Icon
icon="circle"
className={
user
? status === 'online'
? 'text-[--color-success]'
: 'text-[--color-danger]'
: ''
}
/>{' '}
{user
? status.charAt(0).toUpperCase() + status.slice(1)
: 'Log in to see your projects'}
</Button>
<Tooltip
placement="top"
offset={8}
className="border flex items-center gap-2 select-none text-sm min-w-max border-solid border-[--hl-sm] shadow-lg bg-[--color-bg] text-[--color-font] px-4 py-2 rounded-md overflow-y-auto max-h-[85vh] focus:outline-none"
>
{user
? `You are ${status === 'online'
? 'securely connected to Insomnia Cloud.'
: 'offline. Connect to sync your data.'
}`
: 'Log in to Insomnia to sync your data.'}
</Tooltip>
</TooltipTrigger>
<span className='w-[1px] h-full bg-[--hl-sm]' />
<Link>
<a
className="flex focus:outline-none focus:underline gap-1 items-center text-xs text-[--color-font] px-[--padding-md]"
href="https://konghq.com/"
>
Made with
<Icon className="text-[--color-surprise-font]" icon="heart" /> by
Kong
</a>
</Link>
<div className="relative [grid-area:Statusbar] flex items-center overflow-hidden">
<TooltipTrigger>
<ToggleButton
className="w-[50px] flex-shrink-0 px-4 py-1 border-solid border-r border-r-[--hl-md] h-full flex items-center justify-center gap-2 text-[--color-font] text-xs hover:bg-[--hl-xs] focus:ring-inset ring-1 ring-transparent focus:ring-[--hl-md] transition-all"
onChange={setIsOganizationSidebarOpen}
isSelected={isOrganizationSidebarOpen}
>
{({ isSelected }) => {
return (
<svg
width={10}
height={10}
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
>
{isSelected ? (
<path
fillRule="evenodd"
clipRule="evenodd"
d="M2 1L1 2v12l1 1h12l1-1V2l-1-1H2zm12 13H7V2h7v12z"
/>
) : (
<path d="M2 1L1 2v12l1 1h12l1-1V2l-1-1H2zm0 13V2h4v12H2zm5 0V2h7v12H7z" />
)}
</svg>
);
}}
</ToggleButton>
<Tooltip
placement="top"
offset={8}
className="border flex items-center gap-2 select-none text-sm min-w-max border-solid border-[--hl-sm] shadow-lg bg-[--color-bg] text-[--color-font] px-4 py-2 rounded-md overflow-y-auto max-h-[85vh] focus:outline-none"
>
Toggle organizations sidebar
</Tooltip>
</TooltipTrigger>
<div className='flex w-full h-full items-center justify-between'>
<div className="flex h-full">
<TooltipTrigger>
<Button
data-testid="settings-button"
className="px-4 py-1 h-full flex items-center justify-center gap-2 aria-pressed:bg-[--hl-sm] text-[--color-font] text-xs hover:bg-[--hl-xs] focus:ring-inset ring-1 ring-transparent focus:ring-[--hl-md] transition-all"
onPress={showSettingsModal}
>
<Icon icon="gear" /> Preferences
</Button>
<Tooltip
placement="top"
offset={8}
className="border flex items-center gap-2 select-none text-sm min-w-max border-solid border-[--hl-sm] shadow-lg bg-[--color-bg] text-[--color-font] px-4 py-2 rounded-md overflow-y-auto max-h-[85vh] focus:outline-none"
>
Preferences
<Hotkey
keyBindings={
settings.hotKeyRegistry.preferences_showGeneral
}
/>
</Tooltip>
</TooltipTrigger>
{hasUntrackedData ? <div>
<Button
className="px-4 py-1 h-full flex items-center justify-center gap-2 aria-pressed:bg-[--hl-sm] text-[--color-warning] text-xs hover:bg-[--hl-xs] focus:ring-inset ring-1 ring-transparent focus:ring-[--hl-md] transition-all"
onPress={() => showModal(SettingsModal, { tab: 'data' })}
>
<Icon icon="exclamation-circle" /> We have detected orphaned projects on your computer, click here to view them.
</Button>
</div> : null}
</div>
<div className='flex items-center gap-2 divide divide-y-[--hl-sm]'>
{loadingAI && (
<ProgressBar
className="flex items-center gap-2 h-full"
value={loadingAIProgress.progress}
maxValue={loadingAIProgress.total}
minValue={0}
aria-label='AI generation'
>
{({ percentage }) => (
<TooltipTrigger>
<Button className="px-4 py-1 h-full flex items-center justify-center gap-2 aria-pressed:bg-[--hl-sm] text-[--color-font] text-xs hover:bg-[--hl-xs] focus:ring-inset ring-1 ring-transparent focus:ring-[--hl-md] transition-all">
<InsomniaAI className='w-4 text-[--color-font] animate-pulse' />
<div className="h-1 w-32 rounded-full bg-[rgba(var(--color-surprise-rgb),var(--tw-bg-opacity))] bg-opacity-40">
<div
className="h-1 rounded-full bg-[rgba(var(--color-surprise-rgb),var(--tw-bg-opacity))] bg-opacity-100"
style={{ width: percentage + '%' }}
/>
</div>
</Button>
<Tooltip
placement="top"
offset={8}
className="border flex items-center gap-2 select-none text-sm min-w-max border-solid border-[--hl-sm] shadow-lg bg-[--color-bg] text-[--color-font] px-4 py-2 rounded-md overflow-y-auto max-h-[85vh] focus:outline-none"
>
Generating tests with Insomnia AI
</Tooltip>
</TooltipTrigger>
)}
</ProgressBar>
)}
<TooltipTrigger>
<Button
className="px-4 py-1 h-full flex items-center justify-center gap-2 aria-pressed:bg-[--hl-sm] text-[--color-font] text-xs hover:bg-[--hl-xs] focus:ring-inset ring-1 ring-transparent focus:ring-[--hl-md] transition-all"
onPress={() => {
!user && navigate('/auth/login');
}}
>
<Icon
icon="circle"
className={
user
? status === 'online'
? 'text-[--color-success]'
: 'text-[--color-danger]'
: ''
}
/>{' '}
{user
? status.charAt(0).toUpperCase() + status.slice(1)
: 'Log in to see your projects'}
</Button>
<Tooltip
placement="top"
offset={8}
className="border flex items-center gap-2 select-none text-sm min-w-max border-solid border-[--hl-sm] shadow-lg bg-[--color-bg] text-[--color-font] px-4 py-2 rounded-md overflow-y-auto max-h-[85vh] focus:outline-none"
>
{user
? `You are ${status === 'online'
? 'securely connected to Insomnia Cloud.'
: 'offline. Connect to sync your data.'
}`
: 'Log in to Insomnia to sync your data.'}
</Tooltip>
</TooltipTrigger>
<span className='w-[1px] h-full bg-[--hl-sm]' />
<Link>
<a
className="flex focus:outline-none focus:underline gap-1 items-center text-xs text-[--color-font] px-[--padding-md]"
href="https://konghq.com/"
>
Made with
<Icon className="text-[--color-surprise-font]" icon="heart" /> by
Kong
</a>
</Link>
</div>
</div>
</div>
</div>
Expand Down

0 comments on commit 94737e0

Please sign in to comment.