-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #16 from NickRimmer/features/workspace-tabs-save
Features/workspace tabs save
- Loading branch information
Showing
20 changed files
with
422 additions
and
224 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
import { WindowApp, WindowMain } from './insomnia/insomnia.types' | ||
|
||
declare global { | ||
interface Window { | ||
app: WindowApp, | ||
main: WindowMain | ||
} | ||
} | ||
|
||
type WindowApp = { | ||
getAppPath: () => string, | ||
getPath: (name: string) => string, | ||
} | ||
|
||
type WindowMain = { | ||
on(channelName: string, callback: (e: any, data: any) => void): (() => void), | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,25 @@ | ||
import * as insomnia from './services/insomnia/connector' | ||
import * as ui from './ui' | ||
import { cleanupWorkspacesAsync } from './services/db' | ||
|
||
const init = () => { | ||
const initAsync = async () => { | ||
// can be used during development, to be able to access insomnia instance from console for experiments | ||
// (global as any).dev = { | ||
// insomnia | ||
// } | ||
|
||
// initialize ui components | ||
ui.render() | ||
await cleanupWorkspacesAsync() | ||
console.log('[plugin-navigator]', 'initialized') | ||
} | ||
|
||
let tries = 0 | ||
const waitForConnection = () => { | ||
const waitForConnectionAsync = async () => { | ||
if (!insomnia.connect()) { | ||
if (tries++ < 25) window.setTimeout(waitForConnection, 200) | ||
if (tries++ < 25) window.setTimeout(waitForConnectionAsync, 200) | ||
else console.error('[plugin-navigator]', 'cannot connect to Insomnia') | ||
} else init() | ||
} else await initAsync() | ||
} | ||
|
||
waitForConnection() | ||
waitForConnectionAsync() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { database } from './db' | ||
import { getState } from '../insomnia/connector/index' | ||
|
||
export const cleanupWorkspacesAsync = async () => { | ||
try { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const existsWorkspaces = Object.values(getState().workspaces).map((x: any) => x._id) | ||
const storedWorkspaces = await database.getAllData() | ||
const removeWorkspaces = storedWorkspaces.filter(x => !existsWorkspaces.includes(x.workspaceId)) | ||
await Promise.all(removeWorkspaces.map(x => database.remove(x))) | ||
} catch (err) { | ||
console.error('[plugin-navigator]', 'cleanupWorkspaces', err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import Datastore from 'nedb' | ||
import * as path from 'path' | ||
|
||
const NeDb = window.require('nedb') | ||
const dbName = 'Plugin.request-navigator' | ||
const dbPath = path.join(window.app.getPath('userData'), `insomnia.${dbName}.db`) | ||
const databaseInternal = new NeDb({ filename: dbPath, autoload: true, corruptAlertThreshold: 0.9, inMemoryOnly: false }) as Datastore | ||
|
||
export const database = databaseInternal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
export type WorkspaceTab = { | ||
requestId: string, | ||
index: number, | ||
isActive?: boolean, | ||
} | ||
|
||
export type Workspace = { | ||
workspaceId: string, | ||
tabs: WorkspaceTab[], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from './db' | ||
export * from './db.types' | ||
export * from './cleanup' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './insomnia-requests' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { DocBaseModel } from '../insomnia/types' | ||
|
||
export const getRequestMethodName = (requestInfo: DocBaseModel) => { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
let method = (requestInfo as any).method | ||
if (!method) { | ||
if (requestInfo.type === 'GrpcRequest') method = 'gRPC' | ||
else method = 'N/A' | ||
} | ||
|
||
return method | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { TabData } from './tabs-panel.types' | ||
|
||
export const useContextMenu = ({ tabs, setTabs, showTabContent }: { | ||
tabs: TabData[], | ||
setTabs: (tabs: TabData[]) => void, | ||
showTabContent: (requestId: string) => void, | ||
}) => { | ||
|
||
const onCloseOthersClicked = (requestId: string): void => { | ||
const tabData = tabs.find(tab => tab.requestId == requestId) | ||
if (!tabData) { | ||
console.error('tab not found', requestId) | ||
return | ||
} | ||
|
||
tabData.isActive = true | ||
const updated = tabs.filter((tab) => tab.requestId === tabData.requestId) | ||
setTabs(updated) | ||
showTabContent(tabData.requestId) | ||
} | ||
|
||
const onClickCloseOnRight = (requestId: string): void => { | ||
const tabData = tabs.find(tab => tab.requestId == requestId) | ||
if (!tabData) { | ||
console.error('tab not found', requestId) | ||
return | ||
} | ||
|
||
const closedTabIndex = tabs.findIndex((tab) => tab.requestId === tabData.requestId) | ||
const updated = tabs.slice(0, closedTabIndex + 1) | ||
|
||
const currentActive = updated.findIndex((tab) => tab.isActive) | ||
if (currentActive == -1) tabData.isActive = true | ||
|
||
setTabs(updated) | ||
showTabContent(tabData.requestId) | ||
} | ||
|
||
const onClickCloseAll = (): void => { | ||
setTabs([]) | ||
} | ||
|
||
return { | ||
onCloseOthersClicked, | ||
onClickCloseOnRight, | ||
onClickCloseAll, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import React, { useEffect } from 'react' | ||
import { isCurrentConnectionStillActive } from '../../services/insomnia/connector/refs-common' | ||
import { TabData } from './tabs-panel.types' | ||
|
||
export const useDropdown = ({ tabs, id }: { tabs: TabData[], id: string }) => { | ||
const [screenSize, setScreenSize] = React.useState<number>(0) | ||
const [collapsedTabs, setCollapsedTabs] = React.useState<TabData[]>([]) | ||
|
||
useEffect(() => { | ||
const handleResize = () => { | ||
if (!isCurrentConnectionStillActive()) { | ||
window.removeEventListener('resize', handleResize) | ||
return | ||
} | ||
setScreenSize(window.innerWidth) | ||
} | ||
window.addEventListener('resize', handleResize) | ||
}, []) | ||
|
||
// when tabs changed or screen size updated - update dropdown view | ||
useEffect(() => { | ||
const root = document.getElementById(id) | ||
const parent = root?.querySelector('.items') | ||
if (!parent) { | ||
return | ||
} | ||
|
||
const children = parent.querySelectorAll('.plugin-request-navigator-tab-button') | ||
if (!children?.length) { | ||
return | ||
} | ||
|
||
const parentRightBound = parent.getBoundingClientRect().right | ||
if (!parentRightBound) { | ||
console.error('[plugin-navigator]', 'parent has no right bound') | ||
return | ||
} | ||
|
||
const tabsToCollapse: TabData[] = [] | ||
children.forEach((element) => { | ||
if (element.getBoundingClientRect().right > parentRightBound) { | ||
tabsToCollapse.push({ | ||
method: element.getAttribute('data-method'), | ||
title: element.getAttribute('data-title'), | ||
requestId: element.getAttribute('data-request-id'), | ||
isActive: element.classList.contains('active') | ||
} as TabData) | ||
} | ||
}) | ||
|
||
setCollapsedTabs(tabsToCollapse) | ||
}, [tabs, screenSize]) | ||
|
||
return { | ||
collapsedTabs, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
import { MutableRefObject, useEffect } from 'react' | ||
import { TabData } from './tabs-panel.types' | ||
import { onRequestSelected } from '../../services/insomnia/events/request-selected' | ||
import { onRequestUpdated } from '../../services/insomnia/events/request-updated' | ||
import { onRequestDeleted } from '../../services/insomnia/events/request-deleted' | ||
import { getAllRequests } from '../../services/insomnia/connector' | ||
import { getRequestMethodName } from '../../services/helpers' | ||
|
||
export const useRequestHandlers = ({ setTabs, tabDataRef }: { setTabs: (tabs: TabData[]) => void, tabDataRef: MutableRefObject<TabData[]> }) => { | ||
// when request selected - add or activate tab | ||
useEffect(() => { | ||
onRequestSelected((doc) => { | ||
const requestId = (doc as any).activeRequestId | ||
if (!requestId) { | ||
console.warn('onRequestSelected', 'unexpected doc, activeRequestId not found', doc) | ||
return | ||
} | ||
|
||
if (!tabDataRef.current.find(tab => tab.requestId == requestId)) { | ||
const requestInfo = getAllRequests()[requestId] | ||
|
||
const method = getRequestMethodName(requestInfo) | ||
const tabData = { isActive: true, requestId, title: requestInfo.name, method } | ||
tabDataRef.current.forEach((x) => x.isActive = false) | ||
setTabs([...tabDataRef.current, tabData]) | ||
} else { | ||
tabDataRef.current.forEach((x) => x.isActive = x.requestId == requestId) | ||
setTabs([...tabDataRef.current]) | ||
} | ||
}) | ||
}, []) | ||
|
||
// when request renamed - renamed tab | ||
useEffect(() => { | ||
onRequestUpdated((doc) => { | ||
const requestId = doc._id | ||
if (!requestId) { | ||
console.warn('onRequestUpdated', 'unexpected doc, request id not found', doc) | ||
return | ||
} | ||
|
||
const updatedList = [...tabDataRef.current] | ||
const tab = updatedList.find(tab => tab.requestId == requestId) | ||
if (!tab) return | ||
|
||
if (tab.title == doc.name) return | ||
tab.title = doc.name | ||
setTabs(updatedList) | ||
}) | ||
}, []) | ||
|
||
// when request removed - remove tab | ||
useEffect(() => { | ||
onRequestDeleted((doc) => { | ||
const requestId = doc._id | ||
if (!requestId) { | ||
console.warn('onRequestUpdated', 'unexpected doc, request id not found', doc) | ||
return | ||
} | ||
|
||
const updatedList = [...tabDataRef.current].filter(tab => tab.requestId != requestId) | ||
setTabs(updatedList) | ||
}) | ||
}, []) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { TabData } from './tabs-panel.types' | ||
|
||
export const useSortable = ({ tabs, setTabs }: { tabs: TabData[], setTabs: (tabs: TabData[]) => void }) => { | ||
const onSortEnd = ({ oldIndex, newIndex }: { oldIndex: number, newIndex: number }): void => { | ||
// move tab from old index to new index | ||
const element = tabs.splice(oldIndex, 1)[0] | ||
tabs.splice(newIndex, 0, element) | ||
setTabs([...tabs]) | ||
} | ||
|
||
return { | ||
onSortEnd, | ||
} | ||
} |
Oops, something went wrong.