From e75e6865eaae134bee47bee2cc0263da2f571549 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 23 Feb 2024 16:34:19 -0800 Subject: [PATCH] Hook up empty state buttons for first-launch experience --- src-web/components/CreateDropdown.tsx | 55 ++++++++++++++++ src-web/components/SidebarActions.tsx | 41 +----------- src-web/components/Workspace.tsx | 11 ++-- src-web/components/core/Button.tsx | 94 +++++++++++++-------------- 4 files changed, 110 insertions(+), 91 deletions(-) create mode 100644 src-web/components/CreateDropdown.tsx diff --git a/src-web/components/CreateDropdown.tsx b/src-web/components/CreateDropdown.tsx new file mode 100644 index 00000000..d40d432e --- /dev/null +++ b/src-web/components/CreateDropdown.tsx @@ -0,0 +1,55 @@ +import { ReactNode } from 'react'; +import { useCreateFolder } from '../hooks/useCreateFolder'; +import { useCreateGrpcRequest } from '../hooks/useCreateGrpcRequest'; +import { useCreateHttpRequest } from '../hooks/useCreateHttpRequest'; +import { BODY_TYPE_GRAPHQL } from '../lib/models'; +import type { DropdownItem, DropdownProps } from './core/Dropdown'; +import { Dropdown } from './core/Dropdown'; + +interface Props { + hideFolder?: boolean; + children: DropdownProps['children']; +} + +export function CreateDropdown({ hideFolder, children }: Props) { + const createHttpRequest = useCreateHttpRequest(); + const createGrpcRequest = useCreateGrpcRequest(); + const createFolder = useCreateFolder(); + + return ( + createHttpRequest.mutate({}), + }, + { + key: 'create-graphql-request', + label: 'GraphQL Query', + onSelect: () => createHttpRequest.mutate({ bodyType: BODY_TYPE_GRAPHQL, method: 'POST' }), + }, + { + key: 'create-grpc-request', + label: 'gRPC Call', + onSelect: () => createGrpcRequest.mutate({}), + }, + ...((hideFolder + ? [] + : [ + { + type: 'separator', + }, + { + key: 'create-folder', + label: 'Folder', + onSelect: () => createFolder.mutate({}), + }, + ]) as DropdownItem[]), + ]} + > + {children} + + ); +} diff --git a/src-web/components/SidebarActions.tsx b/src-web/components/SidebarActions.tsx index 57b9e794..c343617f 100644 --- a/src-web/components/SidebarActions.tsx +++ b/src-web/components/SidebarActions.tsx @@ -1,18 +1,11 @@ import { memo } from 'react'; -import { useCreateFolder } from '../hooks/useCreateFolder'; -import { useCreateGrpcRequest } from '../hooks/useCreateGrpcRequest'; -import { useCreateHttpRequest } from '../hooks/useCreateHttpRequest'; import { useSidebarHidden } from '../hooks/useSidebarHidden'; import { trackEvent } from '../lib/analytics'; -import { BODY_TYPE_GRAPHQL } from '../lib/models'; -import { Dropdown } from './core/Dropdown'; import { IconButton } from './core/IconButton'; import { HStack } from './core/Stacks'; +import { CreateDropdown } from './CreateDropdown'; export const SidebarActions = memo(function SidebarActions() { - const createHttpRequest = useCreateHttpRequest(); - const createGrpcRequest = useCreateGrpcRequest(); - const createFolder = useCreateFolder(); const { hidden, show, hide } = useSidebarHidden(); return ( @@ -32,37 +25,9 @@ export const SidebarActions = memo(function SidebarActions() { hotkeyAction="sidebar.toggle" icon={hidden ? 'leftPanelHidden' : 'leftPanelVisible'} /> - createHttpRequest.mutate({}), - }, - { - key: 'create-graphql-request', - label: 'GraphQL Query', - onSelect: () => - createHttpRequest.mutate({ bodyType: BODY_TYPE_GRAPHQL, method: 'POST' }), - }, - { - key: 'create-grpc-request', - label: 'gRPC Call', - onSelect: () => createGrpcRequest.mutate({}), - }, - { - type: 'separator', - }, - { - key: 'create-folder', - label: 'Folder', - onSelect: () => createFolder.mutate({}), - }, - ]} - > + - + ); }); diff --git a/src-web/components/Workspace.tsx b/src-web/components/Workspace.tsx index fb1337b6..6e3d95fa 100644 --- a/src-web/components/Workspace.tsx +++ b/src-web/components/Workspace.tsx @@ -17,6 +17,7 @@ import { useSidebarWidth } from '../hooks/useSidebarWidth'; import { Button } from './core/Button'; import { HotKeyList } from './core/HotKeyList'; import { HStack } from './core/Stacks'; +import { CreateDropdown } from './CreateDropdown'; import { GrpcConnectionLayout } from './GrpcConnectionLayout'; import { HttpRequestLayout } from './HttpRequestLayout'; import { Overlay } from './Overlay'; @@ -167,12 +168,14 @@ export default function Workspace() { hotkeys={['http_request.create', 'sidebar.toggle', 'settings.show']} bottomSlot={ - - + + + } /> diff --git a/src-web/components/core/Button.tsx b/src-web/components/core/Button.tsx index 01b22f80..066dca1b 100644 --- a/src-web/components/core/Button.tsx +++ b/src-web/components/core/Button.tsx @@ -46,55 +46,51 @@ export const Button = forwardRef(function Button const hotkeyTrigger = useFormattedHotkey(hotkeyAction ?? null)?.join(''); const fullTitle = hotkeyTrigger ? `${title} ${hotkeyTrigger}` : title; - const classes = useMemo( - () => - classNames( - className, - 'max-w-full min-w-0', // Help with truncation - 'hocus:opacity-100', // Force opacity for certain hover effects - 'whitespace-nowrap outline-none', - 'flex-shrink-0 flex items-center', - 'focus-visible-or-class:ring rounded-md', - disabled ? 'pointer-events-none opacity-disabled' : 'pointer-events-auto', - justify === 'start' && 'justify-start', - justify === 'center' && 'justify-center', - size === 'md' && 'h-md px-3', - size === 'sm' && 'h-sm px-2.5 text-sm', - size === 'xs' && 'h-xs px-2 text-sm', - // Solids - variant === 'solid' && color === 'custom' && 'ring-blue-400', - variant === 'solid' && - color === 'default' && - 'text-gray-700 enabled:hocus:bg-gray-700/10 enabled:hocus:text-gray-800 ring-blue-400', - variant === 'solid' && - color === 'gray' && - 'text-gray-800 bg-highlight enabled:hocus:text-gray-1000 ring-blue-400', - variant === 'solid' && color === 'primary' && 'bg-blue-400 text-white ring-blue-700', - variant === 'solid' && color === 'secondary' && 'bg-violet-400 text-white ring-violet-700', - variant === 'solid' && color === 'warning' && 'bg-orange-400 text-white ring-orange-700', - variant === 'solid' && color === 'danger' && 'bg-red-400 text-white ring-red-700', - // Borders - variant === 'border' && 'border', - variant === 'border' && - color === 'default' && - 'border-highlight text-gray-700 enabled:hocus:border-focus enabled:hocus:text-gray-800 ring-blue-500/50', - variant === 'border' && - color === 'gray' && - 'border-gray-500/70 text-gray-700 enabled:hocus:bg-gray-500/20 enabled:hocus:text-gray-800 ring-blue-500/50', - variant === 'border' && - color === 'primary' && - 'border-blue-500/70 text-blue-700 enabled:hocus:border-blue-500 ring-blue-500/50', - variant === 'border' && - color === 'secondary' && - 'border-violet-500/70 text-violet-700 enabled:hocus:border-violet-500 ring-violet-500/50', - variant === 'border' && - color === 'warning' && - 'border-orange-500/70 text-orange-700 enabled:hocus:border-orange-500 ring-orange-500/50', - variant === 'border' && - color === 'danger' && - 'border-red-500/70 text-red-700 enabled:hocus:border-red-500 ring-red-500/50', - ), - [className, disabled, justify, size, variant, color], + const classes = classNames( + className, + 'max-w-full min-w-0', // Help with truncation + 'hocus:opacity-100', // Force opacity for certain hover effects + 'whitespace-nowrap outline-none', + 'flex-shrink-0 flex items-center', + 'focus-visible-or-class:ring rounded-md', + disabled ? 'pointer-events-none opacity-disabled' : 'pointer-events-auto', + justify === 'start' && 'justify-start', + justify === 'center' && 'justify-center', + size === 'md' && 'h-md px-3', + size === 'sm' && 'h-sm px-2.5 text-sm', + size === 'xs' && 'h-xs px-2 text-sm', + // Solids + variant === 'solid' && color === 'custom' && 'ring-blue-400', + variant === 'solid' && + color === 'default' && + 'text-gray-700 enabled:hocus:bg-gray-700/10 enabled:hocus:text-gray-800 ring-blue-400', + variant === 'solid' && + color === 'gray' && + 'text-gray-800 bg-highlight enabled:hocus:text-gray-1000 ring-blue-400', + variant === 'solid' && color === 'primary' && 'bg-blue-400 text-white ring-blue-700', + variant === 'solid' && color === 'secondary' && 'bg-violet-400 text-white ring-violet-700', + variant === 'solid' && color === 'warning' && 'bg-orange-400 text-white ring-orange-700', + variant === 'solid' && color === 'danger' && 'bg-red-400 text-white ring-red-700', + // Borders + variant === 'border' && 'border', + variant === 'border' && + color === 'default' && + 'border-highlight text-gray-700 enabled:hocus:border-focus enabled:hocus:text-gray-800 ring-blue-500/50', + variant === 'border' && + color === 'gray' && + 'border-gray-500/70 text-gray-700 enabled:hocus:bg-gray-500/20 enabled:hocus:text-gray-800 ring-blue-500/50', + variant === 'border' && + color === 'primary' && + 'border-blue-500/70 text-blue-700 enabled:hocus:border-blue-500 ring-blue-500/50', + variant === 'border' && + color === 'secondary' && + 'border-violet-500/70 text-violet-700 enabled:hocus:border-violet-500 ring-violet-500/50', + variant === 'border' && + color === 'warning' && + 'border-orange-500/70 text-orange-700 enabled:hocus:border-orange-500 ring-orange-500/50', + variant === 'border' && + color === 'danger' && + 'border-red-500/70 text-red-700 enabled:hocus:border-red-500 ring-red-500/50', ); const buttonRef = useRef(null);