PagerankTable filter defaults to GitHub users (#653)
We humans tend to find information about humans more interesting than information about commits or pulls. The UI should accomodate this by defaulting to displaying GitHub user nodes in the cred explorer. This is implemented as a new nullable argument to the PageRankTable. If not present, then the filter defaults to showing all nodes. If the default filter is present but doesn't match any available type, an error is thrown. Test plan: The new behavior is tested. Also, I checked it in the UI and it works. Closes #651
This commit is contained in:
parent
e3a4d1f2b9
commit
f100cd02cc
|
@ -9,6 +9,7 @@ import BrowserLocalStore from "../browserLocalStore";
|
|||
import {PagerankTable} from "./pagerankTable/Table";
|
||||
import {WeightConfig} from "./WeightConfig";
|
||||
import RepositorySelect from "./RepositorySelect";
|
||||
import {_Prefix as GithubPrefix} from "../../plugins/github/nodes";
|
||||
import {
|
||||
createStateTransitionMachine,
|
||||
type AppState,
|
||||
|
@ -71,6 +72,7 @@ export function createApp(
|
|||
const pnd = appState.substate.pagerankNodeDecomposition;
|
||||
pagerankTable = (
|
||||
<PagerankTable
|
||||
defaultNodeFilter={GithubPrefix.userlike}
|
||||
adapters={adapters}
|
||||
pnd={pnd}
|
||||
maxEntriesPerList={100}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import React from "react";
|
||||
import sortBy from "lodash.sortby";
|
||||
import * as NullUtil from "../../../util/null";
|
||||
|
||||
import {type NodeAddressT, NodeAddress} from "../../../core/graph";
|
||||
import type {PagerankNodeDecomposition} from "../../../core/attribution/pagerankNodeDecomposition";
|
||||
|
@ -15,15 +16,29 @@ type PagerankTableProps = {|
|
|||
+pnd: PagerankNodeDecomposition,
|
||||
+adapters: DynamicAdapterSet,
|
||||
+maxEntriesPerList: number,
|
||||
+defaultNodeFilter: ?NodeAddressT,
|
||||
|};
|
||||
type PagerankTableState = {|topLevelFilter: NodeAddressT|};
|
||||
export class PagerankTable extends React.PureComponent<
|
||||
PagerankTableProps,
|
||||
PagerankTableState
|
||||
> {
|
||||
constructor() {
|
||||
constructor(props: PagerankTableProps): void {
|
||||
super();
|
||||
this.state = {topLevelFilter: NodeAddress.empty};
|
||||
const {defaultNodeFilter, adapters} = props;
|
||||
if (defaultNodeFilter != null) {
|
||||
const nodeTypes = adapters.static().nodeTypes();
|
||||
if (!nodeTypes.some((x) => x.prefix === defaultNodeFilter)) {
|
||||
throw new Error(
|
||||
`invalid defaultNodeFilter ${defaultNodeFilter}: doesn't match any type`
|
||||
);
|
||||
}
|
||||
}
|
||||
const topLevelFilter = NullUtil.orElse(
|
||||
props.defaultNodeFilter,
|
||||
NodeAddress.empty
|
||||
);
|
||||
this.state = {topLevelFilter};
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import React from "react";
|
||||
import {shallow} from "enzyme";
|
||||
|
||||
import {NodeAddress} from "../../../core/graph";
|
||||
import {NodeAddress, type NodeAddressT} from "../../../core/graph";
|
||||
|
||||
import {PagerankTable} from "./Table";
|
||||
import {example, COLUMNS} from "./sharedTestUtils";
|
||||
|
@ -24,7 +24,12 @@ describe("app/credExplorer/pagerankTable/Table", () => {
|
|||
it("renders thead column order properly", async () => {
|
||||
const {pnd, adapters} = await example();
|
||||
const element = shallow(
|
||||
<PagerankTable pnd={pnd} adapters={adapters} maxEntriesPerList={1} />
|
||||
<PagerankTable
|
||||
defaultNodeFilter={null}
|
||||
pnd={pnd}
|
||||
adapters={adapters}
|
||||
maxEntriesPerList={1}
|
||||
/>
|
||||
);
|
||||
const th = element.find("thead th");
|
||||
const columnNames = th.map((t) => t.text());
|
||||
|
@ -32,10 +37,15 @@ describe("app/credExplorer/pagerankTable/Table", () => {
|
|||
});
|
||||
|
||||
describe("has a filter select", () => {
|
||||
async function setup() {
|
||||
async function setup(defaultNodeFilter?: NodeAddressT) {
|
||||
const {pnd, adapters} = await example();
|
||||
const element = shallow(
|
||||
<PagerankTable pnd={pnd} adapters={adapters} maxEntriesPerList={1} />
|
||||
<PagerankTable
|
||||
defaultNodeFilter={defaultNodeFilter}
|
||||
pnd={pnd}
|
||||
adapters={adapters}
|
||||
maxEntriesPerList={1}
|
||||
/>
|
||||
);
|
||||
const label = element.find("label");
|
||||
const options = label.find("option");
|
||||
|
@ -74,6 +84,21 @@ describe("app/credExplorer/pagerankTable/Table", () => {
|
|||
);
|
||||
expect(actualNodes).not.toHaveLength(0);
|
||||
});
|
||||
it("filter defaults to show all if defaultNodeFilter not passed", async () => {
|
||||
const {element} = await setup();
|
||||
expect(element.state().topLevelFilter).toEqual(NodeAddress.empty);
|
||||
});
|
||||
it("filter defaults to defaultNodeFilter if available", async () => {
|
||||
const filter = NodeAddress.fromParts(["foo", "a"]);
|
||||
const {element} = await setup(filter);
|
||||
expect(element.state().topLevelFilter).toEqual(filter);
|
||||
});
|
||||
it("raises an error if defaultNodeFilter doesn't match any node type", async () => {
|
||||
const badFilter = NodeAddress.fromParts(["doesn't", "exist"]);
|
||||
await expect(setup(badFilter)).rejects.toThrow(
|
||||
"invalid defaultNodeFilter"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("creates a NodeRowList", () => {
|
||||
|
@ -82,6 +107,7 @@ describe("app/credExplorer/pagerankTable/Table", () => {
|
|||
const maxEntriesPerList = 1;
|
||||
const element = shallow(
|
||||
<PagerankTable
|
||||
defaultNodeFilter={null}
|
||||
pnd={pnd}
|
||||
adapters={adapters}
|
||||
maxEntriesPerList={maxEntriesPerList}
|
||||
|
|
Loading…
Reference in New Issue