mirror of
https://github.com/status-im/sourcecred.git
synced 2025-01-14 14:46:30 +00:00
Show all plugins' types in legacy ui (#1429)
This commit upgrades the legacy explorer to now properly include types from all loaded plugins, rather than just the GitHub plugin. This makes the legacy UI much more usable for inspecting SourceCred's own (multi-plugin) cred. Test plan: Manual inspection of the frontend. `yarn test` passes. Part of https://discourse.sourcecred.io/t/fixup-legacy-explorer/316
This commit is contained in:
parent
3754cafb7d
commit
dfc7ee8524
@ -8,7 +8,6 @@ import CheckedLocalStore from "../../webutil/checkedLocalStore";
|
||||
import BrowserLocalStore from "../../webutil/browserLocalStore";
|
||||
import Link from "../../webutil/Link";
|
||||
import {type NodeAddressT} from "../../core/graph";
|
||||
import {declaration as githubDeclaration} from "../../plugins/github/declaration";
|
||||
|
||||
import {PagerankTable} from "./pagerankTable/Table";
|
||||
import {WeightConfig} from "../weights/WeightConfig";
|
||||
@ -84,25 +83,6 @@ export function createApp(
|
||||
|
||||
render() {
|
||||
const {appState} = this.state;
|
||||
const weightConfig = (
|
||||
<WeightConfig
|
||||
declarations={[githubDeclaration]}
|
||||
nodeTypeWeights={this.state.weights.nodeTypeWeights}
|
||||
edgeTypeWeights={this.state.weights.edgeTypeWeights}
|
||||
onNodeWeightChange={(prefix, weight) => {
|
||||
this.setState(({weights}) => {
|
||||
weights.nodeTypeWeights.set(prefix, weight);
|
||||
return {weights};
|
||||
});
|
||||
}}
|
||||
onEdgeWeightChange={(prefix, weight) => {
|
||||
this.setState(({weights}) => {
|
||||
weights.edgeTypeWeights.set(prefix, weight);
|
||||
return {weights};
|
||||
});
|
||||
}}
|
||||
/>
|
||||
);
|
||||
const weightFileManager = (
|
||||
<WeightsFileManager
|
||||
weights={this.state.weights}
|
||||
@ -113,6 +93,26 @@ export function createApp(
|
||||
);
|
||||
let pagerankTable;
|
||||
if (appState.type === "PAGERANK_EVALUATED") {
|
||||
const declarations = appState.timelineCred.plugins();
|
||||
const weightConfig = (
|
||||
<WeightConfig
|
||||
declarations={declarations}
|
||||
nodeTypeWeights={this.state.weights.nodeTypeWeights}
|
||||
edgeTypeWeights={this.state.weights.edgeTypeWeights}
|
||||
onNodeWeightChange={(prefix, weight) => {
|
||||
this.setState(({weights}) => {
|
||||
weights.nodeTypeWeights.set(prefix, weight);
|
||||
return {weights};
|
||||
});
|
||||
}}
|
||||
onEdgeWeightChange={(prefix, weight) => {
|
||||
this.setState(({weights}) => {
|
||||
weights.edgeTypeWeights.set(prefix, weight);
|
||||
return {weights};
|
||||
});
|
||||
}}
|
||||
/>
|
||||
);
|
||||
const pnd = appState.pagerankNodeDecomposition;
|
||||
pagerankTable = (
|
||||
<PagerankTable
|
||||
@ -120,7 +120,7 @@ export function createApp(
|
||||
weightConfig={weightConfig}
|
||||
weightFileManager={weightFileManager}
|
||||
manualWeights={this.state.weights.nodeManualWeights}
|
||||
declarations={[githubDeclaration]}
|
||||
declarations={declarations}
|
||||
graph={appState.timelineCred.graph()}
|
||||
onManualWeightsChange={(addr: NodeAddressT, weight: number) =>
|
||||
this.setState(({weights}) => {
|
||||
@ -159,10 +159,6 @@ export function createApp(
|
||||
this.stateTransitionMachine.loadTimelineCredAndRunPagerank(
|
||||
this.props.assets,
|
||||
this.state.weights,
|
||||
{
|
||||
nodeTypes: githubDeclaration.nodeTypes.slice(),
|
||||
edgeTypes: githubDeclaration.edgeTypes.slice(),
|
||||
},
|
||||
GithubPrefix.user
|
||||
)
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import deepEqual from "lodash.isequal";
|
||||
import {Graph, type NodeAddressT} from "../../core/graph";
|
||||
import type {Assets} from "../../webutil/assets";
|
||||
import {type EdgeEvaluator} from "../../analysis/pagerank";
|
||||
import type {NodeAndEdgeTypes} from "../../analysis/types";
|
||||
import {defaultLoader} from "../TimelineApp";
|
||||
import {
|
||||
type PagerankNodeDecomposition,
|
||||
@ -16,6 +15,7 @@ import {TimelineCred} from "../../analysis/timeline/timelineCred";
|
||||
|
||||
import type {Weights} from "../../analysis/weights";
|
||||
import {weightsToEdgeEvaluator} from "../../analysis/weightsToEdgeEvaluator";
|
||||
import {combineTypes} from "../../analysis/pluginDeclaration";
|
||||
|
||||
/*
|
||||
This models the UI states of the credExplorer/App as a state machine.
|
||||
@ -69,11 +69,10 @@ export function createStateTransitionMachine(
|
||||
// Exported for testing purposes.
|
||||
export interface StateTransitionMachineInterface {
|
||||
+loadTimelineCred: (Assets) => Promise<boolean>;
|
||||
+runPagerank: (Weights, NodeAndEdgeTypes, NodeAddressT) => Promise<void>;
|
||||
+runPagerank: (Weights, NodeAddressT) => Promise<void>;
|
||||
+loadTimelineCredAndRunPagerank: (
|
||||
Assets,
|
||||
Weights,
|
||||
NodeAndEdgeTypes,
|
||||
NodeAddressT
|
||||
) => Promise<void>;
|
||||
}
|
||||
@ -144,11 +143,7 @@ export class StateTransitionMachine implements StateTransitionMachineInterface {
|
||||
return false;
|
||||
}
|
||||
|
||||
async runPagerank(
|
||||
weights: Weights,
|
||||
types: NodeAndEdgeTypes,
|
||||
totalScoreNodePrefix: NodeAddressT
|
||||
) {
|
||||
async runPagerank(weights: Weights, totalScoreNodePrefix: NodeAddressT) {
|
||||
const state = this.getState();
|
||||
if (
|
||||
state.type !== "READY_TO_RUN_PAGERANK" &&
|
||||
@ -164,6 +159,7 @@ export class StateTransitionMachine implements StateTransitionMachineInterface {
|
||||
this.setState(loadingState);
|
||||
const graph = state.timelineCred.graph();
|
||||
let newState: ?AppState;
|
||||
const types = combineTypes(state.timelineCred.plugins());
|
||||
try {
|
||||
const pagerankNodeDecomposition = await this.pagerank(
|
||||
graph,
|
||||
@ -196,7 +192,6 @@ export class StateTransitionMachine implements StateTransitionMachineInterface {
|
||||
async loadTimelineCredAndRunPagerank(
|
||||
assets: Assets,
|
||||
weights: Weights,
|
||||
types: NodeAndEdgeTypes,
|
||||
totalScoreNodePrefix: NodeAddressT
|
||||
) {
|
||||
const state = this.getState();
|
||||
@ -205,12 +200,12 @@ export class StateTransitionMachine implements StateTransitionMachineInterface {
|
||||
case "READY_TO_LOAD_GRAPH":
|
||||
const loadedTimelineCred = await this.loadTimelineCred(assets);
|
||||
if (loadedTimelineCred) {
|
||||
await this.runPagerank(weights, types, totalScoreNodePrefix);
|
||||
await this.runPagerank(weights, totalScoreNodePrefix);
|
||||
}
|
||||
break;
|
||||
case "READY_TO_RUN_PAGERANK":
|
||||
case "PAGERANK_EVALUATED":
|
||||
await this.runPagerank(weights, types, totalScoreNodePrefix);
|
||||
await this.runPagerank(weights, totalScoreNodePrefix);
|
||||
break;
|
||||
default:
|
||||
throw new Error((type: empty));
|
||||
|
@ -76,9 +76,6 @@ describe("explorer/legacy/state", () => {
|
||||
function pagerankNodeDecomposition() {
|
||||
return new Map();
|
||||
}
|
||||
function defaultTypes() {
|
||||
return {nodeTypes: [], edgeTypes: []};
|
||||
}
|
||||
function loading(state: AppState) {
|
||||
return state.loading;
|
||||
}
|
||||
@ -150,7 +147,7 @@ describe("explorer/legacy/state", () => {
|
||||
const badState = readyToLoadGraph();
|
||||
const {stm} = example(badState);
|
||||
await expect(
|
||||
stm.runPagerank(defaultWeights(), defaultTypes(), NodeAddress.empty)
|
||||
stm.runPagerank(defaultWeights(), NodeAddress.empty)
|
||||
).rejects.toThrow("incorrect state");
|
||||
});
|
||||
it("can be run when READY_TO_RUN_PAGERANK or PAGERANK_EVALUATED", async () => {
|
||||
@ -159,11 +156,7 @@ describe("explorer/legacy/state", () => {
|
||||
const {stm, getState, pagerankMock} = example(g);
|
||||
const pnd = pagerankNodeDecomposition();
|
||||
pagerankMock.mockReturnValue(Promise.resolve(pnd));
|
||||
await stm.runPagerank(
|
||||
defaultWeights(),
|
||||
defaultTypes(),
|
||||
NodeAddress.empty
|
||||
);
|
||||
await stm.runPagerank(defaultWeights(), NodeAddress.empty);
|
||||
const state = getState();
|
||||
if (state.type !== "PAGERANK_EVALUATED") {
|
||||
throw new Error("Impossible");
|
||||
@ -175,13 +168,13 @@ describe("explorer/legacy/state", () => {
|
||||
it("immediately sets loading status", () => {
|
||||
const {getState, stm} = example(readyToRunPagerank());
|
||||
expect(loading(getState())).toBe("NOT_LOADING");
|
||||
stm.runPagerank(defaultWeights(), defaultTypes(), NodeAddress.empty);
|
||||
stm.runPagerank(defaultWeights(), NodeAddress.empty);
|
||||
expect(loading(getState())).toBe("LOADING");
|
||||
});
|
||||
it("calls pagerank with the totalScoreNodePrefix option", async () => {
|
||||
const {pagerankMock, stm} = example(readyToRunPagerank());
|
||||
const foo = NodeAddress.fromParts(["foo"]);
|
||||
await stm.runPagerank(defaultWeights(), defaultTypes(), foo);
|
||||
await stm.runPagerank(defaultWeights(), foo);
|
||||
const args = pagerankMock.mock.calls[0];
|
||||
expect(args[2].totalScoreNodePrefix).toBe(foo);
|
||||
});
|
||||
@ -191,11 +184,7 @@ describe("explorer/legacy/state", () => {
|
||||
// $ExpectFlowError
|
||||
console.error = jest.fn();
|
||||
pagerankMock.mockReturnValue(Promise.reject(error));
|
||||
await stm.runPagerank(
|
||||
defaultWeights(),
|
||||
defaultTypes(),
|
||||
NodeAddress.empty
|
||||
);
|
||||
await stm.runPagerank(defaultWeights(), NodeAddress.empty);
|
||||
const state = getState();
|
||||
expect(loading(state)).toBe("FAILED");
|
||||
expect(state.type).toBe("READY_TO_RUN_PAGERANK");
|
||||
@ -212,13 +201,12 @@ describe("explorer/legacy/state", () => {
|
||||
stm.loadTimelineCred.mockResolvedValue(true);
|
||||
const assets = new Assets("/gateway/");
|
||||
const prefix = NodeAddress.fromParts(["bar"]);
|
||||
const types = defaultTypes();
|
||||
const wt = defaultWeights();
|
||||
await stm.loadTimelineCredAndRunPagerank(assets, wt, types, prefix);
|
||||
await stm.loadTimelineCredAndRunPagerank(assets, wt, prefix);
|
||||
expect(stm.loadTimelineCred).toHaveBeenCalledTimes(1);
|
||||
expect(stm.loadTimelineCred).toHaveBeenCalledWith(assets);
|
||||
expect(stm.runPagerank).toHaveBeenCalledTimes(1);
|
||||
expect(stm.runPagerank).toHaveBeenCalledWith(wt, types, prefix);
|
||||
expect(stm.runPagerank).toHaveBeenCalledWith(wt, prefix);
|
||||
});
|
||||
it("does not run pagerank if loadTimelineCred did not succeed", async () => {
|
||||
const {stm} = example(readyToLoadGraph());
|
||||
@ -230,7 +218,6 @@ describe("explorer/legacy/state", () => {
|
||||
await stm.loadTimelineCredAndRunPagerank(
|
||||
assets,
|
||||
defaultWeights(),
|
||||
defaultTypes(),
|
||||
prefix
|
||||
);
|
||||
expect(stm.loadTimelineCred).toHaveBeenCalledTimes(1);
|
||||
@ -242,16 +229,14 @@ describe("explorer/legacy/state", () => {
|
||||
(stm: any).runPagerank = jest.fn();
|
||||
const prefix = NodeAddress.fromParts(["bar"]);
|
||||
const wt = defaultWeights();
|
||||
const types = defaultTypes();
|
||||
await stm.loadTimelineCredAndRunPagerank(
|
||||
new Assets("/gateway/"),
|
||||
wt,
|
||||
types,
|
||||
prefix
|
||||
);
|
||||
expect(stm.loadTimelineCred).toHaveBeenCalledTimes(0);
|
||||
expect(stm.runPagerank).toHaveBeenCalledTimes(1);
|
||||
expect(stm.runPagerank).toHaveBeenCalledWith(wt, types, prefix);
|
||||
expect(stm.runPagerank).toHaveBeenCalledWith(wt, prefix);
|
||||
});
|
||||
it("when PAGERANK_EVALUATED, runs pagerank", async () => {
|
||||
const {stm} = example(pagerankEvaluated());
|
||||
@ -259,16 +244,14 @@ describe("explorer/legacy/state", () => {
|
||||
(stm: any).runPagerank = jest.fn();
|
||||
const prefix = NodeAddress.fromParts(["bar"]);
|
||||
const wt = defaultWeights();
|
||||
const types = defaultTypes();
|
||||
await stm.loadTimelineCredAndRunPagerank(
|
||||
new Assets("/gateway/"),
|
||||
wt,
|
||||
types,
|
||||
prefix
|
||||
);
|
||||
expect(stm.loadTimelineCred).toHaveBeenCalledTimes(0);
|
||||
expect(stm.runPagerank).toHaveBeenCalledTimes(1);
|
||||
expect(stm.runPagerank).toHaveBeenCalledWith(wt, types, prefix);
|
||||
expect(stm.runPagerank).toHaveBeenCalledWith(wt, prefix);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user