add a filter on web ui

This commit is contained in:
OttoMao 2015-07-01 23:18:35 +08:00
parent ab5bd5d6e6
commit b595e3aa9c
9 changed files with 207 additions and 15 deletions

View File

@ -1,3 +1,11 @@
1 July: anyproxy 3.6.0:
* add a filter on web ui
1 July: anyproxy 3.5.2:
* optimize the row height on web ui
18 June: anyproxy 3.5.1: 18 June: anyproxy 3.5.1:
* print a hint when using SNI features in node <0.12 * print a hint when using SNI features in node <0.12

View File

@ -1,6 +1,6 @@
{ {
"name": "anyproxy", "name": "anyproxy",
"version": "3.5.2", "version": "3.6.0",
"description": "A fully configurable proxy in NodeJS, which can handle HTTPS requests perfectly.", "description": "A fully configurable proxy in NodeJS, which can handle HTTPS requests perfectly.",
"main": "proxy.js", "main": "proxy.js",
"bin": { "bin": {

View File

@ -101,6 +101,12 @@ var eventCenter = new EventManager();
list : recordSet list : recordSet
}); });
}); });
eventCenter.addListener("filterUpdated",function(newKeyword){
Panel.setState({
filter: newKeyword
});
});
})(); })();
@ -138,4 +144,27 @@ var eventCenter = new EventManager();
ifPause = false; ifPause = false;
} }
}); });
function switchFilterWidget(ifToShow){
if(ifToShow){
$(".J_filterSection").show();
$("#J_filterKeyword").focus();
}else{
$(".J_filterSection").hide();
$("#J_filterKeyword").val("");
}
}
$(".J_toggleFilterBtn").on("click",function(){
switchFilterWidget( $(".J_filterSection").css("display") == "none" );
});
$(".J_filterCloseBtn").on("click",function(){
switchFilterWidget(false);
});
$("#J_filterKeyword").on("change keyup",function(){
eventCenter.dispatchEvent("filterUpdated",this.value);
});
})(); })();

View File

