Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spike: remove part of multiple abstraction-[INS-4911] #8362

Draft
wants to merge 49 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
7c5f285
feat: multiple tabs
CurryYangxx Nov 6, 2024
0c442c1
fix: lint error
CurryYangxx Nov 6, 2024
e8d0cd1
fix: type error
CurryYangxx Nov 6, 2024
d4afe9e
fix: ui border align
CurryYangxx Nov 7, 2024
3532f72
feat: sync with db
CurryYangxx Nov 7, 2024
7b047bb
feat: sync with database
CurryYangxx Nov 7, 2024
9ac36f8
ui improvement
CurryYangxx Nov 11, 2024
e154512
fix: mock route display
CurryYangxx Nov 11, 2024
c217731
add dropdown
CurryYangxx Nov 12, 2024
d6d24c2
+ button
CurryYangxx Nov 12, 2024
522ec6d
move search box to center
CurryYangxx Nov 14, 2024
35dc4fd
fix: cannot del request tab
CurryYangxx Nov 14, 2024
860590b
fix ui
CurryYangxx Nov 15, 2024
1941ba6
tab background improvement
CurryYangxx Nov 15, 2024
cda2967
change tab background
CurryYangxx Nov 18, 2024
a31c195
feat: add list scroll
CurryYangxx Nov 18, 2024
6a5682e
ui improvement
CurryYangxx Nov 18, 2024
61756fa
feat: add tab contextmenu
CurryYangxx Nov 20, 2024
4a70830
modify menu text
CurryYangxx Nov 20, 2024
8aa8e90
fix(ui): tab disappear in panelgroup
CurryYangxx Nov 21, 2024
a388ad0
feat: optimize tablist scroll button
CurryYangxx Nov 21, 2024
fdb0d42
add context menu enum
CurryYangxx Nov 21, 2024
ff45756
del log
CurryYangxx Nov 25, 2024
f7fb6e3
fix: rename workspace
CurryYangxx Nov 26, 2024
8ff85a9
feat: scroll into view if needed
CurryYangxx Nov 27, 2024
f7e8c88
fix: runner request list not update after switch tab
CurryYangxx Nov 27, 2024
ca60479
fix: runner not update
CurryYangxx Nov 28, 2024
3b6c4b5
feat: use different tab if for collection runner and folder runner
CurryYangxx Nov 28, 2024
c354037
fix: update tab data after move request or folder
CurryYangxx Dec 2, 2024
0bcc84b
fix: database test
CurryYangxx Dec 2, 2024
87370e8
feat: support drag and drop
CurryYangxx Dec 3, 2024
951d589
fix: ui
CurryYangxx Dec 3, 2024
151e0b6
cr feedback
CurryYangxx Dec 5, 2024
50727d4
fix tab update
CurryYangxx Dec 9, 2024
ab82e60
runner improvements (multiple tabs)-[INS-4779] (#8244)
CurryYangxx Dec 27, 2024
a8523a2
remove debugger
CurryYangxx Jan 7, 2025
440591d
use own debounce instead lodash
CurryYangxx Jan 7, 2025
67942c8
feat: move runner keep log to context
CurryYangxx Jan 7, 2025
9add6e9
convert eventbus type enum to union
CurryYangxx Jan 9, 2025
e902939
reduce duplicate useInsomniaTabContext
CurryYangxx Jan 9, 2025
62a1028
fix search bar style
CurryYangxx Jan 9, 2025
c0415c7
covert enum to union
CurryYangxx Jan 13, 2025
554dfa4
del log
CurryYangxx Jan 13, 2025
75c74da
feat(tabs): keep connection for tabs-[INS-4778] (#8266)
CurryYangxx Jan 13, 2025
8e3b7a8
fix: tab icon
CurryYangxx Jan 14, 2025
faba8f3
uppercase
CurryYangxx Jan 22, 2025
8870e59
test: multiple tab (#8304)
CurryYangxx Feb 10, 2025
a2ee656
remove abstraction
CurryYangxx Feb 12, 2025
fc39ba7
fix: type check
CurryYangxx Feb 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/insomnia-inso/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"sourceMap": true,
/* Runs in the DOM NOTE: this is inconsistent with reality */
"lib": [
"ES2020",
"ES2023",
"DOM",
"DOM.Iterable"
],
Expand Down
2 changes: 1 addition & 1 deletion packages/insomnia-sdk/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"jsx": "react",
/* If your code runs in the DOM: */
"lib": [
"es2022",
"es2023",
"dom",
"dom.iterable"
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,22 +99,22 @@ test.describe('Dashboard', async () => {
await page.getByTestId('project').click();

// Rename document
await page.getByLabel('my-spec.yaml').getByRole('button').click();
await page.getByLabel('Files').getByLabel('my-spec.yaml').getByRole('button').click();
await page.getByRole('menuitem', { name: 'Rename' }).click();
await page.locator('text=Rename DocumentName Rename >> input[type="text"]').fill('test123');
await page.click('#root button:has-text("Rename")');
await expect(page.locator('.app')).toContainText('test123');

// Duplicate document
await page.getByLabel('test123').getByRole('button').click();
await page.getByLabel('Files').getByLabel('test123').getByRole('button').click();
await page.getByRole('menuitem', { name: 'Duplicate' }).click();
await page.locator('input[name="name"]').fill('test123-duplicate');
await page.click('[role="dialog"] button:has-text("Duplicate")');

await page.getByTestId('project').click();

// Delete document
await page.getByLabel('test123-duplicate').getByRole('button').click();
await page.getByLabel('Files').getByLabel('test123-duplicate').getByRole('button').click();
await page.getByRole('menuitem', { name: 'Delete' }).click();
await page.getByRole('button', { name: 'Delete' }).click();
// @TODO: Re-enable - Requires mocking VCS operations
Expand All @@ -141,15 +141,15 @@ test.describe('Dashboard', async () => {
await expect(page.locator('.app')).toContainText('test123');

// Duplicate collection
await page.getByLabel('test123').getByRole('button').click();
await page.getByLabel('Files').getByLabel('test123').getByRole('button').click();
await page.getByRole('menuitem', { name: 'Duplicate' }).click();
await page.locator('input[name="name"]').fill('test123-duplicate');
await page.click('[role="dialog"] button:has-text("Duplicate")');

await page.getByTestId('project').click();

// Delete collection
await page.getByLabel('test123-duplicate').getByRole('button').click();
await page.getByLabel('Files').getByLabel('test123-duplicate').getByRole('button').click();
await page.getByRole('menuitem', { name: 'Delete' }).click();
await page.getByRole('button', { name: 'Delete' }).click();
// @TODO: Re-enable - Requires mocking VCS operations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ test.describe('design document operations', async () => {
await page.getByPlaceholder('my-spec.yaml').fill('jurassic park');
await page.getByPlaceholder('my-spec.yaml').press('Enter');
await page.getByTestId('project').click();
await page.getByLabel('jurassic park').click();
await page.getByLabel('Files').getByLabel('jurassic park').click();
});

test('can delete a test suite with confirmation modal', async ({ page }) => {
Expand Down
88 changes: 88 additions & 0 deletions packages/insomnia-smoke-test/tests/smoke/insomnia-tab.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { expect } from '@playwright/test';

import { test } from '../../playwright/test';

const DEFAULT_REQUEST_NAME = 'New Request';

test.describe('multiple-tab feature test', () => {
test.slow(process.platform === 'darwin' || process.platform === 'win32', 'Slow app start on these platforms');

test.beforeEach(async ({ page }) => {
await page.getByLabel('Create in project').click();
await page.getByLabel('Request collection', { exact: true }).click();
await page.getByRole('button', { name: 'Create', exact: true }).click();
});

test('add tab & close tab', async ({ page }) => {
await page.getByLabel('Create in collection').click();
await page.getByLabel('HTTP Request').click();
const tab = await page.getByLabel('Insomnia Tabs').getByLabel(`tab-${DEFAULT_REQUEST_NAME}`, { exact: true });
expect(tab).toBeVisible();
expect(await tab.getAttribute('data-selected')).toBe('true');
await tab.getByRole('button').click();
await expect(tab).toBeHidden();
});

test('active tab sync with the sidebar active request', async ({ page }) => {
await page.getByLabel('Create in collection').click();
await page.getByLabel('HTTP Request').click();
await page.getByTestId('New Request').dblclick();
await page.getByRole('textbox', { name: 'GET New Request' }).fill('New Request A');
await page.getByLabel('Create in collection').click();
await page.getByLabel('HTTP Request').click();
await page.getByTestId('New Request').dblclick();
await page.getByRole('textbox', { name: 'GET New Request' }).fill('New Request B');
await page.getByTestId('New Request A').click();
await page.waitForTimeout(1000);
const tabA = await page.getByLabel('Insomnia Tabs').getByLabel('tab-New Request A', { exact: true });
expect(await tabA.getAttribute('data-selected')).toBe('true');
await page.getByTestId('New Request B').click();
await page.waitForTimeout(1000);
const tabB = await page.getByLabel('Insomnia Tabs').getByLabel('tab-New Request B', { exact: true });
expect(await tabB.getAttribute('data-selected')).toBe('true');
});

test('close tab after delete a request', async ({ page }) => {
await page.getByLabel('Create in collection').click();
await page.getByLabel('HTTP Request').click();
const tab = await page.getByLabel('Insomnia Tabs').getByLabel(`tab-${DEFAULT_REQUEST_NAME}`, { exact: true });
expect(tab).toBeVisible();
await page.getByTestId('Dropdown-New-Request').click();
await page.getByLabel('Delete').click();
await page.getByRole('button', { name: 'Delete', exact: true }).click();
await expect(tab).toBeHidden();
});

test('change icon after change request method', async ({ page }) => {
await page.getByLabel('Create in collection').click();
await page.getByLabel('HTTP Request').click();
await page.waitForTimeout(1000);
expect(await page.getByLabel('Insomnia Tabs').getByLabel('Tab Tag').innerText()).toEqual('GET');
await page.getByLabel('Request Method').click();
await page.getByRole('button', { name: 'POST' }).click();
await page.waitForTimeout(1000);
expect(await page.getByLabel('Insomnia Tabs').getByLabel('Tab Tag').innerText()).toEqual('POST');
});

test('click + button to add a new request', async ({ page }) => {
await page.getByLabel('Tab Plus').click();
await page.getByRole('menuitem', { name: 'add request to current' }).click();
await page.getByTestId(DEFAULT_REQUEST_NAME).click();
await page.getByTestId(DEFAULT_REQUEST_NAME).dblclick();
await page.getByRole('textbox', { name: 'GET New Request' }).fill('New Request A');
await page.getByTestId('project').click();
await page.getByLabel('Create in project').click();
await page.getByLabel('Request collection', { exact: true }).click();
await page.getByPlaceholder('My Collection').fill('Test add tab collection');
await page.getByRole('button', { name: 'Create', exact: true }).click();
await page.waitForTimeout(1000);
await page.getByLabel('Tab Plus').click();
await page.getByRole('menuitem', { name: 'add request to other' }).click();
await page.getByLabel('Select Workspace').selectOption({ label: 'My Collection' });
await page.getByRole('dialog').getByRole('button', { name: 'Add' }).click();
await page.waitForTimeout(1000);
expect(await page.getByTestId('workspace-context-dropdown').innerText()).toEqual('My Collection');
await page.getByTestId(DEFAULT_REQUEST_NAME).click();
});

});
24 changes: 12 additions & 12 deletions packages/insomnia/src/common/__tests__/database.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ describe('onChange()', () => {
name: 'bar',
});
expect(changesSeen).toEqual([
[['insert', newDoc, false]],
[['update', updatedDoc, false]],
[['insert', newDoc, false, []]],
[['update', updatedDoc, false, [{ name: 'bar' }]]],
]);
db.offChange(callback);
await models.request.create(doc);
Expand Down Expand Up @@ -71,16 +71,16 @@ describe('bufferChanges()', () => {
await db.flushChanges();
expect(changesSeen).toEqual([
[
['insert', newDoc, false],
['update', updatedDoc, false],
['insert', newDoc, false, []],
['update', updatedDoc, false, [true]],
],
]);
// Assert no more changes seen after flush again
await db.flushChanges();
expect(changesSeen).toEqual([
[
['insert', newDoc, false],
['update', updatedDoc, false],
['insert', newDoc, false, []],
['update', updatedDoc, false, [true]],
],
]);
});
Expand All @@ -106,8 +106,8 @@ describe('bufferChanges()', () => {
await new Promise(resolve => setTimeout(resolve, 1500));
expect(changesSeen).toEqual([
[
['insert', newDoc, false],
['update', updatedDoc, false],
['insert', newDoc, false, []],
['update', updatedDoc, false, [true]],
],
]);
});
Expand All @@ -132,8 +132,8 @@ describe('bufferChanges()', () => {
await new Promise(resolve => setTimeout(resolve, 1000));
expect(changesSeen).toEqual([
[
['insert', newDoc, false],
['update', updatedDoc, false],
['insert', newDoc, false, []],
['update', updatedDoc, false, [true]],
],
]);
});
Expand Down Expand Up @@ -166,8 +166,8 @@ describe('bufferChangesIndefinitely()', () => {
await db.flushChanges();
expect(changesSeen).toEqual([
[
['insert', newDoc, false],
['update', updatedDoc, false],
['insert', newDoc, false, []],
['update', updatedDoc, false, [true]],
],
]);
});
Expand Down
14 changes: 8 additions & 6 deletions packages/insomnia/src/common/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export const database = {
},
...patches,
);
return database.update<T>(doc);
return database.update<T>(doc, false, patches);
},

/** duplicate doc and its decendents recursively */
Expand Down Expand Up @@ -524,7 +524,7 @@ export const database = {
notifyOfChange('remove', doc, fromSync);
},

update: async function<T extends BaseModel>(doc: T, fromSync = false) {
update: async function <T extends BaseModel>(doc: T, fromSync = false, patches: Patch<T>[] = []) {
if (db._empty) {
return _send<T>('update', ...arguments);
}
Expand All @@ -550,7 +550,7 @@ export const database = {

resolve(docWithDefaults);
// NOTE: This needs to be after we resolve
notifyOfChange('update', docWithDefaults, fromSync);
notifyOfChange('update', docWithDefaults, fromSync, patches);
},
);
});
Expand Down Expand Up @@ -698,7 +698,8 @@ let bufferChangesId = 1;
export type ChangeBufferEvent<T extends BaseModel = BaseModel> = [
event: ChangeType,
doc: T,
fromSync: boolean
fromSync: boolean,
patches: Patch<T>[],
];

let changeBuffer: ChangeBufferEvent[] = [];
Expand All @@ -709,10 +710,11 @@ let changeListeners: ChangeListener[] = [];

/** push changes into the buffer, so that changeListeners can get change contents when database.flushChanges is called,
* this method should be called whenever a document change happens */
async function notifyOfChange<T extends BaseModel>(event: ChangeType, doc: T, fromSync: boolean) {
async function notifyOfChange<T extends BaseModel>(event: ChangeType, doc: T, fromSync: boolean, patches: Patch<T>[] = []) {
const updatedDoc = doc;

changeBuffer.push([event, updatedDoc, fromSync]);
// TODO: Use object is better than array
changeBuffer.push([event, updatedDoc, fromSync, patches]);

// Flush right away if we're not buffering
if (!bufferingChanges) {
Expand Down
27 changes: 21 additions & 6 deletions packages/insomnia/src/main/ipc/electron.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ export type MainOnChannels =
| 'restart'
| 'set-hidden-window-busy-status'
| 'setMenuBarVisibility'
| 'show-context-menu'
| 'show-nunjucks-context-menu'
| 'showContextMenu'
| 'showItemInFolder'
| 'showOpenDialog'
| 'showSaveDialog'
Expand All @@ -73,7 +74,8 @@ export type MainOnChannels =
export type RendererOnChannels =
'clear-all-models'
| 'clear-model'
| 'context-menu-command'
| 'nunjucks-context-menu-command'
| 'contextMenuCommand'
| 'grpc.data'
| 'grpc.end'
| 'grpc.error'
Expand Down Expand Up @@ -114,10 +116,10 @@ const getTemplateValue = (arg: NunjucksParsedTagArg) => {
return arg.defaultValue;
};
export function registerElectronHandlers() {
ipcMainOn('show-context-menu', (event, options: { key: string; nunjucksTag: ReturnType<typeof extractNunjucksTagFromCoords> }) => {
ipcMainOn('show-nunjucks-context-menu', (event, options: { key: string; nunjucksTag: ReturnType<typeof extractNunjucksTagFromCoords> }) => {
const { key, nunjucksTag } = options;
const sendNunjuckTagContextMsg = (type: NunjucksTagContextMenuAction) => {
event.sender.send('context-menu-command', { key, nunjucksTag: { ...nunjucksTag, type } });
event.sender.send('nunjucks-context-menu-command', { key, nunjucksTag: { ...nunjucksTag, type } });
};
try {
const baseTemplate: MenuItemConstructorOptions[] = nunjucksTag ?
Expand Down Expand Up @@ -170,7 +172,7 @@ export function registerElectronHandlers() {
{
click: () => {
const tag = `{% ${l.templateTag.name} ${l.templateTag.args?.map(getTemplateValue).join(', ')} %}`;
event.sender.send('context-menu-command', { key, tag });
event.sender.send('nunjucks-context-menu-command', { key, tag });
},
} :
{
Expand All @@ -179,7 +181,7 @@ export function registerElectronHandlers() {
click: () => {
const additionalTagFields = additionalArgs.length ? ', ' + additionalArgs.map(getTemplateValue).join(', ') : '';
const tag = `{% ${l.templateTag.name} '${action.value}'${additionalTagFields} %}`;
event.sender.send('context-menu-command', { key, tag });
event.sender.send('nunjucks-context-menu-command', { key, tag });
},
})),
}),
Expand Down Expand Up @@ -236,4 +238,17 @@ export function registerElectronHandlers() {
ipcMainOn('getAppPath', event => {
event.returnValue = app.getAppPath();
});

ipcMainOn('showContextMenu', (event, options: { key: string; menuItems: MenuItemConstructorOptions[]; extra?: Record<string, any> }) => {
const menuItems = options.menuItems.map(item => {
return {
...item,
click: () => {
event.sender.send('contextMenuCommand', { key: options.key, label: item.label, extra: options.extra });
},
};
});
const menu = Menu.buildFromTemplate(menuItems);
menu.popup();
});
}
6 changes: 4 additions & 2 deletions packages/insomnia/src/main/ipc/main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as Sentry from '@sentry/electron/main';
import type { MarkerRange } from 'codemirror';
import { app, BrowserWindow, type IpcRendererEvent, shell } from 'electron';
import { app, BrowserWindow, type IpcRendererEvent, type MenuItemConstructorOptions, shell } from 'electron';
import fs from 'fs';

import { APP_START_TIME, LandingPage, SentryMetrics } from '../../common/sentry';
Expand Down Expand Up @@ -39,7 +39,9 @@ export interface RendererToMainBridgeAPI {
curl: CurlBridgeAPI;
trackSegmentEvent: (options: { event: string; properties?: Record<string, unknown> }) => void;
trackPageView: (options: { name: string }) => void;
showContextMenu: (options: { key: string; nunjucksTag?: { template: string; range: MarkerRange } }) => void;
showNunjucksContextMenu: (options: { key: string; nunjucksTag?: { template: string; range: MarkerRange } }) => void;
showContextMenu: (options: { key: string; menuItems: MenuItemConstructorOptions[]; extra?: Record<string, any> }) => void;

database: {
caCertificate: {
create: (options: { parentId: string; path: string }) => Promise<string>;
Expand Down
3 changes: 2 additions & 1 deletion packages/insomnia/src/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ const main: Window['main'] = {
curl,
trackSegmentEvent: options => ipcRenderer.send('trackSegmentEvent', options),
trackPageView: options => ipcRenderer.send('trackPageView', options),
showContextMenu: options => ipcRenderer.send('show-context-menu', options),
showNunjucksContextMenu: options => ipcRenderer.send('show-nunjucks-context-menu', options),
showContextMenu: options => ipcRenderer.send('showContextMenu', options),
database: {
caCertificate: {
create: options => ipcRenderer.invoke('database.caCertificate.create', options),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ export const CodeEditor = memo(forwardRef<CodeEditorHandle, CodeEditorProps>(({
}
};
useEffect(() => {
const unsubscribe = window.main.on('context-menu-command', (_, { key, tag, nunjucksTag }) => {
const unsubscribe = window.main.on('nunjucks-context-menu-command', (_, { key, tag, nunjucksTag }) => {
if (id === key) {
if (nunjucksTag) {
const { type, template, range } = nunjucksTag as nunjucksTagContextMenuOptions;
Expand Down Expand Up @@ -657,10 +657,10 @@ export const CodeEditor = memo(forwardRef<CodeEditorHandle, CodeEditorProps>(({
const nunjucksTag = extractNunjucksTagFromCoords({ left: clientX, top: clientY }, codeMirror);
if (nunjucksTag) {
// show context menu for nunjucks tag
window.main.showContextMenu({ key: id, nunjucksTag });
window.main.showNunjucksContextMenu({ key: id, nunjucksTag });
}
} else {
window.main.showContextMenu({ key: id });
window.main.showNunjucksContextMenu({ key: id });
}
}}
>
Expand Down
Loading
Loading