mirror of
https://github.com/Kong/insomnia
synced 2024-11-08 14:49:53 +00:00
move env editor to folder tab (#7534)
* move env editor to folder tab * remove old unused test
This commit is contained in:
parent
9db2d42feb
commit
8648f49d4d
@ -144,80 +144,5 @@ test.describe('Debug-Sidebar', async () => {
|
|||||||
await page.getByRole('menuitemradio', { name: 'Http Request' }).click();
|
await page.getByRole('menuitemradio', { name: 'Http Request' }).click();
|
||||||
await page.getByLabel('Request Collection').getByRole('row', { name: 'New Request' }).click();
|
await page.getByLabel('Request Collection').getByRole('row', { name: 'New Request' }).click();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Add new string variable via environment overrides', async ({ page }) => {
|
|
||||||
// Create new Folder
|
|
||||||
await page.getByLabel('Create in collection').click();
|
|
||||||
await page.getByLabel('New Folder').click();
|
|
||||||
await page.locator('#prompt-input').fill('New Folder');
|
|
||||||
await page.getByText('New Folder').press('Enter');
|
|
||||||
|
|
||||||
// Open 'New folder' folder
|
|
||||||
const folderLocator = page.getByTestId('Dropdown-New-Folder');
|
|
||||||
const environmentLocator = page.getByRole('menuitemradio', { name: 'Environment' });
|
|
||||||
await folderLocator.click();
|
|
||||||
await environmentLocator.click();
|
|
||||||
|
|
||||||
// Add a new string environment variable
|
|
||||||
const expected = '{ "foo":"bar" }';
|
|
||||||
const editorTextLocator = await page.getByTestId('CodeEditor').getByRole('textbox');
|
|
||||||
const selectAllShortcut = process.platform === 'darwin' ? 'Meta+A' : 'Control+A';
|
|
||||||
await editorTextLocator.press(selectAllShortcut);
|
|
||||||
await editorTextLocator.fill(expected);
|
|
||||||
|
|
||||||
// Close and re-open modal
|
|
||||||
await page.getByText('Close').click();
|
|
||||||
await folderLocator.click();
|
|
||||||
await environmentLocator.click();
|
|
||||||
|
|
||||||
// Validate expected values persisted
|
|
||||||
const actualRows = await page.getByTestId('CodeEditor').locator('.CodeMirror-line').allInnerTexts();
|
|
||||||
expect(actualRows.length).toBeGreaterThan(0);
|
|
||||||
|
|
||||||
const actualJSON = JSON.parse(actualRows.join(' '));
|
|
||||||
expect(actualJSON).toEqual(JSON.parse(expected));
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Add new string variable to an existing environment overrides folder', async ({ page }) => {
|
|
||||||
// Open 'Test Folder' folder
|
|
||||||
const folderLocator = page.getByTestId('Dropdown-test-folder');
|
|
||||||
const environmentLocator = page.getByRole('menuitemradio', { name: 'Environment' });
|
|
||||||
await folderLocator.click();
|
|
||||||
await environmentLocator.click();
|
|
||||||
|
|
||||||
// Add a new string environment variable to existing overrides
|
|
||||||
|
|
||||||
// 1. Retrieve current editor rows
|
|
||||||
const editorLocator = page.getByTestId('CodeEditor').locator('.CodeMirror-line');
|
|
||||||
const rows = await editorLocator.allInnerTexts();
|
|
||||||
|
|
||||||
// 2. Merge rows and convert to JSON
|
|
||||||
const editorJSON = JSON.parse(rows.join(' '));
|
|
||||||
|
|
||||||
// 3. Modify JSON with new string environment variable
|
|
||||||
editorJSON.REQUEST = 'HTTP';
|
|
||||||
const expected = editorJSON;
|
|
||||||
|
|
||||||
// 4. Apply new JSON to editor
|
|
||||||
const editorTextLocator = await page.getByTestId('CodeEditor').getByRole('textbox');
|
|
||||||
const selectAllShortcut = process.platform === 'darwin' ? 'Meta+A' : 'Control+A';
|
|
||||||
await editorTextLocator.press(selectAllShortcut);
|
|
||||||
await editorTextLocator.fill(JSON.stringify(expected));
|
|
||||||
|
|
||||||
// Close and re-open Modal
|
|
||||||
await page.getByText('Close').click();
|
|
||||||
await folderLocator.click();
|
|
||||||
await environmentLocator.click();
|
|
||||||
|
|
||||||
// Validate expected values persisted
|
|
||||||
const actualRows = await editorLocator.allInnerTexts();
|
|
||||||
expect(actualRows.length).toBeGreaterThan(0);
|
|
||||||
|
|
||||||
const actualJSON = JSON.parse(actualRows.join(' '));
|
|
||||||
expect(actualJSON).toEqual(expected);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO: more scenarios will be added in follow-up iterations of increasing test coverage
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -91,7 +91,7 @@ export interface CodeEditorProps {
|
|||||||
noLint?: boolean;
|
noLint?: boolean;
|
||||||
noMatchBrackets?: boolean;
|
noMatchBrackets?: boolean;
|
||||||
noStyleActiveLine?: boolean;
|
noStyleActiveLine?: boolean;
|
||||||
// used only for saving env editor state
|
// used only for saving env editor state, focusEvent doesn't work well
|
||||||
onBlur?: (e: FocusEvent) => void;
|
onBlur?: (e: FocusEvent) => void;
|
||||||
onChange?: (value: string) => void;
|
onChange?: (value: string) => void;
|
||||||
onPaste?: (value: string) => string;
|
onPaste?: (value: string) => string;
|
||||||
|
@ -19,7 +19,6 @@ import { type DropdownHandle, type DropdownProps } from '../base/dropdown';
|
|||||||
import { Icon } from '../icon';
|
import { Icon } from '../icon';
|
||||||
import { showError, showModal, showPrompt } from '../modals';
|
import { showError, showModal, showPrompt } from '../modals';
|
||||||
import { AskModal } from '../modals/ask-modal';
|
import { AskModal } from '../modals/ask-modal';
|
||||||
import { EnvironmentEditModal } from '../modals/environment-edit-modal';
|
|
||||||
import { PasteCurlModal } from '../modals/paste-curl-modal';
|
import { PasteCurlModal } from '../modals/paste-curl-modal';
|
||||||
import { RequestGroupSettingsModal } from '../modals/request-group-settings-modal';
|
import { RequestGroupSettingsModal } from '../modals/request-group-settings-modal';
|
||||||
interface Props extends Partial<DropdownProps> {
|
interface Props extends Partial<DropdownProps> {
|
||||||
@ -226,12 +225,6 @@ export const RequestGroupActionsDropdown = ({
|
|||||||
hint: hotKeyRegistry.request_createHTTP,
|
hint: hotKeyRegistry.request_createHTTP,
|
||||||
action: () => handleRequestGroupDuplicate(),
|
action: () => handleRequestGroupDuplicate(),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: 'Environment',
|
|
||||||
name: 'Environment',
|
|
||||||
icon: 'code',
|
|
||||||
action: () => showModal(EnvironmentEditModal, { requestGroup }),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: 'Rename',
|
id: 'Rename',
|
||||||
name: 'Rename',
|
name: 'Rename',
|
||||||
|
@ -1,86 +0,0 @@
|
|||||||
import React, { forwardRef, useImperativeHandle, useRef, useState } from 'react';
|
|
||||||
|
|
||||||
import { RequestGroup } from '../../../models/request-group';
|
|
||||||
import { useRequestGroupPatcher } from '../../hooks/use-request';
|
|
||||||
import { Modal, type ModalHandle, ModalProps } from '../base/modal';
|
|
||||||
import { ModalBody } from '../base/modal-body';
|
|
||||||
import { ModalFooter } from '../base/modal-footer';
|
|
||||||
import { ModalHeader } from '../base/modal-header';
|
|
||||||
import { EnvironmentEditor, EnvironmentEditorHandle } from '../editors/environment-editor';
|
|
||||||
|
|
||||||
interface State {
|
|
||||||
requestGroup: RequestGroup | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface EnvironmentEditModalOptions {
|
|
||||||
requestGroup: RequestGroup;
|
|
||||||
}
|
|
||||||
export interface EnvironmentEditModalHandle {
|
|
||||||
show: (options: EnvironmentEditModalOptions) => void;
|
|
||||||
hide: () => void;
|
|
||||||
}
|
|
||||||
export const EnvironmentEditModal = forwardRef<EnvironmentEditModalHandle, ModalProps>((props, ref) => {
|
|
||||||
const modalRef = useRef<ModalHandle>(null);
|
|
||||||
const environmentEditorRef = useRef<EnvironmentEditorHandle>(null);
|
|
||||||
const [state, setState] = useState<State>({
|
|
||||||
requestGroup: null,
|
|
||||||
});
|
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
|
||||||
hide: () => {
|
|
||||||
modalRef.current?.hide();
|
|
||||||
},
|
|
||||||
show: ({ requestGroup }) => {
|
|
||||||
setState(state => ({ ...state, requestGroup }));
|
|
||||||
modalRef.current?.show();
|
|
||||||
},
|
|
||||||
}), []);
|
|
||||||
|
|
||||||
const patchGroup = useRequestGroupPatcher();
|
|
||||||
const { requestGroup } = state;
|
|
||||||
const environmentInfo = {
|
|
||||||
object: requestGroup ? requestGroup.environment : {},
|
|
||||||
propertyOrder: requestGroup && requestGroup.environmentPropertyOrder,
|
|
||||||
};
|
|
||||||
|
|
||||||
const saveChanges = () => {
|
|
||||||
setState({ requestGroup });
|
|
||||||
if (environmentEditorRef.current?.isValid()) {
|
|
||||||
try {
|
|
||||||
const data = environmentEditorRef.current?.getValue();
|
|
||||||
if (state.requestGroup && data) {
|
|
||||||
patchGroup(state.requestGroup._id, {
|
|
||||||
environment: data.object,
|
|
||||||
environmentPropertyOrder: data.propertyOrder,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.warn('Failed to update environment', err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal ref={modalRef} tall {...props} onHide={saveChanges}>
|
|
||||||
<ModalHeader>Environment Overrides (JSON Format)</ModalHeader>
|
|
||||||
<ModalBody noScroll className="pad-top-sm">
|
|
||||||
<EnvironmentEditor
|
|
||||||
ref={environmentEditorRef}
|
|
||||||
key={requestGroup ? requestGroup._id : 'n/a'}
|
|
||||||
environmentInfo={environmentInfo}
|
|
||||||
onBlur={saveChanges}
|
|
||||||
/>
|
|
||||||
</ModalBody>
|
|
||||||
<ModalFooter>
|
|
||||||
<div className="margin-left italic txt-sm">
|
|
||||||
* Used to override data in the global environment
|
|
||||||
</div>
|
|
||||||
<button className="btn" onClick={() => modalRef.current?.hide()}>
|
|
||||||
Close
|
|
||||||
</button>
|
|
||||||
</ModalFooter>
|
|
||||||
</Modal >
|
|
||||||
);
|
|
||||||
});
|
|
||||||
EnvironmentEditModal.displayName = 'EnvironmentEditModal';
|
|
@ -1,4 +1,4 @@
|
|||||||
import React, { FC, useState } from 'react';
|
import React, { FC, useRef, useState } from 'react';
|
||||||
import { Tab, TabList, TabPanel, Tabs } from 'react-aria-components';
|
import { Tab, TabList, TabPanel, Tabs } from 'react-aria-components';
|
||||||
import { useRouteLoaderData } from 'react-router-dom';
|
import { useRouteLoaderData } from 'react-router-dom';
|
||||||
|
|
||||||
@ -8,6 +8,7 @@ import { useActiveRequestSyncVCSVersion, useGitVCSVersion } from '../../hooks/us
|
|||||||
import { RequestGroupLoaderData } from '../../routes/request-group';
|
import { RequestGroupLoaderData } from '../../routes/request-group';
|
||||||
import { WorkspaceLoaderData } from '../../routes/workspace';
|
import { WorkspaceLoaderData } from '../../routes/workspace';
|
||||||
import { AuthWrapper } from '../editors/auth/auth-wrapper';
|
import { AuthWrapper } from '../editors/auth/auth-wrapper';
|
||||||
|
import { EnvironmentEditor, EnvironmentEditorHandle } from '../editors/environment-editor';
|
||||||
import { RequestHeadersEditor } from '../editors/request-headers-editor';
|
import { RequestHeadersEditor } from '../editors/request-headers-editor';
|
||||||
import { RequestScriptEditor } from '../editors/request-script-editor';
|
import { RequestScriptEditor } from '../editors/request-script-editor';
|
||||||
import { ErrorBoundary } from '../error-boundary';
|
import { ErrorBoundary } from '../error-boundary';
|
||||||
@ -25,7 +26,24 @@ export const RequestGroupPane: FC<{ settings: Settings }> = ({ settings }) => {
|
|||||||
const uniqueKey = `${activeEnvironment?.modified}::${activeRequestGroup._id}::${gitVersion}::${activeRequestSyncVersion}`;
|
const uniqueKey = `${activeEnvironment?.modified}::${activeRequestGroup._id}::${gitVersion}::${activeRequestSyncVersion}`;
|
||||||
const folderHeaders = activeRequestGroup?.headers || [];
|
const folderHeaders = activeRequestGroup?.headers || [];
|
||||||
const headersCount = folderHeaders.filter(h => !h.disabled)?.length || 0;
|
const headersCount = folderHeaders.filter(h => !h.disabled)?.length || 0;
|
||||||
|
const environmentEditorRef = useRef<EnvironmentEditorHandle>(null);
|
||||||
|
const patchGroup = useRequestGroupPatcher();
|
||||||
|
|
||||||
|
const saveChanges = () => {
|
||||||
|
if (environmentEditorRef.current?.isValid()) {
|
||||||
|
try {
|
||||||
|
const data = environmentEditorRef.current?.getValue();
|
||||||
|
if (activeRequestGroup && data) {
|
||||||
|
patchGroup(activeRequestGroup._id, {
|
||||||
|
environment: data.object,
|
||||||
|
environmentPropertyOrder: data.propertyOrder,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('Failed to update environment', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Tabs aria-label='Request group tabs' className="flex-1 w-full h-full flex flex-col">
|
<Tabs aria-label='Request group tabs' className="flex-1 w-full h-full flex flex-col">
|
||||||
@ -58,6 +76,12 @@ export const RequestGroupPane: FC<{ settings: Settings }> = ({ settings }) => {
|
|||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</Tab>
|
</Tab>
|
||||||
|
<Tab
|
||||||
|
className='flex-shrink-0 h-full flex items-center justify-between cursor-pointer gap-2 outline-none select-none px-3 py-1 text-[--hl] aria-selected:text-[--color-font] hover:bg-[--hl-sm] hover:text-[--color-font] aria-selected:bg-[--hl-xs] aria-selected:focus:bg-[--hl-sm] aria-selected:hover:bg-[--hl-sm] focus:bg-[--hl-sm] transition-colors duration-300'
|
||||||
|
id='environment'
|
||||||
|
>
|
||||||
|
Environment
|
||||||
|
</Tab>
|
||||||
<Tab
|
<Tab
|
||||||
className='flex-shrink-0 h-full flex items-center justify-between cursor-pointer gap-2 outline-none select-none px-3 py-1 text-[--hl] aria-selected:text-[--color-font] hover:bg-[--hl-sm] hover:text-[--color-font] aria-selected:bg-[--hl-xs] aria-selected:focus:bg-[--hl-sm] aria-selected:hover:bg-[--hl-sm] focus:bg-[--hl-sm] transition-colors duration-300'
|
className='flex-shrink-0 h-full flex items-center justify-between cursor-pointer gap-2 outline-none select-none px-3 py-1 text-[--hl] aria-selected:text-[--color-font] hover:bg-[--hl-sm] hover:text-[--color-font] aria-selected:bg-[--hl-xs] aria-selected:focus:bg-[--hl-sm] aria-selected:hover:bg-[--hl-sm] focus:bg-[--hl-sm] transition-colors duration-300'
|
||||||
id='docs'
|
id='docs'
|
||||||
@ -145,6 +169,22 @@ export const RequestGroupPane: FC<{ settings: Settings }> = ({ settings }) => {
|
|||||||
</TabPanel>
|
</TabPanel>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
<TabPanel className='w-full flex-1 overflow-y-auto ' id='environment'>
|
||||||
|
<ErrorBoundary
|
||||||
|
key={uniqueKey}
|
||||||
|
errorClassName="font-error pad text-center"
|
||||||
|
>
|
||||||
|
<EnvironmentEditor
|
||||||
|
ref={environmentEditorRef}
|
||||||
|
key={activeRequestGroup ? activeRequestGroup._id : 'n/a'}
|
||||||
|
environmentInfo={{
|
||||||
|
object: activeRequestGroup ? activeRequestGroup.environment : {},
|
||||||
|
propertyOrder: activeRequestGroup && activeRequestGroup.environmentPropertyOrder,
|
||||||
|
}}
|
||||||
|
onBlur={saveChanges}
|
||||||
|
/>
|
||||||
|
</ErrorBoundary>
|
||||||
|
</TabPanel>
|
||||||
<TabPanel className='w-full flex-1 overflow-y-auto ' id='docs'>
|
<TabPanel className='w-full flex-1 overflow-y-auto ' id='docs'>
|
||||||
{activeRequestGroup.description ? (
|
{activeRequestGroup.description ? (
|
||||||
<div>
|
<div>
|
||||||
|
@ -7,7 +7,6 @@ import { AddKeyCombinationModal } from '../components/modals/add-key-combination
|
|||||||
import { AlertModal } from '../components/modals/alert-modal';
|
import { AlertModal } from '../components/modals/alert-modal';
|
||||||
import { AskModal } from '../components/modals/ask-modal';
|
import { AskModal } from '../components/modals/ask-modal';
|
||||||
import { CodePromptModal } from '../components/modals/code-prompt-modal';
|
import { CodePromptModal } from '../components/modals/code-prompt-modal';
|
||||||
import { EnvironmentEditModal } from '../components/modals/environment-edit-modal';
|
|
||||||
import { ErrorModal } from '../components/modals/error-modal';
|
import { ErrorModal } from '../components/modals/error-modal';
|
||||||
import { FilterHelpModal } from '../components/modals/filter-help-modal';
|
import { FilterHelpModal } from '../components/modals/filter-help-modal';
|
||||||
import { GenerateCodeModal } from '../components/modals/generate-code-modal';
|
import { GenerateCodeModal } from '../components/modals/generate-code-modal';
|
||||||
@ -72,10 +71,6 @@ const Modals: FC = () => {
|
|||||||
ref={instance => registerModal(instance, 'ResponseDebugModal')}
|
ref={instance => registerModal(instance, 'ResponseDebugModal')}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<EnvironmentEditModal
|
|
||||||
ref={instance => registerModal(instance, 'EnvironmentEditModal')}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<AddKeyCombinationModal
|
<AddKeyCombinationModal
|
||||||
ref={instance => registerModal(instance, 'AddKeyCombinationModal')}
|
ref={instance => registerModal(instance, 'AddKeyCombinationModal')}
|
||||||
/>
|
/>
|
||||||
|
Loading…
Reference in New Issue
Block a user