Add a filter to the namespace column in the web UI
Enables filtering by one or more namespaces. Table updates are prevented
when the filter menu is open, as table updates will rerender the menu,
unselecting anything the user has selected but not confirmed.
@@ -29,12 +29,15 @@ const formatLongTitles = title => {
return words;
}
};
-const columnDefinitions = (sortable = true, resource, ConduitLink) => {
+const columnDefinitions = (sortable = true, resource, namespaces, onFilterClick, ConduitLink) => {
return [
{
title: "Namespace",
key: "namespace",
dataIndex: "namespace",
+ filters: namespaces,
+ onFilterDropdownVisibleChange: onFilterClick,
+ onFilter: (value, row) => row.namespace.indexOf(value) === 0,
sorter: sortable ? (a, b) => (a.namespace || "").localeCompare(b.namespace) : false
},
{
@@ -102,26 +105,56 @@ export default class MetricsTable extends BaseTable {
constructor(props) {
super(props);
this.api = this.props.api;
+ this.onFilterDropdownVisibleChange = this.onFilterDropdownVisibleChange.bind(this);
+ this.state = {
+ preventTableUpdates: false
+ };
}
preprocessMetrics() {
let tableData = _.cloneDeep(this.props.metrics);
+ let namespaces = [];
_.each(tableData, datum => {
+ namespaces.push(datum.namespace);
_.each(datum.latency, (value, quantile) => {
datum[quantile] = value;
});
});
- return tableData;
+ return {
+ rows: tableData,
+ namespaces: _.uniq(namespaces)
+ };
+ }
+
+ shouldComponentUpdate() {
+ // prevent the table from updating if the filter dropdown menu is open
+ // this is because if the table updates, the filters will reset which
+ // makes it impossible to select a filter
+ return !this.state.preventTableUpdates;
+ }
+
+ onFilterDropdownVisibleChange(dropdownVisible) {
+ this.setState({ preventTableUpdates: dropdownVisible});
}
render() {
let tableData = this.preprocessMetrics();
- let columns = _.compact(columnDefinitions(this.props.sortable, this.props.resource, this.api.ConduitLink));
+ let namespaceFilterText = _.map(tableData.namespaces, ns => {
+ return { text: ns, value: ns };
+ });
+
+ let columns = _.compact(columnDefinitions(
+ this.props.sortable,
+ this.props.resource,
+ namespaceFilterText,
+ this.onFilterDropdownVisibleChange,
+ this.api.ConduitLink
+ ));
return (<BaseTable
- dataSource={tableData}
+ dataSource={tableData.rows}
columns={columns}
pagination={false}
className="conduit-table"
