Separate active tabs per request

This commit is contained in:
Gregory Schier
2024-09-03 07:33:48 -07:00
parent 7f952300b3
commit ff459d1570
3 changed files with 31 additions and 14 deletions

View File

@@ -54,11 +54,13 @@ interface Props {
activeRequest: HttpRequest; activeRequest: HttpRequest;
} }
const useActiveTab = createGlobalState<string>('body'); const useActiveTab = createGlobalState<Record<string, string>>({});
const TAB_BODY = 'body'; const TAB_BODY = 'body';
const TAB_PARAMS = 'params'; const TAB_PARAMS = 'params';
const TAB_HEADERS = 'headers'; const TAB_HEADERS = 'headers';
const TAB_AUTH = 'auth'; const TAB_AUTH = 'auth';
const DEFAULT_TAB = TAB_BODY;
export const RequestPane = memo(function RequestPane({ export const RequestPane = memo(function RequestPane({
style, style,
@@ -69,7 +71,7 @@ export const RequestPane = memo(function RequestPane({
const requests = useRequests(); const requests = useRequests();
const activeRequestId = activeRequest.id; const activeRequestId = activeRequest.id;
const updateRequest = useUpdateAnyHttpRequest(); const updateRequest = useUpdateAnyHttpRequest();
const [activeTab, setActiveTab] = useActiveTab(); const [activeTabs, setActiveTabs] = useActiveTab();
const [forceUpdateHeaderEditorKey, setForceUpdateHeaderEditorKey] = useState<number>(0); const [forceUpdateHeaderEditorKey, setForceUpdateHeaderEditorKey] = useState<number>(0);
const { updateKey: forceUpdateKey } = useRequestUpdateKey(activeRequest.id ?? null); const { updateKey: forceUpdateKey } = useRequestUpdateKey(activeRequest.id ?? null);
const contentType = useContentTypeFromHeaders(activeRequest.headers); const contentType = useContentTypeFromHeaders(activeRequest.headers);
@@ -298,6 +300,14 @@ export const RequestPane = memo(function RequestPane({
const { updateKey } = useRequestUpdateKey(activeRequestId ?? null); const { updateKey } = useRequestUpdateKey(activeRequestId ?? null);
const importCurl = useImportCurl(); const importCurl = useImportCurl();
const activeTab = activeTabs[activeRequestId] ?? DEFAULT_TAB;
const setActiveTab = useCallback(
(tab: string) => {
setActiveTabs((r) => ({ ...r, [activeRequest.id]: tab }));
},
[activeRequest.id, setActiveTabs],
);
useRequestEditorEvent('request_pane.focus_tab', () => { useRequestEditorEvent('request_pane.focus_tab', () => {
setActiveTab(TAB_PARAMS); setActiveTab(TAB_PARAMS);
}); });

View File

@@ -1,7 +1,7 @@
import type { HttpRequest } from '@yaakapp/api'; import type { HttpRequest } from '@yaakapp/api';
import classNames from 'classnames'; import classNames from 'classnames';
import type { CSSProperties } from 'react'; import type { CSSProperties } from 'react';
import { memo, useMemo } from 'react'; import { memo, useCallback, useMemo } from 'react';
import { createGlobalState } from 'react-use'; import { createGlobalState } from 'react-use';
import { useContentTypeFromHeaders } from '../hooks/useContentTypeFromHeaders'; import { useContentTypeFromHeaders } from '../hooks/useContentTypeFromHeaders';
import { usePinnedHttpResponse } from '../hooks/usePinnedHttpResponse'; import { usePinnedHttpResponse } from '../hooks/usePinnedHttpResponse';
@@ -34,18 +34,30 @@ interface Props {
activeRequest: HttpRequest; activeRequest: HttpRequest;
} }
const useActiveTab = createGlobalState<string>('body'); const useActiveTab = createGlobalState<Record<string, string>>({});
const TAB_BODY = 'body';
const TAB_HEADERS = 'headers';
const TAB_INFO = 'info';
const DEFAULT_TAB = TAB_BODY;
export const ResponsePane = memo(function ResponsePane({ style, className, activeRequest }: Props) { export const ResponsePane = memo(function ResponsePane({ style, className, activeRequest }: Props) {
const { activeResponse, setPinnedResponseId, responses } = usePinnedHttpResponse(activeRequest); const { activeResponse, setPinnedResponseId, responses } = usePinnedHttpResponse(activeRequest);
const [viewMode, setViewMode] = useResponseViewMode(activeResponse?.requestId); const [viewMode, setViewMode] = useResponseViewMode(activeResponse?.requestId);
const [activeTab, setActiveTab] = useActiveTab(); const [activeTabs, setActiveTabs] = useActiveTab();
const contentType = useContentTypeFromHeaders(activeResponse?.headers ?? null); const contentType = useContentTypeFromHeaders(activeResponse?.headers ?? null);
const activeTab = activeTabs[activeRequest.id] ?? DEFAULT_TAB;
const setActiveTab = useCallback(
(tab: string) => {
setActiveTabs((r) => ({ ...r, [activeRequest.id]: tab }));
},
[activeRequest.id, setActiveTabs],
);
const tabs = useMemo<TabItem[]>( const tabs = useMemo<TabItem[]>(
() => [ () => [
{ {
value: 'body', value: TAB_BODY,
label: 'Preview Mode', label: 'Preview Mode',
options: { options: {
value: viewMode, value: viewMode,
@@ -57,6 +69,7 @@ export const ResponsePane = memo(function ResponsePane({ style, className, activ
}, },
}, },
{ {
value: TAB_HEADERS,
label: ( label: (
<div className="flex items-center"> <div className="flex items-center">
Headers Headers
@@ -65,11 +78,10 @@ export const ResponsePane = memo(function ResponsePane({ style, className, activ
/> />
</div> </div>
), ),
value: 'headers',
}, },
{ {
value: TAB_INFO,
label: 'Info', label: 'Info',
value: 'info',
}, },
], ],
[activeResponse?.headers, contentType, setViewMode, viewMode], [activeResponse?.headers, contentType, setViewMode, viewMode],

View File

@@ -1,6 +1,6 @@
import classNames from 'classnames'; import classNames from 'classnames';
import type { ReactNode } from 'react'; import type { ReactNode } from 'react';
import { memo, useCallback, useEffect, useRef } from 'react'; import { memo, useCallback, useRef } from 'react';
import { Icon } from '../Icon'; import { Icon } from '../Icon';
import type { RadioDropdownProps } from '../RadioDropdown'; import type { RadioDropdownProps } from '../RadioDropdown';
import { RadioDropdown } from '../RadioDropdown'; import { RadioDropdown } from '../RadioDropdown';
@@ -60,11 +60,6 @@ export function Tabs({
[onChangeValue], [onChangeValue],
); );
useEffect(() => {
if (value === undefined) return;
handleTabChange(value);
}, [handleTabChange, value]);
return ( return (
<div <div
ref={ref} ref={ref}