mirror of
https://github.com/Kong/insomnia
synced 2024-11-12 17:26:32 +00:00
213 lines
6.0 KiB
TypeScript
213 lines
6.0 KiB
TypeScript
import { autoBindMethodsForReact } from 'class-autobind-decorator';
|
|
import React, { PureComponent } from 'react';
|
|
|
|
import { trackEvent } from '../../../common/analytics';
|
|
import {
|
|
AUTOBIND_CFG,
|
|
getContentTypeName,
|
|
METHOD_DELETE,
|
|
METHOD_GET,
|
|
METHOD_GRPC,
|
|
METHOD_HEAD,
|
|
METHOD_OPTIONS,
|
|
} from '../../../common/constants';
|
|
import * as models from '../../../models/index';
|
|
import { Request } from '../../../models/request';
|
|
import Modal from '../base/modal';
|
|
import ModalBody from '../base/modal-body';
|
|
import ModalFooter from '../base/modal-footer';
|
|
import ModalHeader from '../base/modal-header';
|
|
import ContentTypeDropdown from '../dropdowns/content-type-dropdown';
|
|
import MethodDropdown from '../dropdowns/method-dropdown';
|
|
import { showModal } from './index';
|
|
import ProtoFilesModal from './proto-files-modal';
|
|
interface RequestCreateModalOptions {
|
|
parentId: string;
|
|
onComplete: (arg0: string) => void;
|
|
}
|
|
|
|
interface State {
|
|
selectedContentType: string | null;
|
|
selectedMethod: string;
|
|
parentId: string | null;
|
|
}
|
|
|
|
@autoBindMethodsForReact(AUTOBIND_CFG)
|
|
class RequestCreateModal extends PureComponent<{}, State> {
|
|
state: State = {
|
|
selectedContentType: null,
|
|
selectedMethod: METHOD_GET,
|
|
parentId: null,
|
|
}
|
|
|
|
modal: Modal | null = null;
|
|
_input: HTMLInputElement | null = null;
|
|
private _onComplete: (arg0: string) => void;
|
|
|
|
_setModalRef(n: Modal) {
|
|
this.modal = n;
|
|
}
|
|
|
|
_setInputRef(n: HTMLInputElement) {
|
|
this._input = n;
|
|
|
|
if (this._input) {
|
|
this._input.value = 'My Request';
|
|
this._input.placeholder = 'My Request';
|
|
}
|
|
}
|
|
|
|
_isGrpcSelected() {
|
|
return this.state.selectedMethod === METHOD_GRPC;
|
|
}
|
|
|
|
async _handleSubmit(e) {
|
|
e.preventDefault();
|
|
const { parentId, selectedContentType, selectedMethod } = this.state;
|
|
const requestName = this._input?.value;
|
|
|
|
if (this._isGrpcSelected()) {
|
|
showModal(ProtoFilesModal, {
|
|
onSave: async (protoFileId: string) => {
|
|
const createdRequest = await models.grpcRequest.create({
|
|
// @ts-expect-error -- TSCONVERSION should not reach here at all if parentId is undefined, it shouldn't even open the modal
|
|
parentId,
|
|
name: requestName,
|
|
protoFileId,
|
|
});
|
|
|
|
this._onComplete(createdRequest._id);
|
|
},
|
|
});
|
|
} else {
|
|
const request = await models.initModel<Request>(models.request.type, {
|
|
parentId,
|
|
name: requestName,
|
|
method: selectedMethod,
|
|
});
|
|
const finalRequest = await models.request.updateMimeType(
|
|
request,
|
|
// @ts-expect-error -- TSCONVERSION null not accepted
|
|
this._shouldNotHaveBody() ? null : selectedContentType,
|
|
true,
|
|
);
|
|
|
|
this._onComplete(finalRequest._id);
|
|
}
|
|
|
|
this.hide();
|
|
trackEvent('Request', 'Create');
|
|
}
|
|
|
|
_handleChangeSelectedContentType(selectedContentType: string | null) {
|
|
this.setState({
|
|
selectedContentType,
|
|
});
|
|
}
|
|
|
|
_handleChangeSelectedMethod(selectedMethod) {
|
|
this.setState({
|
|
selectedMethod,
|
|
});
|
|
}
|
|
|
|
_shouldNotHaveBody() {
|
|
const { selectedMethod } = this.state;
|
|
return (
|
|
selectedMethod === METHOD_GET ||
|
|
selectedMethod === METHOD_HEAD ||
|
|
selectedMethod === METHOD_DELETE ||
|
|
selectedMethod === METHOD_OPTIONS ||
|
|
selectedMethod === METHOD_GRPC
|
|
);
|
|
}
|
|
|
|
hide() {
|
|
this.modal?.hide();
|
|
}
|
|
|
|
show({ parentId, onComplete }: RequestCreateModalOptions) {
|
|
this.setState({
|
|
parentId,
|
|
selectedContentType: null,
|
|
selectedMethod: METHOD_GET,
|
|
});
|
|
this.modal?.show();
|
|
// Need to do this after render because modal focuses itself too
|
|
setTimeout(() => {
|
|
this._input?.focus();
|
|
|
|
this._input?.select();
|
|
}, 200);
|
|
this._onComplete = onComplete;
|
|
}
|
|
|
|
render() {
|
|
const { selectedContentType, selectedMethod } = this.state;
|
|
return (
|
|
<Modal ref={this._setModalRef}>
|
|
<ModalHeader>New Request</ModalHeader>
|
|
<ModalBody noScroll>
|
|
<form onSubmit={this._handleSubmit} className="pad">
|
|
<div className="form-row">
|
|
<div className="form-control form-control--outlined">
|
|
<label>
|
|
Name
|
|
<span className="txt-sm faint italic space-left">
|
|
(defaults to your request URL if left empty)
|
|
</span>
|
|
<input ref={this._setInputRef} type="text" />
|
|
</label>
|
|
</div>
|
|
<div
|
|
className="form-control form-control--no-label"
|
|
style={{
|
|
width: 'auto',
|
|
}}
|
|
>
|
|
<MethodDropdown
|
|
right
|
|
showGrpc
|
|
className="btn btn--clicky no-wrap"
|
|
method={selectedMethod}
|
|
onChange={this._handleChangeSelectedMethod}
|
|
/>
|
|
</div>
|
|
{!this._shouldNotHaveBody() && (
|
|
<div
|
|
className="form-control form-control--no-label"
|
|
style={{
|
|
width: 'auto',
|
|
}}
|
|
>
|
|
<ContentTypeDropdown
|
|
className="btn btn--clicky no-wrap"
|
|
right
|
|
contentType={selectedContentType}
|
|
onChange={this._handleChangeSelectedContentType}
|
|
>
|
|
{getContentTypeName(selectedContentType) || 'No Body'}{' '}
|
|
<i className="fa fa-caret-down" />
|
|
</ContentTypeDropdown>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</form>
|
|
</ModalBody>
|
|
<ModalFooter>
|
|
{!this._isGrpcSelected() && (
|
|
<div className="margin-left italic txt-sm tall">
|
|
* Tip: paste Curl command into URL afterwards to import it
|
|
</div>
|
|
)}
|
|
<button className="btn" onClick={this._handleSubmit}>
|
|
Create
|
|
</button>
|
|
</ModalFooter>
|
|
</Modal>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default RequestCreateModal;
|