mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-23 00:01:36 +00:00
Merge pull request #1220 from mitmproxy/add_sorting_with_redux
Add sorting with redux
This commit is contained in:
commit
90cb84b536
@ -1202,6 +1202,14 @@ Object.defineProperty(exports, "__esModule", {
|
||||
|
||||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
||||
|
||||
exports.TLSColumn = TLSColumn;
|
||||
exports.IconColumn = IconColumn;
|
||||
exports.PathColumn = PathColumn;
|
||||
exports.MethodColumn = MethodColumn;
|
||||
exports.StatusColumn = StatusColumn;
|
||||
exports.SizeColumn = SizeColumn;
|
||||
exports.TimeColumn = TimeColumn;
|
||||
|
||||
var _react = require("react");
|
||||
|
||||
var _react2 = _interopRequireDefault(_react);
|
||||
@ -1455,8 +1463,6 @@ var _classnames = require("classnames");
|
||||
|
||||
var _classnames2 = _interopRequireDefault(_classnames);
|
||||
|
||||
var _utils = require("../utils.js");
|
||||
|
||||
var _lodash = require("lodash");
|
||||
|
||||
var _lodash2 = _interopRequireDefault(_lodash);
|
||||
@ -1479,6 +1485,8 @@ var _filt = require("../filt/filt");
|
||||
|
||||
var _filt2 = _interopRequireDefault(_filt);
|
||||
|
||||
var _flows = require("../ducks/flows");
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
@ -1530,88 +1538,59 @@ var FlowRowContainer = (0, _reactRedux.connect)(function (state, ownProps) {
|
||||
};
|
||||
})(FlowRow);
|
||||
|
||||
var FlowTableHead = function (_React$Component) {
|
||||
_inherits(FlowTableHead, _React$Component);
|
||||
function FlowTableHead(_ref2) {
|
||||
var setSort = _ref2.setSort;
|
||||
var columns = _ref2.columns;
|
||||
var sort = _ref2.sort;
|
||||
|
||||
function FlowTableHead(props, context) {
|
||||
_classCallCheck(this, FlowTableHead);
|
||||
var sortColumn = sort.sortColumn;
|
||||
var sortType = sort.sortDesc ? "sort-desc" : "sort-asc";
|
||||
|
||||
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(FlowTableHead).call(this, props, context));
|
||||
|
||||
_this.state = { sortColumn: undefined, sortDesc: false };
|
||||
return _this;
|
||||
}
|
||||
|
||||
_createClass(FlowTableHead, [{
|
||||
key: "onClick",
|
||||
value: function onClick(Column) {
|
||||
var hasSort = Column.sortKeyFun;
|
||||
|
||||
var sortDesc = this.state.sortDesc;
|
||||
|
||||
if (Column === this.state.sortColumn) {
|
||||
sortDesc = !sortDesc;
|
||||
this.setState({ sortDesc: sortDesc });
|
||||
} else {
|
||||
this.setState({ sortColumn: hasSort && Column, sortDesc: false });
|
||||
}
|
||||
|
||||
var sortKeyFun = Column.sortKeyFun;
|
||||
if (sortDesc) {
|
||||
sortKeyFun = hasSort && function () {
|
||||
var k = Column.sortKeyFun.apply(this, arguments);
|
||||
if (_lodash2.default.isString(k)) {
|
||||
return (0, _utils.reverseString)("" + k);
|
||||
}
|
||||
return -k;
|
||||
};
|
||||
}
|
||||
|
||||
this.props.setSortKeyFun(sortKeyFun);
|
||||
}
|
||||
}, {
|
||||
key: "render",
|
||||
value: function render() {
|
||||
var _this2 = this;
|
||||
|
||||
var sortColumn = this.state.sortColumn;
|
||||
var sortType = this.state.sortDesc ? "sort-desc" : "sort-asc";
|
||||
return _react2.default.createElement(
|
||||
"tr",
|
||||
null,
|
||||
this.props.columns.map(function (Column) {
|
||||
return _react2.default.createElement(Column.Title, {
|
||||
key: Column.name,
|
||||
onClick: function onClick() {
|
||||
return _this2.onClick(Column);
|
||||
},
|
||||
className: sortColumn === Column ? sortType : undefined
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
}]);
|
||||
|
||||
return FlowTableHead;
|
||||
}(_react2.default.Component);
|
||||
return _react2.default.createElement(
|
||||
"tr",
|
||||
null,
|
||||
columns.map(function (Column) {
|
||||
return _react2.default.createElement(Column.Title, {
|
||||
key: Column.name,
|
||||
onClick: function onClick() {
|
||||
return setSort({ sortColumn: Column.name, sortDesc: Column.name != sort.sortColumn ? false : !sort.sortDesc });
|
||||
},
|
||||
className: sortColumn === Column.name ? sortType : undefined
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
FlowTableHead.propTypes = {
|
||||
setSortKeyFun: _react2.default.PropTypes.func.isRequired,
|
||||
setSort: _react2.default.PropTypes.func.isRequired,
|
||||
sort: _react2.default.PropTypes.object.isRequired,
|
||||
columns: _react2.default.PropTypes.array.isRequired
|
||||
};
|
||||
|
||||
var FlowTable = function (_React$Component2) {
|
||||
_inherits(FlowTable, _React$Component2);
|
||||
var FlowTableHeadContainer = (0, _reactRedux.connect)(function (state) {
|
||||
return {
|
||||
sort: state.flows.sort
|
||||
};
|
||||
}, function (dispatch) {
|
||||
return {
|
||||
setSort: function setSort(sort) {
|
||||
return dispatch((0, _flows.setSort)(sort));
|
||||
}
|
||||
};
|
||||
})(FlowTableHead);
|
||||
|
||||
var FlowTable = function (_React$Component) {
|
||||
_inherits(FlowTable, _React$Component);
|
||||
|
||||
function FlowTable(props, context) {
|
||||
_classCallCheck(this, FlowTable);
|
||||
|
||||
var _this3 = _possibleConstructorReturn(this, Object.getPrototypeOf(FlowTable).call(this, props, context));
|
||||
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(FlowTable).call(this, props, context));
|
||||
|
||||
_this3.state = { vScroll: (0, _VirtualScroll.calcVScroll)() };
|
||||
_this.state = { vScroll: (0, _VirtualScroll.calcVScroll)() };
|
||||
|
||||
_this3.onViewportUpdate = _this3.onViewportUpdate.bind(_this3);
|
||||
return _this3;
|
||||
_this.onViewportUpdate = _this.onViewportUpdate.bind(_this);
|
||||
return _this;
|
||||
}
|
||||
|
||||
_createClass(FlowTable, [{
|
||||
@ -1627,11 +1606,11 @@ var FlowTable = function (_React$Component2) {
|
||||
}, {
|
||||
key: "componentWillReceiveProps",
|
||||
value: function componentWillReceiveProps(nextProps) {
|
||||
var _this4 = this;
|
||||
var _this2 = this;
|
||||
|
||||
if (nextProps.selected && nextProps.selected !== this.props.selected) {
|
||||
window.setTimeout(function () {
|
||||
return _this4.scrollIntoView(nextProps.selected);
|
||||
return _this2.scrollIntoView(nextProps.selected);
|
||||
}, 1);
|
||||
}
|
||||
}
|
||||
@ -1683,7 +1662,7 @@ var FlowTable = function (_React$Component2) {
|
||||
}, {
|
||||
key: "render",
|
||||
value: function render() {
|
||||
var _this5 = this;
|
||||
var _this3 = this;
|
||||
|
||||
var vScroll = this.state.vScroll;
|
||||
var flows = this.props.flows.slice(vScroll.start, vScroll.end);
|
||||
@ -1699,9 +1678,10 @@ var FlowTable = function (_React$Component2) {
|
||||
_react2.default.createElement(
|
||||
"thead",
|
||||
{ ref: "head", style: { transform: transform } },
|
||||
_react2.default.createElement(FlowTableHead, {
|
||||
_react2.default.createElement(FlowTableHeadContainer, {
|
||||
columns: _flowtableColumns2.default,
|
||||
setSortKeyFun: this.props.setSortKeyFun
|
||||
setSortKeyFun: this.props.setSortKeyFun,
|
||||
setSort: this.props.setSort
|
||||
})
|
||||
),
|
||||
_react2.default.createElement(
|
||||
@ -1713,7 +1693,7 @@ var FlowTable = function (_React$Component2) {
|
||||
key: flow.id,
|
||||
flowId: flow.id,
|
||||
columns: _flowtableColumns2.default,
|
||||
selectFlow: _this5.props.selectFlow
|
||||
selectFlow: _this3.props.selectFlow
|
||||
});
|
||||
}),
|
||||
_react2.default.createElement("tr", { style: { height: vScroll.paddingBottom } })
|
||||
@ -1746,7 +1726,7 @@ var FlowTableContainer = (0, _reactRedux.connect)(function (state) {
|
||||
|
||||
exports.default = FlowTableContainer;
|
||||
|
||||
},{"../filt/filt":29,"../utils.js":32,"./flowtable-columns.js":7,"./helpers/AutoScroll":16,"./helpers/VirtualScroll":17,"classnames":"classnames","lodash":"lodash","react":"react","react-dom":"react-dom","react-redux":"react-redux","shallowequal":"shallowequal"}],9:[function(require,module,exports){
|
||||
},{"../ducks/flows":24,"../filt/filt":29,"./flowtable-columns.js":7,"./helpers/AutoScroll":16,"./helpers/VirtualScroll":17,"classnames":"classnames","lodash":"lodash","react":"react","react-dom":"react-dom","react-redux":"react-redux","shallowequal":"shallowequal"}],9:[function(require,module,exports){
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
@ -3811,9 +3791,6 @@ var MainView = _react2.default.createClass({
|
||||
this.props.setHighlight(nextProps.location.query[_actions.Query.HIGHLIGHT], false);
|
||||
}
|
||||
},
|
||||
setSortKeyFun: function setSortKeyFun(sortKeyFun) {
|
||||
// FIXME: Move to redux. This requires that sortKeyFun is not a function anymore.
|
||||
},
|
||||
selectFlow: function selectFlow(flow) {
|
||||
// TODO: This belongs into redux
|
||||
if (flow) {
|
||||
@ -3944,7 +3921,6 @@ var MainView = _react2.default.createClass({
|
||||
{ className: "main-view" },
|
||||
_react2.default.createElement(_flowtable2.default, { ref: "flowTable",
|
||||
selectFlow: this.selectFlow,
|
||||
setSortKeyFun: this.setSortKeyFun,
|
||||
selected: this.props.selectedFlow }),
|
||||
details
|
||||
);
|
||||
@ -4496,13 +4472,14 @@ exports.fetchLogEntries = fetchList;
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.fetchFlows = exports.updateFlows = exports.SELECT_FLOW = exports.SET_HIGHLIGHT = exports.SET_FILTER = exports.UPDATE_FLOWS = undefined;
|
||||
exports.fetchFlows = exports.updateFlows = exports.SELECT_FLOW = exports.SET_SORT = exports.SET_HIGHLIGHT = exports.SET_FILTER = exports.UPDATE_FLOWS = undefined;
|
||||
|
||||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
||||
|
||||
exports.default = reducer;
|
||||
exports.setFilter = setFilter;
|
||||
exports.setHighlight = setHighlight;
|
||||
exports.setSort = setSort;
|
||||
exports.selectFlow = selectFlow;
|
||||
|
||||
var _list = require("./utils/list");
|
||||
@ -4515,11 +4492,20 @@ var _filt2 = _interopRequireDefault(_filt);
|
||||
|
||||
var _view = require("./utils/view");
|
||||
|
||||
var _utils = require("../utils.js");
|
||||
|
||||
var _flowtableColumns = require("../components/flowtable-columns.js");
|
||||
|
||||
var flow_table_columns = _interopRequireWildcard(_flowtableColumns);
|
||||
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
var UPDATE_FLOWS = exports.UPDATE_FLOWS = "UPDATE_FLOWS";
|
||||
var SET_FILTER = exports.SET_FILTER = "SET_FLOW_FILTER";
|
||||
var SET_HIGHLIGHT = exports.SET_HIGHLIGHT = "SET_FLOW_HIGHLIGHT";
|
||||
var SET_SORT = exports.SET_SORT = "SET_FLOW_SORT";
|
||||
var SELECT_FLOW = exports.SELECT_FLOW = "SELECT_FLOW";
|
||||
|
||||
var _makeList = (0, _list2.default)(UPDATE_FLOWS, "/flows");
|
||||
@ -4534,7 +4520,8 @@ var defaultState = {
|
||||
selected: [],
|
||||
view: [],
|
||||
filter: undefined,
|
||||
highlight: undefined
|
||||
highlight: undefined,
|
||||
sort: { sortColumn: undefined, sortDesc: false }
|
||||
};
|
||||
|
||||
function makeFilterFn(filter) {
|
||||
@ -4543,6 +4530,20 @@ function makeFilterFn(filter) {
|
||||
};
|
||||
}
|
||||
|
||||
function makeSortFn(sort) {
|
||||
var column = flow_table_columns[sort.sortColumn];
|
||||
if (!column) return;
|
||||
|
||||
var sortKeyFun = column.sortKeyFun;
|
||||
if (sort.sortDesc) {
|
||||
sortKeyFun = sortKeyFun && function (flow) {
|
||||
var k = column.sortKeyFun(flow);
|
||||
return _.isString(k) ? (0, _utils.reverseString)("" + k) : -k;
|
||||
};
|
||||
}
|
||||
return sortKeyFun;
|
||||
}
|
||||
|
||||
function reducer() {
|
||||
var state = arguments.length <= 0 || arguments[0] === undefined ? defaultState : arguments[0];
|
||||
var action = arguments[1];
|
||||
@ -4552,17 +4553,22 @@ function reducer() {
|
||||
var all = reduceList(state.all, action);
|
||||
return _extends({}, state, {
|
||||
all: all,
|
||||
view: (0, _view.updateViewList)(state.view, state.all, all, action, makeFilterFn(action.filter))
|
||||
view: (0, _view.updateViewList)(state.view, state.all, all, action, makeFilterFn(action.filter), makeSortFn(state.sort))
|
||||
});
|
||||
case SET_FILTER:
|
||||
return _extends({}, state, {
|
||||
filter: action.filter,
|
||||
view: (0, _view.updateViewFilter)(state.all, makeFilterFn(action.filter))
|
||||
view: (0, _view.updateViewFilter)(state.all, makeFilterFn(action.filter), makeSortFn(state.sort))
|
||||
});
|
||||
case SET_HIGHLIGHT:
|
||||
return _extends({}, state, {
|
||||
highlight: action.highlight
|
||||
});
|
||||
case SET_SORT:
|
||||
return _extends({}, state, {
|
||||
sort: action.sort,
|
||||
view: (0, _view.updateViewSort)(state.view, makeSortFn(action.sort))
|
||||
});
|
||||
case SELECT_FLOW:
|
||||
return _extends({}, state, {
|
||||
selected: [action.flowId]
|
||||
@ -4584,6 +4590,12 @@ function setHighlight(highlight) {
|
||||
highlight: highlight
|
||||
};
|
||||
}
|
||||
function setSort(sort) {
|
||||
return {
|
||||
type: SET_SORT,
|
||||
sort: sort
|
||||
};
|
||||
}
|
||||
function selectFlow(flowId) {
|
||||
return {
|
||||
type: SELECT_FLOW,
|
||||
@ -4594,7 +4606,7 @@ function selectFlow(flowId) {
|
||||
exports.updateFlows = updateList;
|
||||
exports.fetchFlows = fetchList;
|
||||
|
||||
},{"../filt/filt":29,"./utils/list":26,"./utils/view":27}],25:[function(require,module,exports){
|
||||
},{"../components/flowtable-columns.js":7,"../filt/filt":29,"../utils.js":32,"./utils/list":26,"./utils/view":27}],25:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
@ -4839,6 +4851,7 @@ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol
|
||||
exports.sortedIndexOf = sortedIndexOf;
|
||||
exports.updateViewList = updateViewList;
|
||||
exports.updateViewFilter = updateViewFilter;
|
||||
exports.updateViewSort = updateViewSort;
|
||||
|
||||
var _list = require("./list");
|
||||
|
||||
@ -4895,12 +4908,10 @@ var sortedRemove = function sortedRemove(list, sortFn, item) {
|
||||
};
|
||||
|
||||
function sortedIndexOf(list, value, sortFn) {
|
||||
if (sortFn === false) {
|
||||
var i = 0;
|
||||
while (i < list.length && list[i].id !== value.id) {
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
if (!sortFn) {
|
||||
sortFn = function sortFn(x) {
|
||||
return 0;
|
||||
}; // This triggers the linear search for flows that have the same sort value.
|
||||
}
|
||||
|
||||
var low = 0,
|
||||
@ -4992,6 +5003,20 @@ function updateViewFilter(list) {
|
||||
return filtered;
|
||||
}
|
||||
|
||||
function updateViewSort(list) {
|
||||
var sortFn = arguments.length <= 1 || arguments[1] === undefined ? defaultSortFn : arguments[1];
|
||||
|
||||
var sorted = list.slice(0);
|
||||
if (sortFn) {
|
||||
sorted.sort(makeCompareFn(sortFn));
|
||||
}
|
||||
sorted.indexOf = function (x) {
|
||||
return sortedIndexOf(sorted, x, sortFn);
|
||||
};
|
||||
|
||||
return sorted;
|
||||
}
|
||||
|
||||
},{"./list":26}],28:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,7 @@ import {RequestUtils, ResponseUtils} from "../flow/utils.js"
|
||||
import {formatSize, formatTimeDelta} from "../utils.js"
|
||||
|
||||
|
||||
function TLSColumn({flow}) {
|
||||
export function TLSColumn({flow}) {
|
||||
let ssl = (flow.request.scheme === "https")
|
||||
let classes
|
||||
if (ssl) {
|
||||
@ -17,7 +17,7 @@ TLSColumn.Title = ({className = "", ...props}) => <th {...props} className={"col
|
||||
TLSColumn.sortKeyFun = flow => flow.request.scheme
|
||||
|
||||
|
||||
function IconColumn({flow}) {
|
||||
export function IconColumn({flow}) {
|
||||
let icon
|
||||
if (flow.response) {
|
||||
var contentType = ResponseUtils.getContentType(flow.response)
|
||||
@ -49,7 +49,7 @@ function IconColumn({flow}) {
|
||||
IconColumn.Title = ({className = "", ...props}) => <th {...props} className={"col-icon " + className }></th>
|
||||
|
||||
|
||||
function PathColumn({flow}) {
|
||||
export function PathColumn({flow}) {
|
||||
return <td className="col-path">
|
||||
{flow.request.is_replay ? <i className="fa fa-fw fa-repeat pull-right"></i> : null}
|
||||
{flow.intercepted ? <i className="fa fa-fw fa-pause pull-right"></i> : null}
|
||||
@ -61,7 +61,7 @@ PathColumn.Title = ({className = "", ...props}) =>
|
||||
PathColumn.sortKeyFun = flow => RequestUtils.pretty_url(flow.request)
|
||||
|
||||
|
||||
function MethodColumn({flow}) {
|
||||
export function MethodColumn({flow}) {
|
||||
return <td className="col-method">{flow.request.method}</td>
|
||||
}
|
||||
MethodColumn.Title = ({className = "", ...props}) =>
|
||||
@ -69,7 +69,7 @@ MethodColumn.Title = ({className = "", ...props}) =>
|
||||
MethodColumn.sortKeyFun = flow => flow.request.method
|
||||
|
||||
|
||||
function StatusColumn({flow}) {
|
||||
export function StatusColumn({flow}) {
|
||||
let status
|
||||
if (flow.response) {
|
||||
status = flow.response.status_code
|
||||
@ -84,7 +84,7 @@ StatusColumn.Title = ({className = "", ...props}) =>
|
||||
StatusColumn.sortKeyFun = flow => flow.response ? flow.response.status_code : undefined
|
||||
|
||||
|
||||
function SizeColumn({flow}) {
|
||||
export function SizeColumn({flow}) {
|
||||
let total = flow.request.contentLength
|
||||
if (flow.response) {
|
||||
total += flow.response.contentLength || 0
|
||||
@ -104,7 +104,7 @@ SizeColumn.sortKeyFun = flow => {
|
||||
}
|
||||
|
||||
|
||||
function TimeColumn({flow}) {
|
||||
export function TimeColumn({flow}) {
|
||||
let time
|
||||
if (flow.response) {
|
||||
time = formatTimeDelta(1000 * (flow.response.timestamp_end - flow.request.timestamp_start))
|
||||
|
@ -2,13 +2,13 @@ import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import {connect} from 'react-redux'
|
||||
import classNames from "classnames";
|
||||
import {reverseString} from "../utils.js";
|
||||
import _ from "lodash";
|
||||
import shallowEqual from "shallowequal";
|
||||
import AutoScroll from "./helpers/AutoScroll";
|
||||
import {calcVScroll} from "./helpers/VirtualScroll";
|
||||
import flowtable_columns from "./flowtable-columns.js";
|
||||
import Filt from "../filt/filt";
|
||||
import {setSort} from "../ducks/flows";
|
||||
|
||||
|
||||
FlowRow.propTypes = {
|
||||
@ -46,61 +46,38 @@ const FlowRowContainer = connect(
|
||||
})
|
||||
)(FlowRow)
|
||||
|
||||
class FlowTableHead extends React.Component {
|
||||
function FlowTableHead({setSort, columns, sort}) {
|
||||
const sortColumn = sort.sortColumn;
|
||||
const sortType = sort.sortDesc ? "sort-desc" : "sort-asc";
|
||||
|
||||
static propTypes = {
|
||||
setSortKeyFun: React.PropTypes.func.isRequired,
|
||||
columns: React.PropTypes.array.isRequired,
|
||||
};
|
||||
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
this.state = {sortColumn: undefined, sortDesc: false};
|
||||
}
|
||||
|
||||
onClick(Column) {
|
||||
const hasSort = Column.sortKeyFun;
|
||||
|
||||
let sortDesc = this.state.sortDesc;
|
||||
|
||||
if (Column === this.state.sortColumn) {
|
||||
sortDesc = !sortDesc;
|
||||
this.setState({sortDesc});
|
||||
} else {
|
||||
this.setState({sortColumn: hasSort && Column, sortDesc: false});
|
||||
}
|
||||
|
||||
let sortKeyFun = Column.sortKeyFun;
|
||||
if (sortDesc) {
|
||||
sortKeyFun = hasSort && function () {
|
||||
const k = Column.sortKeyFun.apply(this, arguments);
|
||||
if (_.isString(k)) {
|
||||
return reverseString("" + k);
|
||||
}
|
||||
return -k;
|
||||
};
|
||||
}
|
||||
|
||||
this.props.setSortKeyFun(sortKeyFun);
|
||||
}
|
||||
|
||||
render() {
|
||||
const sortColumn = this.state.sortColumn;
|
||||
const sortType = this.state.sortDesc ? "sort-desc" : "sort-asc";
|
||||
return (
|
||||
<tr>
|
||||
{this.props.columns.map(Column => (
|
||||
{columns.map(Column => (
|
||||
<Column.Title
|
||||
key={Column.name}
|
||||
onClick={() => this.onClick(Column)}
|
||||
className={sortColumn === Column ? sortType : undefined}
|
||||
onClick={() => setSort({sortColumn: Column.name, sortDesc: Column.name != sort.sortColumn ? false : !sort.sortDesc})}
|
||||
className={sortColumn === Column.name ? sortType : undefined}
|
||||
/>
|
||||
))}
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
FlowTableHead.propTypes = {
|
||||
setSort: React.PropTypes.func.isRequired,
|
||||
sort: React.PropTypes.object.isRequired,
|
||||
columns: React.PropTypes.array.isRequired
|
||||
};
|
||||
|
||||
const FlowTableHeadContainer = connect(
|
||||
state => ({
|
||||
sort: state.flows.sort
|
||||
}),
|
||||
dispatch => ({
|
||||
setSort: (sort) => dispatch(setSort(sort)),
|
||||
})
|
||||
)(FlowTableHead)
|
||||
|
||||
class FlowTable extends React.Component {
|
||||
|
||||
static propTypes = {
|
||||
@ -186,9 +163,10 @@ class FlowTable extends React.Component {
|
||||
<div className="flow-table" onScroll={this.onViewportUpdate}>
|
||||
<table>
|
||||
<thead ref="head" style={{ transform }}>
|
||||
<FlowTableHead
|
||||
<FlowTableHeadContainer
|
||||
columns={flowtable_columns}
|
||||
setSortKeyFun={this.props.setSortKeyFun}
|
||||
setSort={this.props.setSort}
|
||||
/>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -216,7 +194,7 @@ const parseFilter = _.memoize(Filt.parse)
|
||||
|
||||
const FlowTableContainer = connect(
|
||||
state => ({
|
||||
flows: state.flows.view,
|
||||
flows: state.flows.view
|
||||
})
|
||||
)(FlowTable)
|
||||
|
||||
|
@ -23,9 +23,6 @@ var MainView = React.createClass({
|
||||
this.props.setHighlight(nextProps.location.query[Query.HIGHLIGHT], false)
|
||||
}
|
||||
},
|
||||
setSortKeyFun: function (sortKeyFun) {
|
||||
// FIXME: Move to redux. This requires that sortKeyFun is not a function anymore.
|
||||
},
|
||||
selectFlow: function (flow) {
|
||||
// TODO: This belongs into redux
|
||||
if (flow) {
|
||||
@ -161,7 +158,6 @@ var MainView = React.createClass({
|
||||
<div className="main-view">
|
||||
<FlowTable ref="flowTable"
|
||||
selectFlow={this.selectFlow}
|
||||
setSortKeyFun={this.setSortKeyFun}
|
||||
selected={this.props.selectedFlow} />
|
||||
{details}
|
||||
</div>
|
||||
|
@ -1,10 +1,13 @@
|
||||
import makeList from "./utils/list"
|
||||
import Filt from "../filt/filt"
|
||||
import {updateViewFilter, updateViewList} from "./utils/view"
|
||||
import {updateViewFilter, updateViewList, updateViewSort} from "./utils/view"
|
||||
import {reverseString} from "../utils.js";
|
||||
import * as flow_table_columns from "../components/flowtable-columns.js";
|
||||
|
||||
export const UPDATE_FLOWS = "UPDATE_FLOWS"
|
||||
export const SET_FILTER = "SET_FLOW_FILTER"
|
||||
export const SET_HIGHLIGHT = "SET_FLOW_HIGHLIGHT"
|
||||
export const SET_SORT = "SET_FLOW_SORT"
|
||||
export const SELECT_FLOW = "SELECT_FLOW"
|
||||
|
||||
const {
|
||||
@ -20,12 +23,28 @@ const defaultState = {
|
||||
view: [],
|
||||
filter: undefined,
|
||||
highlight: undefined,
|
||||
sort: {sortColumn: undefined, sortDesc: false},
|
||||
}
|
||||
|
||||
function makeFilterFn(filter) {
|
||||
return filter ? Filt.parse(filter) : () => true;
|
||||
}
|
||||
|
||||
|
||||
function makeSortFn(sort){
|
||||
let column = flow_table_columns[sort.sortColumn];
|
||||
if (!column) return;
|
||||
|
||||
let sortKeyFun = column.sortKeyFun;
|
||||
if (sort.sortDesc) {
|
||||
sortKeyFun = sortKeyFun && function (flow) {
|
||||
const k = column.sortKeyFun(flow);
|
||||
return _.isString(k) ? reverseString("" + k) : -k;
|
||||
};
|
||||
}
|
||||
return sortKeyFun;
|
||||
}
|
||||
|
||||
export default function reducer(state = defaultState, action) {
|
||||
switch (action.type) {
|
||||
case UPDATE_FLOWS:
|
||||
@ -33,19 +52,25 @@ export default function reducer(state = defaultState, action) {
|
||||
return {
|
||||
...state,
|
||||
all,
|
||||
view: updateViewList(state.view, state.all, all, action, makeFilterFn(action.filter))
|
||||
view: updateViewList(state.view, state.all, all, action, makeFilterFn(action.filter), makeSortFn(state.sort))
|
||||
}
|
||||
case SET_FILTER:
|
||||
return {
|
||||
...state,
|
||||
filter: action.filter,
|
||||
view: updateViewFilter(state.all, makeFilterFn(action.filter))
|
||||
view: updateViewFilter(state.all, makeFilterFn(action.filter), makeSortFn(state.sort))
|
||||
}
|
||||
case SET_HIGHLIGHT:
|
||||
return {
|
||||
...state,
|
||||
highlight: action.highlight
|
||||
}
|
||||
case SET_SORT:
|
||||
return {
|
||||
...state,
|
||||
sort: action.sort,
|
||||
view: updateViewSort(state.view, makeSortFn(action.sort))
|
||||
}
|
||||
case SELECT_FLOW:
|
||||
return {
|
||||
...state,
|
||||
@ -69,6 +94,12 @@ export function setHighlight(highlight) {
|
||||
highlight
|
||||
}
|
||||
}
|
||||
export function setSort(sort){
|
||||
return {
|
||||
type: SET_SORT,
|
||||
sort
|
||||
}
|
||||
}
|
||||
export function selectFlow(flowId) {
|
||||
return {
|
||||
type: SELECT_FLOW,
|
||||
|
@ -122,3 +122,13 @@ export function updateViewFilter(list, filterFn = defaultFilterFn, sortFn = defa
|
||||
|
||||
return filtered
|
||||
}
|
||||
|
||||
export function updateViewSort(list, sortFn = defaultSortFn) {
|
||||
let sorted = list.slice(0)
|
||||
if (sortFn) {
|
||||
sorted.sort(makeCompareFn(sortFn))
|
||||
}
|
||||
sorted.indexOf = x => sortedIndexOf(sorted, x, sortFn)
|
||||
|
||||
return sorted
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user