mirror of
https://github.com/Kong/insomnia.git
synced 2026-04-20 22:27:24 -04:00
Re-implemented filtering in the Sidbare
This commit is contained in:
@@ -48,7 +48,7 @@ class RequestPane extends Component {
|
||||
<Tab className="no-wrap grid grid--center">
|
||||
<button>JSON</button>
|
||||
<Dropdown>
|
||||
<button> <i className="fa fa-caret-down"></i></button>
|
||||
<button><i className="fa fa-caret-down"></i></button>
|
||||
<ul>
|
||||
<li><button><i className="fa fa-file-text"></i> Plain Text</button></li>
|
||||
<li><button><i className="fa fa-picture-o"></i> File Upload</button></li>
|
||||
|
||||
@@ -21,7 +21,9 @@ class UrlInput extends Component {
|
||||
<ul>
|
||||
{METHODS.map(m => (
|
||||
<li key={m}>
|
||||
<button onClick={onMethodChange.bind(null, m)}>{m}</button>
|
||||
<button onClick={onMethodChange.bind(null, m)}>
|
||||
{m}
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import React, {Component, PropTypes} from 'react'
|
||||
import {Tab, Tabs, TabList, TabPanel} from 'react-tabs'
|
||||
|
||||
import StatusTag from '../components/StatusTag'
|
||||
import Dropdown from '../components/base/Dropdown'
|
||||
import Editor from '../components/base/Editor'
|
||||
import StatusTag from '../components/StatusTag'
|
||||
import SizeTag from '../components/SizeTag'
|
||||
import TimeTag from '../components/TimeTag'
|
||||
|
||||
@@ -39,8 +40,17 @@ class ResponsePane extends Component {
|
||||
</header>
|
||||
<Tabs className="grid__cell grid--v section__body">
|
||||
<TabList className="grid grid--start">
|
||||
<Tab><button>Preview</button></Tab>
|
||||
<Tab><button>Raw</button></Tab>
|
||||
<Tab className="no-wrap grid grid--center">
|
||||
<button>Preview</button>
|
||||
<Dropdown>
|
||||
<button><i className="fa fa-caret-down"></i></button>
|
||||
<ul>
|
||||
<li><button><i className="fa fa-eye"></i> Preview</button></li>
|
||||
<li><button><i className="fa fa-code"></i> Formatted</button></li>
|
||||
<li><button><i className="fa fa-file"></i> Raw</button></li>
|
||||
</ul>
|
||||
</Dropdown>
|
||||
</Tab>
|
||||
<Tab><button>Headers</button></Tab>
|
||||
</TabList>
|
||||
<TabPanel className="grid__cell editor-wrapper">
|
||||
@@ -54,17 +64,6 @@ class ResponsePane extends Component {
|
||||
}}
|
||||
/>
|
||||
</TabPanel>
|
||||
<TabPanel className="grid__cell editor-wrapper">
|
||||
<Editor
|
||||
value={response && response.body || ''}
|
||||
options={{
|
||||
lineWrapping: true,
|
||||
mode: 'text/plain',
|
||||
readOnly: true,
|
||||
placeholder: 'nothing yet...'
|
||||
}}
|
||||
/>
|
||||
</TabPanel>
|
||||
<TabPanel className="grid__cell grid__cell--scroll--v">
|
||||
<div className="wide">
|
||||
<div className="grid--v grid--start pad">
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import React, {Component, PropTypes} from 'react'
|
||||
import classnames from 'classnames'
|
||||
import WorkspaceDropdown from './../containers/WorkspaceDropdown'
|
||||
import RequestGroupActionsDropdown from './../containers/RequestGroupActionsDropdown'
|
||||
import DebouncingInput from './base/DebouncingInput'
|
||||
import SidebarRequestGroupRow from './SidebarRequestGroupRow'
|
||||
import SidebarRequestRow from './SidebarRequestRow'
|
||||
|
||||
class Sidebar extends Component {
|
||||
@@ -10,105 +9,70 @@ class Sidebar extends Component {
|
||||
this.props.changeFilter(value);
|
||||
}
|
||||
|
||||
renderRequestGroupRow (child, parent) {
|
||||
const {
|
||||
filter,
|
||||
activeRequestId,
|
||||
addRequestToRequestGroup,
|
||||
toggleRequestGroup
|
||||
} = this.props;
|
||||
|
||||
const requestGroup = child.doc.type === 'RequestGroup' ? child.doc : null;
|
||||
_filterChildren (filter, children, extra = null) {
|
||||
return children.filter(child => {
|
||||
if (child.doc.type !== 'Request') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!requestGroup) {
|
||||
return child.children.map(c => this._renderChild(c, child));
|
||||
}
|
||||
const request = child.doc;
|
||||
|
||||
// Don't show folder if it was not in the filter
|
||||
if (filter && !child.children.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isActive = activeRequestId && child.children.find(c => c.doc._id == activeRequestId);
|
||||
|
||||
let folderIconClass = 'fa-folder';
|
||||
let expanded = !requestGroup.collapsed;
|
||||
folderIconClass += !expanded ? '' : '-open';
|
||||
folderIconClass += isActive ? '' : '-o';
|
||||
|
||||
const sidebarItemClassNames = classnames(
|
||||
'sidebar__item',
|
||||
'sidebar__item--bordered',
|
||||
{'sidebar__item--active': isActive}
|
||||
);
|
||||
|
||||
child.children.sort((a, b) => a.doc._id > b.doc._id ? -1 : 1);
|
||||
|
||||
return (
|
||||
<li key={requestGroup._id}>
|
||||
<div className={sidebarItemClassNames}>
|
||||
<div className="sidebar__item__row sidebar__item__row--heading">
|
||||
<button onClick={e => toggleRequestGroup(requestGroup)}>
|
||||
<i className={'fa ' + folderIconClass}></i>
|
||||
{requestGroup.name}
|
||||
</button>
|
||||
</div>
|
||||
<div className="sidebar__item__btn grid">
|
||||
<button onClick={(e) => addRequestToRequestGroup(requestGroup)}>
|
||||
<i className="fa fa-plus-circle"></i>
|
||||
</button>
|
||||
<RequestGroupActionsDropdown
|
||||
requestGroup={requestGroup}
|
||||
right={true}
|
||||
className="tall"/>
|
||||
</div>
|
||||
</div>
|
||||
<ul>
|
||||
{expanded && !child.children.length ? this.renderRequestRow() : null}
|
||||
{!expanded ? null : child.children.map(c => this._renderChild(c, child))}
|
||||
</ul>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
renderRequestRow (child = null, parent = null) {
|
||||
const request = child ? child.doc : null;
|
||||
const requestGroup = parent ? parent.doc : null;
|
||||
const {activeRequestId, activateRequest} = this.props;
|
||||
const isActive = request && activeRequestId && request._id === activeRequestId || false;
|
||||
|
||||
return (
|
||||
<SidebarRequestRow
|
||||
key={request ? request._id : null}
|
||||
activateRequest={activateRequest}
|
||||
isActive={isActive}
|
||||
request={request}
|
||||
requestGroup={requestGroup}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
_renderChild (child, parent = null) {
|
||||
const {filter} = this.props;
|
||||
|
||||
if (child.doc.type === 'Request') {
|
||||
const r = child.doc;
|
||||
const toMatch = `${r.method}❅${r.name}`.toLowerCase();
|
||||
const otherMatches = extra || '';
|
||||
const toMatch = `${request.method}❅${request.name}❅${otherMatches}`.toLowerCase();
|
||||
const matchTokens = filter.toLowerCase().split(' ');
|
||||
|
||||
for (let i = 0; i < matchTokens.length; i++) {
|
||||
let token = `${matchTokens[i]}`;
|
||||
if (toMatch.indexOf(token) === -1) {
|
||||
// Filter failed. Don't render children
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return this.renderRequestRow(child, parent)
|
||||
} else if (child.doc.type === 'RequestGroup') {
|
||||
return this.renderRequestGroupRow(child, parent);
|
||||
} else {
|
||||
console.error('Unknown child type', child.doc.type);
|
||||
}
|
||||
return true;
|
||||
})
|
||||
}
|
||||
|
||||
_renderChildren (children, requestGroup) {
|
||||
const {filter} = this.props;
|
||||
|
||||
const filteredChildren = this._filterChildren(
|
||||
filter,
|
||||
children,
|
||||
requestGroup && requestGroup.name
|
||||
).sort((a, b) => a.doc._id > b.doc._id ? -1 : 1);
|
||||
|
||||
return filteredChildren.map(child => {
|
||||
if (child.doc.type === 'Request') {
|
||||
return (
|
||||
<SidebarRequestRow
|
||||
key={child.doc._id}
|
||||
activateRequest={this.props.activateRequest}
|
||||
isActive={child.doc._id === this.props.activeRequestId}
|
||||
request={child.doc}
|
||||
/>
|
||||
)
|
||||
} else if (child.doc.type === 'RequestGroup') {
|
||||
const requestGroup = child.doc;
|
||||
const isActive = !!child.children.find(c => c.doc._id === this.props.activeRequestId);
|
||||
|
||||
return (
|
||||
<SidebarRequestGroupRow
|
||||
key={requestGroup._id}
|
||||
isActive={isActive}
|
||||
toggleRequestGroup={this.props.toggleRequestGroup}
|
||||
addRequestToRequestGroup={this.props.addRequestToRequestGroup}
|
||||
numChildren={child.children.length}
|
||||
requestGroup={requestGroup}
|
||||
>
|
||||
{this._renderChildren(child.children, requestGroup)}
|
||||
</SidebarRequestGroupRow>
|
||||
)
|
||||
} else {
|
||||
console.error('Unknown child type', child.doc.type);
|
||||
return null;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
render () {
|
||||
@@ -122,7 +86,7 @@ class Sidebar extends Component {
|
||||
<div className="grid--v grid--start grid__cell section__body">
|
||||
<ul
|
||||
className="grid--v grid--start grid__cell sidebar__scroll hover-scrollbars sidebar__request-list">
|
||||
{children.map(c => this._renderChild(c))}
|
||||
{this._renderChildren(children)}
|
||||
</ul>
|
||||
<div className="grid grid--center">
|
||||
<div className="grid__cell form-control form-control--underlined">
|
||||
|
||||
71
app/components/SidebarRequestGroupRow.js
Normal file
71
app/components/SidebarRequestGroupRow.js
Normal file
@@ -0,0 +1,71 @@
|
||||
import React, {Component, PropTypes} from 'react'
|
||||
import classnames from 'classnames'
|
||||
import RequestGroupActionsDropdown from './../containers/RequestGroupActionsDropdown'
|
||||
|
||||
class SidebarRequestGroupRow extends Component {
|
||||
render () {
|
||||
const {
|
||||
children,
|
||||
numChildren,
|
||||
requestGroup,
|
||||
isActive,
|
||||
toggleRequestGroup,
|
||||
addRequestToRequestGroup
|
||||
} = this.props;
|
||||
|
||||
// If we are supposed to have children, but aren't passed any, we are probably
|
||||
// filtering so don't render anything
|
||||
if (numChildren >= 0 && children.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let folderIconClass = 'fa-folder';
|
||||
let expanded = !requestGroup.collapsed;
|
||||
folderIconClass += !expanded ? '' : '-open';
|
||||
folderIconClass += isActive ? '' : '-o';
|
||||
|
||||
const sidebarItemClassNames = classnames(
|
||||
'sidebar__item',
|
||||
'sidebar__item--bordered',
|
||||
{'sidebar__item--active': isActive}
|
||||
);
|
||||
|
||||
return (
|
||||
<li key={requestGroup._id}>
|
||||
<div className={sidebarItemClassNames}>
|
||||
<div className="sidebar__item__row sidebar__item__row--heading">
|
||||
<button onClick={e => toggleRequestGroup(requestGroup)}>
|
||||
<i className={'fa ' + folderIconClass}></i>
|
||||
{requestGroup.name}
|
||||
</button>
|
||||
</div>
|
||||
<div className="sidebar__item__btn grid">
|
||||
<button onClick={(e) => addRequestToRequestGroup(requestGroup)}>
|
||||
<i className="fa fa-plus-circle"></i>
|
||||
</button>
|
||||
<RequestGroupActionsDropdown
|
||||
requestGroup={requestGroup}
|
||||
right={true}
|
||||
className="tall"/>
|
||||
</div>
|
||||
</div>
|
||||
<ul>
|
||||
{expanded ? children : null}
|
||||
</ul>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SidebarRequestGroupRow.propTypes = {
|
||||
// Functions
|
||||
toggleRequestGroup: PropTypes.func.isRequired,
|
||||
addRequestToRequestGroup: PropTypes.func.isRequired,
|
||||
|
||||
// Other
|
||||
isActive: PropTypes.bool.isRequired,
|
||||
numChildren: PropTypes.number.isRequired,
|
||||
requestGroup: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
export default SidebarRequestGroupRow;
|
||||
@@ -28,7 +28,7 @@
|
||||
padding: $padding-sm $padding-md $padding-sm $padding-sm;
|
||||
width: 100%;
|
||||
display: block;
|
||||
color: $font-super-light-bg;
|
||||
color: $font-super-light-bg !important;
|
||||
|
||||
&:hover {
|
||||
background: $hl-sm;
|
||||
|
||||
@@ -9,6 +9,7 @@ $border-color: $hl-md;
|
||||
align-items: flex-start;
|
||||
align-content: flex-start;
|
||||
height: $line-height-sm;
|
||||
line-height: $line-height-sm;
|
||||
|
||||
&::after {
|
||||
width: 100%;
|
||||
@@ -21,12 +22,16 @@ $border-color: $hl-md;
|
||||
|
||||
.ReactTabs__Tab {
|
||||
align-self: flex-start;
|
||||
padding: $padding-sm / 4 $padding-md;
|
||||
height: $line-height-sm;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid transparent;
|
||||
border-bottom: 1px solid $border-color;
|
||||
border-top: 0 !important;
|
||||
|
||||
* {
|
||||
color: $hl-xxl;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-left-color: transparent;
|
||||
}
|
||||
@@ -35,23 +40,29 @@ $border-color: $hl-md;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
& > button {
|
||||
color: $hl-xxl;
|
||||
position: relative;
|
||||
& > * {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border-left: 1px solid transparent;
|
||||
border-right: 1px solid transparent;
|
||||
padding-left: $padding-md / 3;
|
||||
padding-right: $padding-md / 3;
|
||||
|
||||
&:first-child {
|
||||
padding-left: $padding-md;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
padding-right: $padding-md;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.ReactTabs__Tab--selected {
|
||||
border: 1px solid $border-color;
|
||||
border-bottom-color: transparent;
|
||||
|
||||
& > button {
|
||||
* {
|
||||
color: inherit;
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
& > button:hover {
|
||||
|
||||
@@ -37,6 +37,10 @@ $modal-width: 50rem;
|
||||
$breakpoint-md: 790px;
|
||||
$breakpoint-sm: 580px;
|
||||
|
||||
.txt-xs {
|
||||
font-size: $font-size-xs;
|
||||
}
|
||||
|
||||
.txt-sm {
|
||||
font-size: $font-size-sm;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user