mirror of
https://github.com/Kong/insomnia
synced 2024-11-07 14:19:58 +00:00
Refactored modals a bit
This commit is contained in:
parent
949dbff04b
commit
8a4c4fcd4f
@ -3,9 +3,6 @@ jest.unmock('../global');
|
||||
jest.unmock('../../constants/global');
|
||||
jest.unmock('../../constants/actionTypes');
|
||||
jest.unmock('../../validators/requestGroup');
|
||||
jest.unmock('jsonschema');
|
||||
jest.unmock('redux-thunk');
|
||||
jest.unmock('redux-mock-store');
|
||||
|
||||
describe('RequestGroup Actions', () => {
|
||||
it('should add valid group', () => {
|
||||
|
@ -5,10 +5,6 @@ jest.unmock('../../constants/actionTypes');
|
||||
jest.unmock('../../validators/request');
|
||||
jest.unmock('../../reducers/requests');
|
||||
jest.unmock('../../reducers/global');
|
||||
jest.unmock('jsonschema');
|
||||
jest.unmock('nunjucks');
|
||||
jest.unmock('redux-thunk');
|
||||
jest.unmock('redux-mock-store');
|
||||
|
||||
// Jest seems to barf when this isn't here
|
||||
jest.unmock('request');
|
||||
|
@ -1,6 +1,6 @@
|
||||
import * as types from '../constants/actionTypes'
|
||||
import * as methods from '../constants/global'
|
||||
import makeRequest from '../lib/request.electron'
|
||||
import makeRequest from '../lib/request'
|
||||
import {loadStart, loadStop} from './global'
|
||||
import {showModal} from './modals'
|
||||
import {REQUEST_RENAME} from '../constants/modals'
|
||||
|
@ -1,36 +1,6 @@
|
||||
import React, {Component, PropTypes} from 'react';
|
||||
import classnames from 'classnames';
|
||||
|
||||
const ModalHeader = (props) => (
|
||||
<div className="modal__header bg-light">
|
||||
<div className="grid">
|
||||
<div className="grid__cell pad">
|
||||
<div className={props.className}>
|
||||
{props.children}
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid--v">
|
||||
<button className="btn btn--compact txt-lg" data-close-modal="true">
|
||||
<i className="fa fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const ModalBody = (props) => (
|
||||
<div className={classnames('modal__body', 'grid__cell', 'scrollable', props.className)}>
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
|
||||
const ModalFooter = (props) => (
|
||||
<div className="modal__footer">
|
||||
<div className={props.className}>
|
||||
{props.children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
import React, {Component, PropTypes} from 'react'
|
||||
import classnames from 'classnames'
|
||||
import * as ModalActions from '../../actions/modals'
|
||||
|
||||
class Modal extends Component {
|
||||
_handleClick (e) {
|
||||
@ -70,7 +40,7 @@ class Modal extends Component {
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.refs.modal.focus();
|
||||
this.refs.modal && this.refs.modal.focus();
|
||||
}
|
||||
|
||||
render () {
|
||||
@ -80,7 +50,8 @@ class Modal extends Component {
|
||||
className={classnames('modal', 'grid', 'grid--center', this.props.className)}
|
||||
onKeyDown={this._keyDown.bind(this)}
|
||||
onClick={this._handleClick.bind(this)}>
|
||||
<div className={classnames('modal__content', 'grid--v', 'bg-super-light', {tall: this.props.tall})}>
|
||||
<div
|
||||
className={classnames('modal__content', 'grid--v', 'bg-super-light', {tall: this.props.tall})}>
|
||||
{this.props.children}
|
||||
</div>
|
||||
</div>
|
||||
@ -93,4 +64,5 @@ Modal.propTypes = {
|
||||
tall: PropTypes.bool
|
||||
};
|
||||
|
||||
export {Modal, ModalHeader, ModalBody, ModalFooter};
|
||||
export default Modal;
|
||||
|
||||
|
10
app/components/base/ModalBody.js
Normal file
10
app/components/base/ModalBody.js
Normal file
@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
|
||||
const ModalBody = (props) => (
|
||||
<div className={classnames('modal__body', 'grid__cell', 'scrollable', props.className)}>
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
|
||||
export default ModalBody;
|
11
app/components/base/ModalFooter.js
Normal file
11
app/components/base/ModalFooter.js
Normal file
@ -0,0 +1,11 @@
|
||||
import React from 'react';
|
||||
|
||||
const ModalFooter = (props) => (
|
||||
<div className="modal__footer">
|
||||
<div className={props.className}>
|
||||
{props.children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default ModalFooter;
|
20
app/components/base/ModalHeader.js
Normal file
20
app/components/base/ModalHeader.js
Normal file
@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
|
||||
const ModalHeader = (props) => (
|
||||
<div className="modal__header bg-light">
|
||||
<div className="grid">
|
||||
<div className="grid__cell pad">
|
||||
<div className={props.className}>
|
||||
{props.children}
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid--v">
|
||||
<button className="btn btn--compact txt-lg" data-close-modal="true">
|
||||
<i className="fa fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default ModalHeader;
|
@ -1,5 +1,8 @@
|
||||
import React, {Component, PropTypes} from 'react';
|
||||
import {Modal, ModalHeader, ModalBody, ModalFooter} from './Modal'
|
||||
import React, {Component, PropTypes} from 'react'
|
||||
import Modal from './Modal'
|
||||
import ModalBody from './ModalBody'
|
||||
import ModalHeader from './ModalHeader'
|
||||
import ModalFooter from './ModalFooter'
|
||||
|
||||
class PromptModal extends Component {
|
||||
_onSubmit (e) {
|
||||
@ -29,9 +32,9 @@ class PromptModal extends Component {
|
||||
}
|
||||
|
||||
render () {
|
||||
const {onClose, submitName, headerName} = this.props;
|
||||
const {onClose, submitName, headerName, ...extraProps} = this.props;
|
||||
return (
|
||||
<Modal ref="modal" onClose={onClose}>
|
||||
<Modal ref="modal" onClose={onClose} {...extraProps}>
|
||||
<ModalHeader>{headerName}</ModalHeader>
|
||||
<ModalBody className="wide">
|
||||
<form onSubmit={this._onSubmit.bind(this)} className="wide pad">
|
||||
|
@ -1,44 +0,0 @@
|
||||
import React, {Component, PropTypes} from 'react'
|
||||
import {Modal, ModalHeader, ModalBody, ModalFooter} from '../base/Modal'
|
||||
import Editor from '../base/Editor'
|
||||
import KeyValueEditor from '../base/KeyValueEditor'
|
||||
import * as modalIds from '../../constants/modals'
|
||||
|
||||
class EnvironmentEditModal extends Component {
|
||||
render () {
|
||||
const editorOptions = {
|
||||
mode: 'application/json',
|
||||
placeholder: '{ "array": [1, 2, 3, 4] }',
|
||||
theme: 'neat'
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal {...this.props}>
|
||||
<ModalHeader>Environment Variables</ModalHeader>
|
||||
<ModalBody className="grid--v wide pad">
|
||||
<div>
|
||||
<KeyValueEditor onChange={() => {}}
|
||||
pairs={[{name: 'foo', value: 'hello'}]}
|
||||
namePlaceholder="BASE_URL"
|
||||
valuePlaceholder="https://api.insomnia.com/v1"/>
|
||||
</div>
|
||||
{/*
|
||||
<h3>Hello</h3>
|
||||
<Editor value={undefined} options={editorOptions}/>
|
||||
*/}
|
||||
</ModalBody>
|
||||
<ModalFooter className="text-right">
|
||||
<button className="btn">Done</button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
EnvironmentEditModal.propTypes = {};
|
||||
|
||||
EnvironmentEditModal.defaultProps = {
|
||||
id: modalIds.ENVIRONMENT_EDITOR
|
||||
};
|
||||
|
||||
export default EnvironmentEditModal;
|
@ -7,14 +7,10 @@ import * as RequestGroupActions from '../../actions/requestGroups'
|
||||
import * as RequestActions from '../../actions/requests'
|
||||
import * as modalIds from '../../constants/modals'
|
||||
import PromptModal from '../base/PromptModal'
|
||||
import EnvironmentEditModal from './EnvironmentEditModal'
|
||||
|
||||
class Modals extends Component {
|
||||
class Prompts extends Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
this._modals = [
|
||||
EnvironmentEditModal
|
||||
];
|
||||
this._prompts = {};
|
||||
this._prompts[modalIds.REQUEST_RENAME] = {
|
||||
header: 'Rename Request',
|
||||
@ -37,53 +33,33 @@ class Modals extends Component {
|
||||
const {modals, actions} = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div ref="prompts">
|
||||
{Object.keys(this._prompts).map(id => {
|
||||
const promptDef = this._prompts[id];
|
||||
const modal = modals.find(m => m.id === id);
|
||||
<div ref="prompts">
|
||||
{Object.keys(this._prompts).map(id => {
|
||||
const promptDef = this._prompts[id];
|
||||
const modal = modals.find(m => m.id === id);
|
||||
|
||||
if (!modal) {
|
||||
return null;
|
||||
}
|
||||
if (!modal) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<PromptModal
|
||||
key={id}
|
||||
headerName={promptDef.header}
|
||||
submitName={promptDef.submit}
|
||||
defaultValue={modal.data.defaultValue}
|
||||
onClose={() => actions.hideModal(modal.id)}
|
||||
onSubmit={value => promptDef.onSubmit(modal, value)}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
<div ref="modals">
|
||||
{this._modals.map(c => {
|
||||
const id = c.defaultProps.id;
|
||||
const isVisible = modals.find(m => m.id === id);
|
||||
const modal = React.createElement(c, {
|
||||
key: id,
|
||||
onClose: () => actions.hideModal(id)
|
||||
});
|
||||
return isVisible ? modal : null;
|
||||
})}
|
||||
</div>
|
||||
<div ref="toasts">
|
||||
{/*<div className="toast grid">
|
||||
<div className="toast__message">Request deleted</div>
|
||||
<button className="btn toast__action">
|
||||
Undo
|
||||
</button>
|
||||
</div> */}
|
||||
</div>
|
||||
return (
|
||||
<PromptModal
|
||||
key={id}
|
||||
id={id}
|
||||
headerName={promptDef.header}
|
||||
submitName={promptDef.submit}
|
||||
defaultValue={modal.data.defaultValue}
|
||||
onClose={() => actions.hideModal(modal.id)}
|
||||
onSubmit={value => promptDef.onSubmit(modal, value)}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Modals.propTypes = {
|
||||
Prompts.propTypes = {
|
||||
actions: PropTypes.shape({
|
||||
hideModal: PropTypes.func.isRequired,
|
||||
updateRequestGroup: PropTypes.func.isRequired,
|
||||
@ -113,5 +89,5 @@ function mapDispatchToProps (dispatch) {
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Modals);
|
||||
)(Prompts);
|
||||
|
65
app/components/modals/RequestGroupEnvironmentEditModal.js
Normal file
65
app/components/modals/RequestGroupEnvironmentEditModal.js
Normal file
@ -0,0 +1,65 @@
|
||||
import React, {Component, PropTypes} from 'react'
|
||||
import Modal from '../base/Modal'
|
||||
import ModalBody from '../base/ModalBody'
|
||||
import ModalHeader from '../base/ModalHeader'
|
||||
import ModalFooter from '../base/ModalFooter'
|
||||
import Editor from '../base/Editor'
|
||||
import KeyValueEditor from '../base/KeyValueEditor'
|
||||
import * as modalIds from '../../constants/modals'
|
||||
|
||||
class RequestGroupEnvironmentEditModal extends Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
pairs: []
|
||||
}
|
||||
}
|
||||
|
||||
_saveChanges () {
|
||||
this.props.onChange(this.state.pairs);
|
||||
}
|
||||
|
||||
_keyValueChange (pairs) {
|
||||
this.setState({pairs});
|
||||
}
|
||||
|
||||
render () {
|
||||
const editorOptions = {
|
||||
mode: 'application/json',
|
||||
placeholder: '{ "array": [1, 2, 3, 4] }',
|
||||
theme: 'neat'
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal {...this.props}>
|
||||
<ModalHeader>Environment Variables</ModalHeader>
|
||||
<ModalBody className="grid--v wide pad">
|
||||
<div>
|
||||
<KeyValueEditor onChange={this._keyValueChange.bind(this)}
|
||||
pairs={this.state.pairs}
|
||||
namePlaceholder="BASE_URL"
|
||||
valuePlaceholder="https://api.insomnia.com/v1"/>
|
||||
</div>
|
||||
{/*
|
||||
<h3>Hello</h3>
|
||||
<Editor value={undefined} options={editorOptions}/>
|
||||
*/}
|
||||
</ModalBody>
|
||||
<ModalFooter className="text-right">
|
||||
<button className="btn" onClick={this._saveChanges.bind(this)}>Done</button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
RequestGroupEnvironmentEditModal.propTypes = {
|
||||
// requestGroup: PropTypes.object.isRequired,
|
||||
onChange: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
RequestGroupEnvironmentEditModal.defaultProps = {
|
||||
id: modalIds.ENVIRONMENT_EDITOR
|
||||
};
|
||||
|
||||
export default RequestGroupEnvironmentEditModal;
|
@ -4,17 +4,19 @@ import {bindActionCreators} from 'redux'
|
||||
import {Tab, Tabs, TabList, TabPanel} from 'react-tabs'
|
||||
|
||||
import Editor from '../components/base/Editor'
|
||||
import Modals from '../components/modals/ModalContainer'
|
||||
import Prompts from '../components/modals/Prompts'
|
||||
import KeyValueEditor from '../components/base/KeyValueEditor'
|
||||
import RequestBodyEditor from '../components/RequestBodyEditor'
|
||||
import RequestAuthEditor from '../components/RequestAuthEditor'
|
||||
import RequestUrlBar from '../components/RequestUrlBar'
|
||||
import Sidebar from '../components/Sidebar'
|
||||
import RequestGroupEnvironmentEditModal from '../components/modals/RequestGroupEnvironmentEditModal'
|
||||
|
||||
import * as GlobalActions from '../actions/global'
|
||||
import * as RequestGroupActions from '../actions/requestGroups'
|
||||
import * as RequestActions from '../actions/requests'
|
||||
import * as ResponseActions from '../actions/responses'
|
||||
import * as ModalActions from '../actions/modals'
|
||||
|
||||
// Don't inject component styles (use our own)
|
||||
Tabs.setUseDefaultStyles(false);
|
||||
@ -144,13 +146,19 @@ class App extends Component {
|
||||
}
|
||||
|
||||
render () {
|
||||
const {actions, requests, responses, requestGroups, tabs} = this.props;
|
||||
const {actions, requests, responses, requestGroups, tabs, modals} = this.props;
|
||||
const activeRequest = requests.all.find(r => r.id === requests.active);
|
||||
const activeResponse = responses[activeRequest && activeRequest.id];
|
||||
|
||||
return (
|
||||
<div className="grid bg-super-dark tall">
|
||||
<Modals />
|
||||
<Prompts />
|
||||
{!modals.find(m => m.id === RequestGroupEnvironmentEditModal.defaultProps.id) ? null : (
|
||||
<RequestGroupEnvironmentEditModal
|
||||
onClose={() => actions.hideModal(RequestGroupEnvironmentEditModal.defaultProps.id)}
|
||||
onChange={v => console.log(v)}
|
||||
/>
|
||||
)}
|
||||
<Sidebar
|
||||
activateRequest={actions.activateRequest}
|
||||
changeFilter={actions.changeFilter}
|
||||
@ -192,7 +200,8 @@ App.propTypes = {
|
||||
active: PropTypes.string // "required" but can be null
|
||||
}).isRequired,
|
||||
responses: PropTypes.object.isRequired,
|
||||
tabs: PropTypes.object.isRequired
|
||||
tabs: PropTypes.object.isRequired,
|
||||
modals: PropTypes.array.isRequired
|
||||
};
|
||||
|
||||
function mapStateToProps (state) {
|
||||
@ -201,7 +210,8 @@ function mapStateToProps (state) {
|
||||
requests: state.requests,
|
||||
requestGroups: state.requestGroups,
|
||||
responses: state.responses,
|
||||
tabs: state.tabs
|
||||
tabs: state.tabs,
|
||||
modals: state.modals
|
||||
};
|
||||
}
|
||||
|
||||
@ -210,6 +220,7 @@ function mapDispatchToProps (dispatch) {
|
||||
actions: Object.assign(
|
||||
{},
|
||||
bindActionCreators(GlobalActions, dispatch),
|
||||
bindActionCreators(ModalActions, dispatch),
|
||||
bindActionCreators(RequestGroupActions, dispatch),
|
||||
bindActionCreators(RequestActions, dispatch),
|
||||
bindActionCreators(ResponseActions, dispatch)
|
||||
|
@ -1,7 +1,7 @@
|
||||
import nunjucks from 'nunjucks'
|
||||
|
||||
nunjucks.configure({ autoescape: false });
|
||||
nunjucks.configure({autoescape: false});
|
||||
|
||||
export default function (template, context) {
|
||||
export default function (template, context = {}) {
|
||||
return nunjucks.renderString(template, context);
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
jest.unmock('../request');
|
||||
jest.unmock('../../constants/global');
|
||||
jest.unmock('jsonschema');
|
||||
|
||||
import validate from '../request';
|
||||
|
||||
|
12
package.json
12
package.json
@ -61,9 +61,21 @@
|
||||
},
|
||||
"jest": {
|
||||
"unmockedModulePathPatterns": [
|
||||
"<rootDir>/node_modules/redux-thunk",
|
||||
"<rootDir>/node_modules/redux-mock-store",
|
||||
"<rootDir>/node_modules/nunjucks",
|
||||
"<rootDir>/node_modules/jsonschema",
|
||||
"<rootDir>/node_modules/react",
|
||||
"<rootDir>/node_modules/react-dom",
|
||||
"<rootDir>/node_modules/react-addons-test-utils"
|
||||
],
|
||||
"testFileExtensions": [
|
||||
"test.js"
|
||||
],
|
||||
"moduleFileExtensions": [
|
||||
"js",
|
||||
"electron.js",
|
||||
"chrome.js"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,8 @@ base.plugins = [
|
||||
|
||||
base.target = webpackTargetElectronRenderer(base);
|
||||
|
||||
base.resolve.extensions.push('electron.js');
|
||||
base.resolve.extensions.push('.electron.js');
|
||||
console.log(base);
|
||||
|
||||
module.exports = base;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user