From b4c48fb411074eea6eb728d4afeef9c7f4466c7a Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 4 Apr 2016 00:15:30 -0700 Subject: [PATCH] Lots --- app/actions/__tests__/requests.test.js | 10 +- app/actions/requestgroups.js | 26 ++- app/actions/requests.js | 25 +-- app/components/MethodTag.js | 27 ++++ app/components/RequestBodyEditor.js | 8 +- app/components/RequestUrlBar.js | 8 +- app/components/Sidebar.js | 120 ++++++++------ app/components/base/Dropdown.js | 2 +- .../dropdowns/RequestActionsDropdown.js | 18 ++- app/components/dropdowns/WorkspaceDropdown.js | 69 ++++++++ app/constants/actionTypes.js | 1 + app/constants/global.js | 2 + app/containers/App.js | 44 +++--- app/css/components/dropdown.scss | 50 +++--- app/css/components/editor.scss | 3 +- app/css/components/forms.scss | 7 +- app/css/components/grid.scss | 1 - app/css/components/links.scss | 1 - app/css/components/pane.scss | 2 +- app/css/components/tabs.scss | 2 +- app/css/components/tag.scss | 8 + app/css/constants/colors.scss | 65 ++++++-- app/css/constants/dimensions.scss | 9 +- app/css/layout/base.scss | 26 ++- app/css/layout/sidebar.scss | 104 +++++++----- app/reducers/__tests__/requestGroups.test.js | 148 ++---------------- app/reducers/__tests__/requests.test.js | 1 - app/reducers/requestgroups.js | 52 ++++-- app/validators/__tests__/Request.test.js | 1 - app/validators/request.js | 2 - app/validators/requestGroup.js | 1 - electron.js | 4 +- 32 files changed, 505 insertions(+), 342 deletions(-) create mode 100644 app/components/MethodTag.js create mode 100644 app/components/dropdowns/WorkspaceDropdown.js diff --git a/app/actions/__tests__/requests.test.js b/app/actions/__tests__/requests.test.js index 297d8bf58..726ae3b2d 100644 --- a/app/actions/__tests__/requests.test.js +++ b/app/actions/__tests__/requests.test.js @@ -27,14 +27,16 @@ describe('Requests Actions', () => { type: types.REQUEST_ADD, request: { id: 'rq_1000000000000', - _mode: 'json', created: 1000000000000, modified: 1000000000000, - name: 'Test Request', + name: 'My Request', method: 'GET', url: '', body: '', - headers: [], + headers: [{ + name: 'Content-Type', + value: 'application/json' + }], params: [], authentication: {} } @@ -43,7 +45,7 @@ describe('Requests Actions', () => { ]; const store = mockStore(); - store.dispatch(addRequest('Test Request')); + store.dispatch(addRequest()); jest.runAllTimers(); const actions = store.getActions(); diff --git a/app/actions/requestgroups.js b/app/actions/requestgroups.js index 5492b68e4..3b9e4e007 100644 --- a/app/actions/requestgroups.js +++ b/app/actions/requestgroups.js @@ -4,11 +4,13 @@ import {loadStart} from "./global"; import {loadStop} from "./global"; const defaultRequestGroup = { - id: null, - created: 0, - modified: 0, - name: '', - environment: {} + id: null, + created: 0, + modified: 0, + collapsed: false, + name: '', + environment: {}, + children: [] }; /** @@ -43,6 +45,20 @@ export function addRequestGroup (name = 'My Group') { }; } +export function addChildRequest (id, requestId) { + return (dispatch) => { + dispatch(loadStart()); + dispatch({type: types.REQUEST_GROUP_ADD_CHILD_REQUEST, id, requestId}); + + return new Promise((resolve) => { + setTimeout(() => { + dispatch(loadStop()); + resolve(); + }, 500); + }); + }; +} + export function updateRequestGroup (requestGroupPatch) { if (!requestGroupPatch.id) { throw new Error('Cannot update RequestGroup without id'); diff --git a/app/actions/requests.js b/app/actions/requests.js index 798bafc88..5a06312c7 100644 --- a/app/actions/requests.js +++ b/app/actions/requests.js @@ -5,7 +5,6 @@ import {loadStop} from "./global"; const defaultRequest = { id: null, - _mode: 'json', created: 0, modified: 0, url: '', @@ -13,15 +12,13 @@ const defaultRequest = { method: methods.METHOD_GET, body: '', params: [], - headers: [], + headers: [{ + name: 'Content-Type', + value: 'application/json' + }], authentication: {} }; -/** - * Build a new request from a subset of fields - * @param request values to override defaults with - * @returns {*} - */ function buildRequest (request) { // Build the required fields const id = request.id || `rq_${Date.now()}`; @@ -34,12 +31,18 @@ function buildRequest (request) { }); } -export function addRequest (name = 'My Request') { +export function addRequest (requestGroupId = null) { return (dispatch) => { dispatch(loadStart()); - const request = buildRequest({name}); + const request = buildRequest({name: 'My Request'}); dispatch({type: types.REQUEST_ADD, request}); + if (requestGroupId) { + const id = requestGroupId; + const requestId = request.id; + dispatch({type: types.REQUEST_GROUP_ADD_CHILD_REQUEST, requestId, id}); + } + return new Promise((resolve) => { setTimeout(() => { dispatch(loadStop()); @@ -103,3 +106,7 @@ export function activateRequest (id) { export function changeFilter (filter) { return {type: types.REQUEST_CHANGE_FILTER, filter}; } + +export function sendRequest (id) { + +} diff --git a/app/components/MethodTag.js b/app/components/MethodTag.js new file mode 100644 index 000000000..ce91eb058 --- /dev/null +++ b/app/components/MethodTag.js @@ -0,0 +1,27 @@ +import React, {Component, PropTypes} from 'react' +import * as constants from '../constants/global'; + +class MethodTag extends Component { + render () { + const {method} = this.props; + + let methodName; + if (method === constants.METHOD_DELETE || method === constants.METHOD_OPTIONS) { + methodName = method.slice(0, 3); + } else { + methodName = method.slice(0, 4); + } + + return ( +
+ {methodName} +
+ ); + } +} + +MethodTag.propTypes = { + method: PropTypes.string.isRequired +}; + +export default MethodTag; diff --git a/app/components/RequestBodyEditor.js b/app/components/RequestBodyEditor.js index b5ba3a7ea..e0ab016b3 100644 --- a/app/components/RequestBodyEditor.js +++ b/app/components/RequestBodyEditor.js @@ -8,13 +8,16 @@ class RequestBodyEditor extends Component { render () { const {request, onChange, className} = this.props; + const contentTypeHeader = request.headers.find(h => h.name.toLowerCase() === 'content-type'); + const mode = contentTypeHeader ? contentTypeHeader.value : 'text/plain'; + return ( @@ -24,8 +27,7 @@ class RequestBodyEditor extends Component { RequestBodyEditor.propTypes = { request: PropTypes.shape({ - body: PropTypes.string.isRequired, - _mode: PropTypes.string.isRequired + body: PropTypes.string.isRequired }).isRequired, onChange: PropTypes.func.isRequired }; diff --git a/app/components/RequestUrlBar.js b/app/components/RequestUrlBar.js index 6a103384f..bdfd32450 100644 --- a/app/components/RequestUrlBar.js +++ b/app/components/RequestUrlBar.js @@ -12,10 +12,10 @@ class UrlInput extends Component { return (
- -
    +
      {METHODS.map((method) => (
) diff --git a/app/components/Sidebar.js b/app/components/Sidebar.js index 21a989802..9df3234c9 100644 --- a/app/components/Sidebar.js +++ b/app/components/Sidebar.js @@ -1,7 +1,9 @@ import React, {Component, PropTypes} from 'react' -import Dropdown from './base/Dropdown' +import WorkspaceDropdown from './dropdowns/WorkspaceDropdown' import DebouncingInput from './base/DebouncingInput' import RequestActionsDropdown from './dropdowns/RequestActionsDropdown' +import MethodTag from './MethodTag' +import Dropdown from './base/Dropdown' class Sidebar extends Component { onFilterChange (value) { @@ -9,80 +11,97 @@ class Sidebar extends Component { } renderRequestGroupRow (requestGroup) { - const {activeFilter, addRequest, requests} = this.props; + const {activeFilter, activeRequest, addRequest, toggleRequestGroup, requests, requestGroups} = this.props; - const filteredRequests = requests.filter( - r => !requestGroup || requestGroup.requests.find(r.id) - ).filter( - r => r.name.toLowerCase().indexOf(activeFilter.toLowerCase()) >= 0 + let filteredRequests = requests.filter( + r => r.name.toLowerCase().indexOf(activeFilter.toLowerCase()) != -1 ); - if (requestGroup) { + if (!requestGroup) { + // Grab all requests that are not children of request groups + filteredRequests = filteredRequests.filter(r => { + return !requestGroups.find(rg => { + return rg.children.find(c => c.id === r.id) + }) + }); + + return filteredRequests.map(request => this.renderRequestRow(request)); + } else { + // Grab all of the children for this request group + filteredRequests = filteredRequests.filter( + r => requestGroup.children.find(c => c.id === r.id) + ); + + const isActive = activeRequest && filteredRequests.find(r => r.id == activeRequest.id); + + let folderIconClass = 'fa-folder'; + folderIconClass += requestGroup.collapsed ? '' : '-open'; + folderIconClass += isActive ? '' : '-o'; + return ( -
  • -
    - - +
  • +
    +
    + +
    +
    + + + +
      +
    • +
    • +
    • +
    +
    +
      - {filteredRequests.map(request => this.renderRequestRow(request))} + {requestGroup.collapsed ? null : filteredRequests.map(request => this.renderRequestRow(request))}
  • ) - } else { - return ( - filteredRequests.map(request => this.renderRequestRow(request)) - ) } } renderRequestRow (request) { const {activeRequest, activateRequest} = this.props; const isActive = activeRequest && request.id === activeRequest.id; - const className = ['grid'].concat(isActive ? ['active'] : ''); return ( -
  • -
    - - +
  • +
    +
    + +
    +
  • ); } render () { - const {activeFilter, loading, addRequest, requestGroups} = this.props; + const {activeFilter, requestGroups} = this.props; return (