mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-17 23:13:51 +01:00
Fix header editor and scroll in general
This commit is contained in:
@@ -134,19 +134,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.cm-scroller, .cm-tooltip-autocomplete > ul {
|
||||
&::-webkit-scrollbar-corner,
|
||||
&::-webkit-scrollbar {
|
||||
@apply w-1.5 h-1.5 bg-transparent;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
@apply bg-gray-200 hover:bg-gray-300 rounded-full;
|
||||
}
|
||||
}
|
||||
|
||||
/* <-- */
|
||||
|
||||
/* NOTE: Extra selector required to override default styles */
|
||||
.cm-tooltip.cm-tooltip {
|
||||
@apply shadow-lg bg-gray-50 rounded overflow-hidden text-gray-900 border border-gray-200 z-50 pointer-events-auto;
|
||||
|
||||
@@ -5,7 +5,8 @@ import classnames from 'classnames';
|
||||
import { EditorView } from 'codemirror';
|
||||
import { formatSdl } from 'format-graphql';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { useUnmount } from 'react-use';
|
||||
import { useDebounce, useUnmount } from 'react-use';
|
||||
import { debounce } from '../../lib/debounce';
|
||||
import { IconButton } from '../IconButton';
|
||||
import './Editor.css';
|
||||
import { baseExtensions, getLanguageExtension, multiLineExtensions } from './extensions';
|
||||
@@ -96,7 +97,7 @@ export function _Editor({
|
||||
readOnly && 'cm-readonly',
|
||||
)}
|
||||
>
|
||||
{contentType?.includes("graphql") && (
|
||||
{contentType?.includes('graphql') && (
|
||||
<IconButton
|
||||
icon="eye"
|
||||
className="absolute right-3 bottom-3 z-10"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import classnames from 'classnames';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useRequestUpdate } from '../hooks/useRequest';
|
||||
import type { HttpHeader, HttpRequest } from '../lib/models';
|
||||
@@ -7,11 +8,12 @@ import { VStack } from './Stacks';
|
||||
|
||||
interface Props {
|
||||
request: HttpRequest;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
type PairWithId = { header: Partial<HttpHeader>; id: string };
|
||||
|
||||
export function HeaderEditor({ request }: Props) {
|
||||
export function HeaderEditor({ request, className }: Props) {
|
||||
const updateRequest = useRequestUpdate(request);
|
||||
const saveHeaders = (pairs: PairWithId[]) => {
|
||||
const headers = pairs.map((p) => ({ name: '', value: '', ...p.header }));
|
||||
@@ -59,7 +61,7 @@ export function HeaderEditor({ request }: Props) {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="pb-6">
|
||||
<div className={classnames(className, 'pb-6 grid')}>
|
||||
<VStack space={2}>
|
||||
{pairs.map((p, i) => (
|
||||
<FormRow
|
||||
|
||||
@@ -40,6 +40,9 @@ export function RequestPane({ fullHeight, request, className }: Props) {
|
||||
defaultValue="body"
|
||||
label="Request body"
|
||||
>
|
||||
<TabContent value="headers" className="pl-2">
|
||||
<HeaderEditor key={request.id} request={request} />
|
||||
</TabContent>
|
||||
<TabContent value="body">
|
||||
<Editor
|
||||
key={request.id}
|
||||
@@ -51,9 +54,6 @@ export function RequestPane({ fullHeight, request, className }: Props) {
|
||||
onChange={(body) => updateRequest.mutate({ body })}
|
||||
/>
|
||||
</TabContent>
|
||||
<TabContent value="headers" className="pl-2">
|
||||
<HeaderEditor key={request.id} request={request} />
|
||||
</TabContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import classnames from 'classnames';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { memo, useEffect, useMemo, useState } from 'react';
|
||||
import { useDeleteAllResponses, useDeleteResponse, useResponses } from '../hooks/useResponses';
|
||||
import { tryFormatJson } from '../lib/formatters';
|
||||
import { Dropdown } from './Dropdown';
|
||||
@@ -15,7 +15,7 @@ interface Props {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function ResponsePane({ requestId, className }: Props) {
|
||||
export const ResponsePane = memo(function ResponsePane({ requestId, className }: Props) {
|
||||
const [activeResponseId, setActiveResponseId] = useState<string | null>(null);
|
||||
const [viewMode, setViewMode] = useState<'pretty' | 'raw'>('pretty');
|
||||
const responses = useResponses(requestId);
|
||||
@@ -129,4 +129,4 @@ export function ResponsePane({ requestId, className }: Props) {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -22,7 +22,7 @@ export function Sidebar({ className, activeRequestId, workspaceId, requests }: P
|
||||
<div
|
||||
className={classnames(
|
||||
className,
|
||||
'min-w-[12rem] 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 grid grid-rows-[auto,1fr]',
|
||||
)}
|
||||
>
|
||||
<HStack as={WindowDragRegion} alignItems="center" justifyContent="end">
|
||||
@@ -34,7 +34,7 @@ export function Sidebar({ className, activeRequestId, workspaceId, requests }: P
|
||||
}}
|
||||
/>
|
||||
</HStack>
|
||||
<VStack as="ul" className="py-3 px-2" space={1}>
|
||||
<VStack as="ul" className="py-3 px-2 overflow-auto h-full" space={1}>
|
||||
{requests.map((r) => (
|
||||
<SidebarItem key={r.id} request={r} active={r.id === activeRequestId} />
|
||||
))}
|
||||
|
||||
@@ -23,25 +23,21 @@ export function Tabs({ defaultValue, label, children, tabs, className, tabListCl
|
||||
<T.Root
|
||||
defaultValue={defaultValue}
|
||||
onValueChange={setValue}
|
||||
className={classnames(
|
||||
className,
|
||||
// 'h-full overflow-hidden grid grid-rows-[auto_minmax(0,1fr)]',
|
||||
'h-full flex flex-col min-h-[min-content]',
|
||||
)}
|
||||
className={classnames(className, 'h-full grid grid-rows-[auto_minmax(0,1fr)] grid-cols-1')}
|
||||
>
|
||||
<T.List
|
||||
aria-label={label}
|
||||
className={classnames(tabListClassName, 'h-auto flex items-center')}
|
||||
className={classnames(tabListClassName, 'h-auto flex items-center overflow-x-auto mb-1 pb-1')}
|
||||
>
|
||||
<ScrollArea className="w-full pb-2">
|
||||
<HStack space={1}>
|
||||
{tabs.map((t) => (
|
||||
<TabTrigger key={t.value} value={t.value} active={t.value === value}>
|
||||
{t.label}
|
||||
</TabTrigger>
|
||||
))}
|
||||
</HStack>
|
||||
</ScrollArea>
|
||||
{/*<ScrollArea className="w-full pb-2">*/}
|
||||
<HStack space={1}>
|
||||
{tabs.map((t) => (
|
||||
<TabTrigger key={t.value} value={t.value} active={t.value === value}>
|
||||
{t.label}
|
||||
</TabTrigger>
|
||||
))}
|
||||
</HStack>
|
||||
{/*</ScrollArea>*/}
|
||||
</T.List>
|
||||
{children}
|
||||
</T.Root>
|
||||
@@ -81,7 +77,7 @@ export function TabContent({ value, children, className }: TabContentProps) {
|
||||
<T.Content
|
||||
forceMount
|
||||
value={value}
|
||||
className={classnames(className, 'tab-content', 'w-full overflow-auto flex-grow h-0')}
|
||||
className={classnames(className, 'tab-content', 'w-full h-full overflow-auto')}
|
||||
>
|
||||
{children}
|
||||
</T.Content>
|
||||
|
||||
Reference in New Issue
Block a user