Fix ButtonLink and edit request names

This commit is contained in:
Gregory Schier
2023-03-13 00:11:23 -07:00
parent 4ad91b4553
commit 7ad1bd54ac
4 changed files with 66 additions and 35 deletions

View File

@@ -1,6 +1,6 @@
import classnames from 'classnames'; import classnames from 'classnames';
import type { ComponentChildren } from 'preact'; import type { ComponentChildren } from 'preact';
import type { ForwardedRef } from 'preact/compat'; import { Link } from 'preact-router';
import { forwardRef } from 'preact/compat'; import { forwardRef } from 'preact/compat';
import { Icon } from './Icon'; import { Icon } from './Icon';
@@ -15,11 +15,15 @@ const colorStyles = {
}; };
export type ButtonProps = { export type ButtonProps = {
href?: string;
color?: keyof typeof colorStyles; color?: keyof typeof colorStyles;
size?: 'sm' | 'md'; size?: 'sm' | 'md';
justify?: 'start' | 'center'; justify?: 'start' | 'center';
type?: 'button' | 'submit'; type?: 'button' | 'submit';
onClick?: (event: MouseEvent) => void; onClick?: (event: MouseEvent) => void;
onDoubleClick?: (event: MouseEvent) => void;
contentEditable?: boolean;
onKeyDown?: (event: KeyboardEvent) => void;
forDropdown?: boolean; forDropdown?: boolean;
className?: string; className?: string;
children?: ComponentChildren; children?: ComponentChildren;
@@ -28,21 +32,17 @@ export type ButtonProps = {
tabIndex?: number; tabIndex?: number;
}; };
export const Button = forwardRef(function Button( // eslint-disable-next-line @typescript-eslint/no-explicit-any
{ export const Button = forwardRef<any, ButtonProps>(function Button(
className, { href, className, children, forDropdown, color, justify = 'center', size = 'md', ...props },
children, ref,
forDropdown,
color,
justify = 'center',
size = 'md',
...props
}: ButtonProps,
ref: ForwardedRef<HTMLButtonElement>,
) { ) {
// const Component = 'button';
const Component = typeof href === 'string' ? Link : 'button';
return ( return (
<button <Component
ref={ref} ref={ref}
href={href}
className={classnames( className={classnames(
className, className,
'outline-none', 'outline-none',
@@ -58,6 +58,6 @@ export const Button = forwardRef(function Button(
> >
{children} {children}
{forDropdown && <Icon icon="triangleDown" className="ml-1 -mr-1" />} {forDropdown && <Icon icon="triangleDown" className="ml-1 -mr-1" />}
</button> </Component>
); );
}); });

View File

@@ -1,5 +1,4 @@
import classnames from 'classnames'; import classnames from 'classnames';
import { Link } from 'preact-router';
import type { ButtonProps } from './Button'; import type { ButtonProps } from './Button';
import { Button } from './Button'; import { Button } from './Button';
@@ -8,10 +7,12 @@ type Props = ButtonProps & {
}; };
export function ButtonLink({ href, className, ...buttonProps }: Props) { export function ButtonLink({ href, className, ...buttonProps }: Props) {
const linkProps = { href };
return ( return (
<Link {...linkProps}> <Button
<Button className={classnames(className, 'w-full')} tabIndex={-1} {...buttonProps} /> href={href}
</Link> className={classnames(className, 'w-full')}
tabIndex={-1}
{...buttonProps}
/>
); );
} }

View File

@@ -96,15 +96,17 @@ export function _Editor({
readOnly && 'cm-readonly', readOnly && 'cm-readonly',
)} )}
> >
<IconButton {contentType?.includes("graphql") && (
icon="eye" <IconButton
className="absolute right-3 bottom-3 z-10" icon="eye"
onClick={() => { className="absolute right-3 bottom-3 z-10"
const doc = cm.current?.view.state.doc ?? ''; onClick={() => {
const insert = formatSdl(doc.toString()); const doc = cm.current?.view.state.doc ?? '';
cm.current?.view.dispatch({ changes: { from: 0, to: doc.length, insert } }); const insert = formatSdl(doc.toString());
}} cm.current?.view.dispatch({ changes: { from: 0, to: doc.length, insert } });
/> }}
/>
)}
</div> </div>
); );
} }

View File

@@ -1,5 +1,7 @@
import classnames from 'classnames'; import classnames from 'classnames';
import { useRequestCreate } from '../hooks/useRequest'; import { Link } from 'preact-router';
import { useState } from 'react';
import { useRequestCreate, useRequestUpdate } from '../hooks/useRequest';
import { useTheme } from '../hooks/useTheme'; import { useTheme } from '../hooks/useTheme';
import type { HttpRequest } from '../lib/models'; import type { HttpRequest } from '../lib/models';
import { ButtonLink } from './ButtonLink'; import { ButtonLink } from './ButtonLink';
@@ -21,7 +23,7 @@ export function Sidebar({ className, activeRequestId, workspaceId, requests }: P
<div <div
className={classnames( className={classnames(
className, className,
'min-w-[10rem] bg-gray-100 h-full border-r border-gray-200 relative', 'min-w-[12rem] bg-gray-100 h-full border-r border-gray-200 relative',
)} )}
> >
<HStack as={WindowDragRegion} alignItems="center" justifyContent="end"> <HStack as={WindowDragRegion} alignItems="center" justifyContent="end">
@@ -52,22 +54,48 @@ export function Sidebar({ className, activeRequestId, workspaceId, requests }: P
} }
function SidebarItem({ request, active }: { request: HttpRequest; active: boolean }) { function SidebarItem({ request, active }: { request: HttpRequest; active: boolean }) {
const updateRequest = useRequestUpdate(request);
const [editing, setEditing] = useState<boolean>(false);
const handleSubmitNameEdit = async (el: HTMLInputElement) => {
await updateRequest.mutate({ name: el.value });
setEditing(false);
};
const handleFocus = (el: HTMLInputElement | null) => {
el?.focus();
};
return ( return (
<li key={request.id}> <li key={request.id} className="flex">
<ButtonLink <ButtonLink
color="custom" color="custom"
href={`/workspaces/${request.workspaceId}/requests/${request.id}`} size="sm"
disabled={active}
className={classnames( className={classnames(
'w-full', 'w-full',
active active
? 'bg-gray-200/70 text-gray-900' ? 'bg-gray-200/70 text-gray-900'
: 'text-gray-600 hover:text-gray-800 active:bg-gray-200/30', : 'text-gray-600 hover:text-gray-800 active:bg-gray-200/30',
)} )}
size="sm" href={`/workspaces/${request.workspaceId}/requests/${request.id}`}
contentEditable={editing}
onDoubleClick={() => setEditing(true)}
justify="start" justify="start"
> >
{request.name || request.url} {editing ? (
<input
ref={handleFocus}
defaultValue={request.name}
className="bg-transparent outline-none"
onBlur={(e) => handleSubmitNameEdit(e.currentTarget)}
onKeyDown={async (e) => {
if (e.key === 'Enter') {
await handleSubmitNameEdit(e.currentTarget);
}
}}
/>
) : (
request.name || request.url
)}
</ButtonLink> </ButtonLink>
</li> </li>
); );