diff --git a/addon/web/client/src/App.css b/addon/web/client/src/App.css index 127b9b2..2be344b 100644 --- a/addon/web/client/src/App.css +++ b/addon/web/client/src/App.css @@ -3,6 +3,15 @@ font-size: 0.8rem; } +.top-control { + display: flex; + align-items: center; +} + +.top-control > div { + margin-right: 20px; +} + .main-table-wrap tbody tr.tr-selected { background-color: rgb(35, 118, 229); color: white; diff --git a/addon/web/client/src/App.js b/addon/web/client/src/App.js index d53b9ea..f31add4 100644 --- a/addon/web/client/src/App.js +++ b/addon/web/client/src/App.js @@ -1,5 +1,8 @@ import React from 'react' import Table from 'react-bootstrap/Table' +import Form from 'react-bootstrap/Form' +import Button from 'react-bootstrap/Button' +import { FlowManager } from './flow' import './App.css' const isTextResponse = response => { @@ -74,14 +77,15 @@ class App extends React.Component { constructor(props) { super(props) + this.flowMgr = new FlowManager() + this.state = { - flows: [], + flows: this.flowMgr.showList(), flow: null, flowTab: 'Headers', // Headers, Preview, Response } this.ws = null - this.flowsMap = new Map() } componentDidMount() { @@ -117,17 +121,17 @@ class App extends React.Component { if (msg.type === 'request') { const flow = { id: msg.id, request: msg.content } - this.flowsMap.set(msg.id, flow) - this.setState({ flows: this.state.flows.concat(flow) }) + this.flowMgr.add(flow) + this.setState({ flows: this.flowMgr.showList() }) } else if (msg.type === 'response') { - const flow = this.flowsMap.get(msg.id) + const flow = this.flowMgr.get(msg.id) if (!flow) return flow.response = msg.content this.setState({ flows: this.state.flows }) } else if (msg.type === 'responseBody') { - const flow = this.flowsMap.get(msg.id) + const flow = this.flowMgr.get(msg.id) if (!flow || !flow.response) return flow.response.body = msg.content this.setState({ flows: this.state.flows }) @@ -218,9 +222,29 @@ class App extends React.Component { const { flows } = this.state return (
No | Host | Path | Method | @@ -233,8 +257,10 @@ class App extends React.Component { flows.map(f => { const url = f.request.url const u = new URL(url) + let host = u.host + if (host.length > 35) host = host.slice(0, 35) + '...' let path = u.pathname + u.search - if (path.length > 60) path = path.slice(0, 60) + '...' + if (path.length > 65) path = path.slice(0, 65) + '...' const request = f.request const response = f.response || {} @@ -242,7 +268,8 @@ class App extends React.Component {||
---|---|---|---|---|---|
{u.host} | +{f.no} | +{host} | {path} | {request.method} | {response.statusCode || '(pending)'} | diff --git a/addon/web/client/src/flow.js b/addon/web/client/src/flow.js new file mode 100644 index 0000000..2731031 --- /dev/null +++ b/addon/web/client/src/flow.js @@ -0,0 +1,54 @@ +export class FlowManager { + constructor() { + this.items = [] + this._map = new Map() + this.filterText = '' + this.filterTimer = null + this.num = 0 + + this.max = 1000 + } + + showList() { + if (!this.filterText) return this.items + return this.items.filter(item => { + return item.request.url.includes(this.filterText) + }) + } + + add(item) { + item.no = ++this.num + this.items.push(item) + this._map.set(item.id, item) + + if (this.items.length > this.max) { + const oldest = this.items.shift() + this._map.delete(oldest.id) + } + } + + get(id) { + return this._map.get(id) + } + + changeFilter(text) { + this.filterText = text + } + + changeFilterLazy(text, callback) { + if (this.filterTimer) { + clearTimeout(this.filterTimer) + this.filterTimer = null + } + + this.filterTimer = setTimeout(() => { + this.filterText = text + callback() + }, 300) + } + + clear() { + this.items = [] + this._map = new Map() + } +}