diff --git a/web/app/js/components/MetricsTable.jsx b/web/app/js/components/MetricsTable.jsx index 86a53d198..4f3961e8f 100644 --- a/web/app/js/components/MetricsTable.jsx +++ b/web/app/js/components/MetricsTable.jsx @@ -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 (