mirror of
https://github.com/Kong/insomnia.git
synced 2026-10-25 08:09:06 -04:00
Add support for request action plugins (#2678)
Co-authored-by: Opender Singh <opender.singh@konghq.com>
This commit is contained in:
1 parent
45a8aa45b8
commit
fba78881db
5 files changed
+122
-5
No files matched your search
@@ -41,6 +41,19 @@ export type RequestGroupAction = {
|
||||
icon?: string,
|
||||
};
|
||||
|
||||
export type RequestAction = {
|
||||
plugin: Plugin,
|
||||
action: (
|
||||
context: Object,
|
||||
models: {
|
||||
requestGroup: RequestGroup,
|
||||
request: Array<Request>,
|
||||
},
|
||||
) => void | Promise<void>,
|
||||
label: string,
|
||||
icon?: string,
|
||||
};
|
||||
|
||||
export type WorkspaceAction = {
|
||||
plugin: Plugin,
|
||||
action: (
|
||||
@@ -218,6 +231,16 @@ export async function getRequestGroupActions(): Promise<Array<RequestGroupAction
|
||||
return extensions;
|
||||
}
|
||||
|
||||
export async function getRequestActions(): Promise<Array<RequestAction>> {
|
||||
let extensions = [];
|
||||
for (const plugin of await getActivePlugins()) {
|
||||
const actions = plugin.module.requestActions || [];
|
||||
extensions = [...extensions, ...actions.map(p => ({ plugin, ...p }))];
|
||||
}
|
||||
|
||||
return extensions;
|
||||
}
|
||||
|
||||
export async function getWorkspaceActions(): Promise<Array<WorkspaceAction>> {
|
||||
let extensions = [];
|
||||
for (const plugin of await getActivePlugins()) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
// @flow
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import autobind from 'autobind-decorator';
|
||||
import PromptButton from '../base/prompt-button';
|
||||
@@ -15,8 +16,46 @@ import { isRequest } from '../../../models/helpers/is-model';
|
||||
import * as requestOperations from '../../../models/helpers/request-operations';
|
||||
import { incrementDeletedRequests } from '../../../models/stats';
|
||||
|
||||
// Plugin action related imports
|
||||
import type { RequestAction, RequestGroupAction } from '../../../plugins';
|
||||
import type { HotKeyRegistry } from '../../../common/hotkeys';
|
||||
import type { Request } from '../../../models/request';
|
||||
import type { RequestGroup } from '../../../models/request-group';
|
||||
import type { Environment } from '../../../models/environment';
|
||||
import { getRequestActions } from '../../../plugins';
|
||||
import * as pluginContexts from '../../../plugins/context/index';
|
||||
import { showError } from '../modals';
|
||||
import { RENDER_PURPOSE_NO_RENDER } from '../../../common/render';
|
||||
import classnames from 'classnames';
|
||||
|
||||
type Props = {
|
||||
handleDuplicateRequest: Function,
|
||||
handleGenerateCode: Function,
|
||||
handleCopyAsCurl: Function,
|
||||
handleShowSettings: Function,
|
||||
isPinned: Boolean,
|
||||
request: Request,
|
||||
requestGroup: RequestGroup,
|
||||
hotKeyRegistry: HotKeyRegistry,
|
||||
handleSetRequestPinned: Function,
|
||||
activeEnvironment: Environment | null,
|
||||
};
|
||||
|
||||
// Setup state for plugin actions
|
||||
type State = {
|
||||
actionPlugins: Array<RequestGroupAction>,
|
||||
loadingActions: { [string]: boolean },
|
||||
};
|
||||
|
||||
@autobind
|
||||
class RequestActionsDropdown extends PureComponent {
|
||||
class RequestActionsDropdown extends React.PureComponent<Props, State> {
|
||||
_dropdown: ?Dropdown;
|
||||
|
||||
state = {
|
||||
actionPlugins: [],
|
||||
loadingActions: {},
|
||||
};
|
||||
|
||||
_setDropdownRef(n) {
|
||||
this._dropdown = n;
|
||||
}
|
||||
@@ -49,8 +88,38 @@ class RequestActionsDropdown extends PureComponent {
|
||||
return requestOperations.remove(request);
|
||||
}
|
||||
|
||||
show() {
|
||||
this._dropdown.show();
|
||||
async _onOpen() {
|
||||
const plugins = await getRequestActions();
|
||||
this.setState({ actionPlugins: plugins });
|
||||
}
|
||||
|
||||
async show() {
|
||||
this._dropdown && this._dropdown.show();
|
||||
}
|
||||
|
||||
async _handlePluginClick(p: RequestAction) {
|
||||
this.setState(state => ({ loadingActions: { ...state.loadingActions, [p.label]: true } }));
|
||||
|
||||
try {
|
||||
const { activeEnvironment, request, requestGroup } = this.props;
|
||||
const activeEnvironmentId = activeEnvironment ? activeEnvironment._id : null;
|
||||
const context = {
|
||||
...(pluginContexts.app.init(RENDER_PURPOSE_NO_RENDER): Object),
|
||||
...(pluginContexts.data.init(): Object),
|
||||
...(pluginContexts.store.init(p.plugin): Object),
|
||||
...(pluginContexts.network.init(activeEnvironmentId): Object),
|
||||
};
|
||||
|
||||
await p.action(context, { request, requestGroup });
|
||||
} catch (err) {
|
||||
showError({
|
||||
title: 'Plugin Action Failed',
|
||||
error: err,
|
||||
});
|
||||
}
|
||||
|
||||
this.setState(state => ({ loadingActions: { ...state.loadingActions, [p.label]: false } }));
|
||||
this._dropdown && this._dropdown.hide();
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -61,11 +130,13 @@ class RequestActionsDropdown extends PureComponent {
|
||||
...other
|
||||
} = this.props;
|
||||
|
||||
const { actionPlugins, loadingActions } = this.state;
|
||||
|
||||
// Can only generate code for regular requests, not gRPC requests
|
||||
const canGenerateCode = isRequest(request);
|
||||
|
||||
return (
|
||||
<Dropdown ref={this._setDropdownRef} {...other}>
|
||||
<Dropdown ref={this._setDropdownRef} onOpen={this._onOpen} {...other}>
|
||||
<DropdownButton>
|
||||
<i className="fa fa-caret-down" />
|
||||
</DropdownButton>
|
||||
@@ -100,6 +171,22 @@ class RequestActionsDropdown extends PureComponent {
|
||||
<DropdownHint keyBindings={hotKeyRegistry[hotKeyRefs.REQUEST_SHOW_DELETE.id]} />
|
||||
</DropdownItem>
|
||||
|
||||
{actionPlugins.length > 0 && <DropdownDivider>Plugins</DropdownDivider>}
|
||||
{actionPlugins.map((p: RequestAction) => (
|
||||
<DropdownItem
|
||||
key={`${p.plugin.name}::${p.label}`}
|
||||
value={p}
|
||||
onClick={this._handlePluginClick}
|
||||
stayOpenAfterClick>
|
||||
{loadingActions[p.label] ? (
|
||||
<i className="fa fa-refresh fa-spin" />
|
||||
) : (
|
||||
<i className={classnames('fa', p.icon || 'fa-code')} />
|
||||
)}
|
||||
{p.label}
|
||||
</DropdownItem>
|
||||
))}
|
||||
|
||||
<DropdownDivider />
|
||||
|
||||
<DropdownItem onClick={handleShowSettings}>
|
||||
|
||||
@@ -122,6 +122,8 @@ class SidebarChildren extends React.PureComponent<Props> {
|
||||
request={child.doc}
|
||||
workspace={workspace}
|
||||
hotKeyRegistry={hotKeyRegistry}
|
||||
// Necessary for plugin actions on requests
|
||||
activeEnvironment={activeEnvironment}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -155,6 +155,8 @@ class SidebarRequestGroupRow extends PureComponent {
|
||||
filter={filter}
|
||||
hotKeyRegistry={hotKeyRegistry}
|
||||
isPinned={false}
|
||||
// Necessary so that plugin actions work
|
||||
activeEnvironment={activeEnvironment}
|
||||
/>
|
||||
)}
|
||||
</ul>
|
||||
|
||||
@@ -158,6 +158,7 @@ class SidebarRequestRow extends PureComponent {
|
||||
isPinned,
|
||||
disableDragAndDrop,
|
||||
hotKeyRegistry,
|
||||
activeEnvironment,
|
||||
} = this.props;
|
||||
|
||||
const { dragDirection } = this.state;
|
||||
@@ -232,6 +233,8 @@ class SidebarRequestRow extends PureComponent {
|
||||
isPinned={isPinned}
|
||||
requestGroup={requestGroup}
|
||||
hotKeyRegistry={hotKeyRegistry}
|
||||
// Necessary for plugin actions to have network capabilities
|
||||
activeEnvironment={activeEnvironment}
|
||||
/>
|
||||
</div>
|
||||
{isPinned && (
|
||||
|
||||
Reference in new issue
Block a user