Skip to content

Commit

Permalink
Add WebSocketRequest to sidebar and update types (#5048)
Browse files Browse the repository at this point in the history
  • Loading branch information
gatzjames authored and jackkav committed Sep 9, 2022
1 parent fb08a08 commit 815d978
Show file tree
Hide file tree
Showing 12 changed files with 111 additions and 59 deletions.
14 changes: 10 additions & 4 deletions packages/insomnia/src/models/helpers/request-operations.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import { GrpcRequest, isGrpcRequest, isGrpcRequestId } from '../grpc-request';
import * as models from '../index';
import { Request } from '../request';
import { isWebSocketRequest, WebSocketRequest } from '../websocket-request';

export function getById(requestId: string): Promise<Request | GrpcRequest | null> {
return isGrpcRequestId(requestId)
? models.grpcRequest.getById(requestId)
: models.request.getById(requestId);
}

export function remove(request: Request | GrpcRequest) {
return isGrpcRequest(request)
? models.grpcRequest.remove(request)
: models.request.remove(request);
export function remove(request: Request | GrpcRequest | WebSocketRequest) {
if (isGrpcRequest(request)) {
return models.grpcRequest.remove(request);
}
if (isWebSocketRequest(request)) {
return models.websocketRequest.remove(request);
} else {
return models.request.remove(request);
}
}

export function update<T extends object>(request: T, patch: Partial<T> = {}): Promise<T> {
Expand Down
4 changes: 3 additions & 1 deletion packages/insomnia/src/models/websocket-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ export const canSync = false;
export interface BaseWebSocketRequest {
name: string;
url: string;
metaSortKey: number;
}

export type WebSocketRequest = BaseWebSocketRequest & BaseModel;
export type WebSocketRequest = BaseModel & BaseWebSocketRequest & { type: typeof type };

export const isWebSocketRequest = (model: Pick<BaseModel, 'type'>): model is WebSocketRequest => (
model.type === type
Expand All @@ -25,6 +26,7 @@ export const isWebSocketRequest = (model: Pick<BaseModel, 'type'>): model is Web
export const init = (): BaseWebSocketRequest => ({
name: 'New WebSocket Request',
url: '',
metaSortKey: -1 * Date.now(),
});

export const migrate = (doc: WebSocketRequest) => doc;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
} from '../../../common/constants';
import * as models from '../../../models';
import { update } from '../../../models/helpers/request-operations';
import { isRequest } from '../../../models/request';
import { selectActiveRequest } from '../../redux/selectors';
import { Dropdown } from '../base/dropdown/dropdown';
import { DropdownButton } from '../base/dropdown/dropdown-button';
Expand Down Expand Up @@ -46,8 +47,7 @@ export const AuthDropdown: FC = () => {
return;
}

if (!('authentication' in activeRequest)) {
// gRPC Requests don't have `authentication`
if (!isRequest(activeRequest)) {
return;
}

Expand Down Expand Up @@ -86,7 +86,7 @@ export const AuthDropdown: FC = () => {
if (!activeRequest) {
return false;
}
if (!('authentication' in activeRequest)) {
if (!isRequest(activeRequest)) {
return false;
}
return type === (activeRequest.authentication.type || AUTH_NONE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
CONTENT_TYPE_YAML,
getContentTypeName,
} from '../../../common/constants';
import { isWebSocketRequest } from '../../../models/websocket-request';
import { selectActiveRequest } from '../../redux/selectors';
import { Dropdown } from '../base/dropdown/dropdown';
import { DropdownButton } from '../base/dropdown/dropdown-button';
Expand All @@ -38,7 +39,9 @@ const MimeTypeItem: FC<{
mimeType,
onChange,
}) => {
const activeRequest = useSelector(selectActiveRequest);
const request = useSelector(selectActiveRequest);
const activeRequest = request && !isWebSocketRequest(request) ? request : null;

const handleChangeMimeType = useCallback(async (mimeType: string | null) => {
if (!activeRequest) {
return;
Expand Down Expand Up @@ -91,7 +94,8 @@ const MimeTypeItem: FC<{
MimeTypeItem.displayName = DropdownItem.name;

export const ContentTypeDropdown: FC<Props> = ({ onChange }) => {
const activeRequest = useSelector(selectActiveRequest);
const request = useSelector(selectActiveRequest);
const activeRequest = request && !isWebSocketRequest(request) ? request : null;

if (!activeRequest) {
return null;
Expand Down
3 changes: 2 additions & 1 deletion packages/insomnia/src/ui/components/sidebar/dnd.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import * as models from '../../../models';
import { GrpcRequest } from '../../../models/grpc-request';
import { Request } from '../../../models/request';
import { RequestGroup } from '../../../models/request-group';
import { WebSocketRequest } from '../../../models/websocket-request';

export type DnDDragProps = ReturnType<typeof sourceCollect>;
export type DnDDropProps = ReturnType<typeof targetCollect>;
export type DnDProps = DnDDragProps & DnDDropProps;

export interface DragObject {
item?: GrpcRequest | Request | RequestGroup;
item?: GrpcRequest | Request | WebSocketRequest | RequestGroup;
}

export const sourceCollect = (connect: DragSourceConnector, monitor: DragSourceMonitor) => ({
Expand Down
57 changes: 36 additions & 21 deletions packages/insomnia/src/ui/components/sidebar/sidebar-children.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import React, { FC, Fragment } from 'react';
import ReactDOM from 'react-dom';
import { useSelector } from 'react-redux';

import { GrpcRequest, isGrpcRequest } from '../../../models/grpc-request';
import { GrpcRequest } from '../../../models/grpc-request';
import * as models from '../../../models/index';
import { isRequest, Request } from '../../../models/request';
import type { RequestGroup } from '../../../models/request-group';
import { Request } from '../../../models/request';
import { isRequestGroup, RequestGroup } from '../../../models/request-group';
import { WebSocketRequest } from '../../../models/websocket-request';
import { updateRequestMetaByParentId } from '../../hooks/create-request';
import { selectActiveRequest, selectActiveWorkspaceMeta } from '../../redux/selectors';
import { selectSidebarChildren } from '../../redux/sidebar-selectors';
Expand All @@ -14,7 +15,7 @@ import { SidebarRequestGroupRow } from './sidebar-request-group-row';
import { SidebarRequestRow } from './sidebar-request-row';

export interface Child {
doc: Request | GrpcRequest | RequestGroup;
doc: Request | GrpcRequest | WebSocketRequest | RequestGroup;
children: Child[];
collapsed: boolean;
hidden: boolean;
Expand Down Expand Up @@ -50,16 +51,37 @@ export const SidebarChildren: FC<Props> = ({
updateRequestMetaByParentId(requestId, { lastActive: Date.now() });
};

const RecursiveSidebarRows: FC<RecursiveSidebarRowsProps> = ({ rows, isInPinnedList }) => {
const RecursiveSidebarRows: FC<RecursiveSidebarRowsProps> = ({
rows,
isInPinnedList,
}) => {
const activeRequest = useSelector(selectActiveRequest);
const activeRequestId = activeRequest ? activeRequest._id : 'n/a';

return (
<>
{rows.map(row => (!isInPinnedList && row.hidden)
? null
: (isRequest(row.doc) || isGrpcRequest(row.doc))
? (
{rows
.filter(row => !(!isInPinnedList && row.hidden))
.map(row => {
if (isRequestGroup(row.doc)) {
return (
<SidebarRequestGroupRow
key={row.doc._id}
filter={filter || ''}
isActive={hasActiveChild(row.children, activeRequestId)}
isCollapsed={row.collapsed}
requestGroup={row.doc}
>
{row.children.filter(Boolean).length > 0 ? (
<RecursiveSidebarRows
isInPinnedList={isInPinnedList}
rows={row.children}
/>
) : null}
</SidebarRequestGroupRow>
);
}
return (
<SidebarRequestRow
key={row.doc._id}
filter={isInPinnedList ? '' : filter || ''}
Expand All @@ -70,19 +92,12 @@ export const SidebarChildren: FC<Props> = ({
disableDragAndDrop={isInPinnedList}
request={row.doc}
/>
) : (
<SidebarRequestGroupRow
key={row.doc._id}
filter={filter || ''}
isActive={hasActiveChild(row.children, activeRequestId)}
isCollapsed={row.collapsed}
requestGroup={row.doc}
>
{row.children.filter(Boolean).length > 0 ? <RecursiveSidebarRows isInPinnedList={isInPinnedList} rows={row.children} /> : null}
</SidebarRequestGroupRow>
))}
</>);
);
})}
</>
);
};

const { all, pinned } = sidebarChildren;
const showSeparator = sidebarChildren.pinned.length > 0;
const contextMenuPortal = ReactDOM.createPortal(
Expand Down
49 changes: 29 additions & 20 deletions packages/insomnia/src/ui/components/sidebar/sidebar-request-row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import { CONTENT_TYPE_GRAPHQL } from '../../../common/constants';
import { getMethodOverrideHeader } from '../../../common/misc';
import { GrpcRequest, isGrpcRequest } from '../../../models/grpc-request';
import * as requestOperations from '../../../models/helpers/request-operations';
import { Request } from '../../../models/request';
import { isRequest, Request } from '../../../models/request';
import { RequestGroup } from '../../../models/request-group';
import { isWebSocketRequest, WebSocketRequest } from '../../../models/websocket-request';
import { useNunjucks } from '../../context/nunjucks/use-nunjucks';
import { createRequest } from '../../hooks/create-request';
import { selectActiveEnvironment, selectActiveProject, selectActiveWorkspace } from '../../redux/selectors';
Expand All @@ -21,6 +22,7 @@ import { showModal } from '../modals/index';
import { RequestSettingsModal } from '../modals/request-settings-modal';
import { GrpcTag } from '../tags/grpc-tag';
import { MethodTag } from '../tags/method-tag';
import { WebSocketTag } from '../tags/websocket-tag';
import { DnDProps, DragObject, dropHandleCreator, hoverHandleCreator, sourceCollect, targetCollect } from './dnd';

interface RawProps {
Expand All @@ -30,7 +32,7 @@ interface RawProps {
handleDuplicateRequest: Function;
isActive: boolean;
isPinned: boolean;
request?: Request | GrpcRequest;
request?: Request | GrpcRequest | WebSocketRequest;
requestGroup?: RequestGroup;
}

Expand Down Expand Up @@ -138,7 +140,7 @@ export const _SidebarRequestRow: FC<Props> = forwardRef(({
return;
}

if (isGrpcRequest(request)) {
if (!isRequest(request)) {
return;
}

Expand Down Expand Up @@ -203,12 +205,17 @@ export const _SidebarRequestRow: FC<Props> = forwardRef(({
</li>
);
} else {
const methodTag =
isGrpcRequest(request) ? (
<GrpcTag />
) : (
<MethodTag method={request.method} override={methodOverrideValue} />
);

let methodTag = null;

if (isGrpcRequest(request)) {
methodTag = <GrpcTag />;
} else if (isWebSocketRequest(request)) {
methodTag = <WebSocketTag />;
} else if (isRequest(request)) {
methodTag = <MethodTag method={request.method} override={methodOverrideValue} />;
}

node = (
<li ref={nodeRef} className={classes}>
<div
Expand Down Expand Up @@ -243,17 +250,19 @@ export const _SidebarRequestRow: FC<Props> = forwardRef(({
</div>
</button>
<div className="sidebar__actions">
<RequestActionsDropdown
right
ref={requestActionsDropdown}
handleDuplicateRequest={handleDuplicateRequest}
handleShowSettings={handleShowRequestSettings}
request={request}
isPinned={isPinned}
requestGroup={requestGroup}
activeEnvironment={activeEnvironment}
activeProject={activeProject}
/>
{!isWebSocketRequest(request) && (
<RequestActionsDropdown
right
ref={requestActionsDropdown}
handleDuplicateRequest={handleDuplicateRequest}
handleShowSettings={handleShowRequestSettings}
request={request}
isPinned={isPinned}
requestGroup={requestGroup}
activeEnvironment={activeEnvironment}
activeProject={activeProject}
/>
)}
</div>
{isPinned && (
<div className="sidebar__item__icon-pin">
Expand Down
7 changes: 7 additions & 0 deletions packages/insomnia/src/ui/components/tags/websocket-tag.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from 'react';

export const WebSocketTag = () => (
<div className="tag tag--no-bg tag--small">
<span className="tag__inner">WS</span>
</div>
);
8 changes: 7 additions & 1 deletion packages/insomnia/src/ui/containers/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { isNotDefaultProject } from '../../models/project';
import { Request, updateMimeType } from '../../models/request';
import { type RequestGroupMeta } from '../../models/request-group-meta';
import { getByParentId as getRequestMetaByParentId } from '../../models/request-meta';
import { isWebSocketRequest, WebSocketRequest } from '../../models/websocket-request';
import { isWorkspace } from '../../models/workspace';
import * as plugins from '../../plugins';
import * as themes from '../../plugins/misc';
Expand Down Expand Up @@ -266,7 +267,7 @@ class App extends PureComponent<AppProps, State> {
];
}

_requestDuplicate(request?: Request | GrpcRequest) {
_requestDuplicate(request?: Request | GrpcRequest | WebSocketRequest) {
if (!request) {
return;
}
Expand Down Expand Up @@ -353,6 +354,11 @@ class App extends PureComponent<AppProps, State> {
return null;
}

if (isWebSocketRequest(this.props.activeRequest)) {
console.warn('Tried to update request mime-type on WebSocket request');
return null;
}

const requestMeta = await models.requestMeta.getOrCreateByParentId(
this.props.activeRequest._id,
);
Expand Down
4 changes: 3 additions & 1 deletion packages/insomnia/src/ui/context/nunjucks/use-nunjucks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useCallback } from 'react';
import { useSelector } from 'react-redux';

import { getRenderContext, getRenderContextAncestors, HandleGetRenderContext, HandleRender, render } from '../../../common/render';
import { isWebSocketRequest } from '../../../models/websocket-request';
import { NUNJUCKS_TEMPLATE_GLOBAL_PROPERTY_NAME } from '../../../templating';
import { getKeys } from '../../../templating/utils';
import { selectActiveEnvironment, selectActiveRequest, selectActiveWorkspace } from '../../redux/selectors';
Expand All @@ -19,7 +20,8 @@ initializeNunjucksRenderPromiseCache();
*/
export const useNunjucks = () => {
const environmentId = useSelector(selectActiveEnvironment)?._id;
const request = useSelector(selectActiveRequest);
const activeRequest = useSelector(selectActiveRequest);
const request = activeRequest && isWebSocketRequest(activeRequest) ? null : activeRequest;
const workspace = useSelector(selectActiveWorkspace);

const fetchRenderContext = useCallback(async () => {
Expand Down
7 changes: 3 additions & 4 deletions packages/insomnia/src/ui/hooks/use-active-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { useCallback } from 'react';
import { useSelector } from 'react-redux';

import * as models from '../../models';
import { isGrpcRequest } from '../../models/grpc-request';
import { Request } from '../../models/request';
import { isRequest, Request } from '../../models/request';
import { selectActiveRequest } from '../redux/selectors';

export const useActiveRequest = () => {
Expand All @@ -13,8 +12,8 @@ export const useActiveRequest = () => {
throw new Error('Tried to load null request');
}

if (isGrpcRequest(activeRequest)) {
throw new Error('Loaded GrpcRequest, expected to load Request');
if (!isRequest(activeRequest)) {
throw new Error('Expected to load Request');
}

const patchRequest = useCallback(async (patch: Partial<Request>) => {
Expand Down
3 changes: 2 additions & 1 deletion packages/insomnia/src/ui/redux/sidebar-selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { BaseModel } from '../../models';
import { GrpcRequest, isGrpcRequest } from '../../models/grpc-request';
import { isRequest, Request } from '../../models/request';
import { isRequestGroup, RequestGroup } from '../../models/request-group';
import { isWebSocketRequest } from '../../models/websocket-request';
import {
selectActiveWorkspace,
selectActiveWorkspaceMeta,
Expand All @@ -17,7 +18,7 @@ import {
type SidebarModel = Request | GrpcRequest | RequestGroup;

export const shouldShowInSidebar = (model: BaseModel): boolean =>
isRequest(model) || isGrpcRequest(model) || isRequestGroup(model);
isRequest(model) || isWebSocketRequest(model) || isGrpcRequest(model) || isRequestGroup(model);

export const shouldIgnoreChildrenOf = (model: SidebarModel): boolean =>
isRequest(model) || isGrpcRequest(model);
Expand Down

0 comments on commit 815d978

Please sign in to comment.