@ -4,14 +4,34 @@ function init(React){
var RecordPanel = React.createClass({displayName: "RecordPanel", var RecordPanel = React.createClass({displayName: "RecordPanel",
getInitialState : function(){ getInitialState : function(){
return { return {
list : [] list : [],
filter: ""
}; };
}, },
render : function(){ render : function(){
var rowCollection = []; var rowCollection = [],
filterStr = this.state.filter,
filter = filterStr;
//regexp
if(filterStr[0]=="/" && filterStr[filterStr.length-1]=="/"){
try{
filter = new RegExp(filterStr.substr(1,filterStr.length-2));
}catch(e){}
}
for(var i = this.state.list.length-1 ; i >=0 ; i--){ for(var i = this.state.list.length-1 ; i >=0 ; i--){
var item = this.state.list[i]; var item = this.state.list[i];
if(item){ if(item){
if(filter && item){
try{
if(typeof filter == "object" && !filter.test(item.url)){
continue;
}else if(typeof filter == "string" && item.url.indexOf(filter) < 0){
continue;
}
}catch(e){}
}
if(item._justUpdated){ if(item._justUpdated){
item._justUpdated = false; item._justUpdated = false;

View File

@ -286,3 +286,30 @@ body, html {
cursor: col-resize; cursor: col-resize;
z-index:999 z-index:999
} }
.filterSection{
background: #FFF;
padding: 15px 10px;
position: absolute;
left: 0;
top: 0;
border: 1px solid #333;
border-radius: 3px;
}
.filterSection .filterIcon{
font-size: 16px;
}
.filterSection form{
display: inline-block;
margin-right: 5px;
}
.filterSection input{
width: 250px;
}
.filterSection i{
cursor: pointer;
}

View File

@ -14,21 +14,31 @@
</div> </div>
<div class="ctrlWrapper"> <div class="ctrlWrapper">
<a href="#"><span class="J_statusBtn topBtn"><i class="uk-icon-stop"></i>Stop</span></a> <a href="#"><span class="topBtn J_statusBtn"><i class="uk-icon-stop"></i>Stop</span></a>
<a href="#"><span class="J_statusBtn btn_disable topBtn"><i class="uk-icon-play"></i>Resume</span></a> <a href="#"><span class="topBtn J_statusBtn btn_disable"><i class="uk-icon-play"></i>Resume</span></a>
<a href="#" class="J_clearBtn"><span class="topBtn"><i class="uk-icon-eraser"></i>Clear(Ctrl+X)</span></a> <a href="#"><span class="topBtn J_toggleFilterBtn"><i class="uk-icon-filter"></i>Filter</span></a>
<span class="sep">|</span> <a href="#"><span class="topBtn J_clearBtn"><i class="uk-icon-eraser"></i>Clear(Ctrl+X)</span></a>
<a href="/fetchCrtFile" target="_blank"><span class="topBtn"><i class="uk-icon-certificate"></i>Download rootCA.crt</span></a>
<a href="/qr_root" class="J_fetchRootQR" target="_blank"><span class="topBtn"><i class="uk-icon-certificate"></i>QRCode of rootCA.crt</span></a>
<span class="sep">|</span> <span class="sep">|</span>
<a href="https://github.com/alibaba/anyproxy" target="_blank"><span class="topBtn"><i class="uk-icon-external-link-square"></i>Anyproxy(Github)</span></a> <a href="/fetchCrtFile" target="_blank"><span class="topBtn"><i class="uk-icon-certificate"></i>Download rootCA.crt</span></a>
<a href="/qr_root" class="J_fetchRootQR" target="_blank"><span class="topBtn"><i class="uk-icon-qrcode"></i>QRCode of rootCA.crt</span></a>
<span class="sep">|</span>
<a href="https://github.com/alibaba/anyproxy" target="_blank"><span class="topBtn"><i class="uk-icon-external-link-square"></i>Github</span></a>
</div> </div>
<div class="ruleDesc"> <div class="ruleDesc">
<span><i class="uk-icon-chain"></i>{{rule}}</span> <span><i class="uk-icon-chain"></i>Rule : {{rule}}</span>
</div> </div>
<div class="filterSection J_filterSection" style="display:none">
<form class="uk-form">
<input class="uk-form-large" type="text" id="J_filterKeyword" placeholder="type keywords or /^regExp$/" width="200"/>
</form>
<i class="uk-icon-times J_filterCloseBtn"></i>
</div>
<div style="clear:both"></div> <div style="clear:both"></div>
</div> </div>

View File

@ -147,6 +147,12 @@
list : recordSet list : recordSet
}); });
}); });
eventCenter.addListener("filterUpdated",function(newKeyword){
Panel.setState({
filter: newKeyword
});
});
})(); })();
@ -184,6 +190,29 @@
ifPause = false; ifPause = false;
} }
}); });
function switchFilterWidget(ifToShow){
if(ifToShow){
$(".J_filterSection").show();
$("#J_filterKeyword").focus();
}else{
$(".J_filterSection").hide();
$("#J_filterKeyword").val("");
}
}
$(".J_toggleFilterBtn").on("click",function(){
switchFilterWidget( $(".J_filterSection").css("display") == "none" );
});
$(".J_filterCloseBtn").on("click",function(){
switchFilterWidget(false);
});
$("#J_filterKeyword").on("change keyup",function(){
eventCenter.dispatchEvent("filterUpdated",this.value);
});
})(); })();
/***/ }, /***/ },
@ -395,14 +424,34 @@
var RecordPanel = React.createClass({displayName: "RecordPanel", var RecordPanel = React.createClass({displayName: "RecordPanel",
getInitialState : function(){ getInitialState : function(){
return { return {
list : [] list : [],
filter: ""
}; };
}, },
render : function(){ render : function(){
var rowCollection = []; var rowCollection = [],
filterStr = this.state.filter,
filter = filterStr;
//regexp
if(filterStr[0]=="/" && filterStr[filterStr.length-1]=="/"){
try{
filter = new RegExp(filterStr.substr(1,filterStr.length-2));
}catch(e){}
}
for(var i = this.state.list.length-1 ; i >=0 ; i--){ for(var i = this.state.list.length-1 ; i >=0 ; i--){
var item = this.state.list[i]; var item = this.state.list[i];
if(item){ if(item){
if(filter && item){
try{
if(typeof filter == "object" && !filter.test(item.url)){
continue;
}else if(typeof filter == "string" && item.url.indexOf(filter) < 0){
continue;
}
}catch(e){}
}
if(item._justUpdated){ if(item._justUpdated){
item._justUpdated = false; item._justUpdated = false;

View File

@ -101,6 +101,12 @@ var eventCenter = new EventManager();
list : recordSet list : recordSet
}); });
}); });
eventCenter.addListener("filterUpdated",function(newKeyword){
Panel.setState({
filter: newKeyword
});
});
})(); })();
@ -138,4 +144,27 @@ var eventCenter = new EventManager();
ifPause = false; ifPause = false;
} }
}); });
function switchFilterWidget(ifToShow){
if(ifToShow){
$(".J_filterSection").show();
$("#J_filterKeyword").focus();
}else{
$(".J_filterSection").hide();
$("#J_filterKeyword").val("");
}
}
$(".J_toggleFilterBtn").on("click",function(){
switchFilterWidget( $(".J_filterSection").css("display") == "none" );
});
$(".J_filterCloseBtn").on("click",function(){
switchFilterWidget(false);
});
$("#J_filterKeyword").on("change keyup",function(){
eventCenter.dispatchEvent("filterUpdated",this.value);
});
})(); })();

View File

@ -4,14 +4,34 @@ function init(React){
var RecordPanel = React.createClass({ var RecordPanel = React.createClass({
getInitialState : function(){ getInitialState : function(){
return { return {
list : [] list : [],
filter: ""
}; };
}, },
render : function(){ render : function(){
var rowCollection = []; var rowCollection = [],
filterStr = this.state.filter,
filter = filterStr;
//regexp
if(filterStr[0]=="/" && filterStr[filterStr.length-1]=="/"){
try{
filter = new RegExp(filterStr.substr(1,filterStr.length-2));
}catch(e){}
}
for(var i = this.state.list.length-1 ; i >=0 ; i--){ for(var i = this.state.list.length-1 ; i >=0 ; i--){
var item = this.state.list[i]; var item = this.state.list[i];
if(item){ if(item){
if(filter && item){
try{
if(typeof filter == "object" && !filter.test(item.url)){
continue;
}else if(typeof filter == "string" && item.url.indexOf(filter) < 0){
continue;
}
}catch(e){}
}
if(item._justUpdated){ if(item._justUpdated){
item._justUpdated = false; item._justUpdated = false;