diff --git a/src/app/credExplorer/WeightConfig.js b/src/app/credExplorer/WeightConfig.js index 08e19f6..87afab5 100644 --- a/src/app/credExplorer/WeightConfig.js +++ b/src/app/credExplorer/WeightConfig.js @@ -6,9 +6,14 @@ import sortBy from "lodash.sortby"; import {type EdgeEvaluator} from "../../core/attribution/pagerank"; import {byEdgeType, byNodeType} from "./edgeWeights"; import {defaultStaticAdapters} from "../adapters/defaultPlugins"; -import type {NodeType, EdgeType} from "../adapters/pluginAdapter"; +import type {EdgeType} from "../adapters/pluginAdapter"; import {WeightSlider} from "./weights/WeightSlider"; import {DirectionalitySlider} from "./weights/DirectionalitySlider"; +import { + NodeTypeConfig, + defaultWeightedNodeType, + type WeightedNodeType, +} from "./weights/NodeTypeConfig"; type Props = {| +onChange: (EdgeEvaluator) => void, @@ -28,19 +33,9 @@ const defaultEdgeWeights = (): EdgeWeights => { return result; }; -type NodeWeights = WeightedNodeType[]; -type WeightedNodeType = {|+type: NodeType, +weight: number|}; -const defaultNodeWeights = (): NodeWeights => { - const result = []; - for (const type of defaultStaticAdapters().nodeTypes()) { - result.push({type, weight: type.defaultWeight}); - } - return result; -}; - type State = { edgeWeights: EdgeWeights, - nodeWeights: NodeWeights, + nodeWeights: $ReadOnlyArray, expanded: boolean, }; @@ -49,7 +44,9 @@ export class WeightConfig extends React.Component { super(props); this.state = { edgeWeights: defaultEdgeWeights(), - nodeWeights: defaultNodeWeights(), + nodeWeights: defaultStaticAdapters() + .nodeTypes() + .map(defaultWeightedNodeType), expanded: false, }; } @@ -175,36 +172,30 @@ class EdgeConfig extends React.Component<{ } class NodeConfig extends React.Component<{ - nodeWeights: NodeWeights, - onChange: (NodeWeights) => void, + nodeWeights: $ReadOnlyArray, + onChange: ($ReadOnlyArray) => void, }> { - render() { - const sortedWeights = sortBy( - this.props.nodeWeights, - ({type}) => type.prefix - ); - - const controls = sortedWeights.map(({type, weight}) => { - const onChange = (value) => { - const nodeWeights = this.props.nodeWeights.filter( - (x) => x.type.prefix !== type.prefix + _renderControls() { + return sortBy(this.props.nodeWeights, ({type}) => type.prefix).map( + (weightedType) => { + const onChange = (newType) => { + const nodeWeights = this.props.nodeWeights.filter( + (x) => x.type.prefix !== weightedType.type.prefix + ); + nodeWeights.push(newType); + this.props.onChange(nodeWeights); + }; + return ( + ); - nodeWeights.push({type, weight: value}); - this.props.onChange(nodeWeights); - }; - return ( - - ); - }); + } + ); + } + render() { return (

Node weights

- {controls} + {this._renderControls()}
); } diff --git a/src/app/credExplorer/weights/NodeTypeConfig.js b/src/app/credExplorer/weights/NodeTypeConfig.js new file mode 100644 index 0000000..f22dcff --- /dev/null +++ b/src/app/credExplorer/weights/NodeTypeConfig.js @@ -0,0 +1,34 @@ +// @flow + +import React from "react"; +import {WeightSlider} from "./WeightSlider"; +import {type NodeType} from "../../adapters/pluginAdapter"; + +export type WeightedNodeType = {|+type: NodeType, +weight: number|}; + +export function defaultWeightedNodeType(type: NodeType): WeightedNodeType { + return { + type, + weight: type.defaultWeight, + }; +} + +export class NodeTypeConfig extends React.Component<{ + +weightedType: WeightedNodeType, + +onChange: (WeightedNodeType) => void, +}> { + render() { + return ( + { + this.props.onChange({ + ...this.props.weightedType, + weight, + }); + }} + /> + ); + } +} diff --git a/src/app/credExplorer/weights/NodeTypeConfig.test.js b/src/app/credExplorer/weights/NodeTypeConfig.test.js new file mode 100644 index 0000000..c1c33e5 --- /dev/null +++ b/src/app/credExplorer/weights/NodeTypeConfig.test.js @@ -0,0 +1,45 @@ +// @flow + +import React from "react"; +import {shallow} from "enzyme"; + +import {WeightSlider} from "./WeightSlider"; +import {defaultWeightedNodeType, NodeTypeConfig} from "./NodeTypeConfig"; +import {inserterNodeType} from "../../adapters/demoAdapters"; + +require("../../testUtil").configureEnzyme(); + +describe("app/credExplorer/weights/NodeTypeConfig", () => { + describe("defaultWeightedNodeType", () => { + it("sets default weight as specified in type", () => { + const wnt = defaultWeightedNodeType(inserterNodeType); + expect(wnt.weight).toEqual(wnt.type.defaultWeight); + }); + }); + describe("NodeTypeConfig", () => { + function example() { + const onChange = jest.fn(); + const wnt = { + type: inserterNodeType, + weight: 0.125, + }; + const element = shallow( + + ); + const slider = element.find(WeightSlider); + return {onChange, wnt, slider}; + } + it("sets up the weight slider", () => { + const {wnt, slider} = example(); + expect(slider.props().name).toBe(wnt.type.name); + expect(slider.props().weight).toBe(wnt.weight); + }); + it("weight slider onChange works", () => { + const {wnt, slider, onChange} = example(); + slider.props().onChange(9); + const updated = {...wnt, weight: 9}; + expect(onChange).toHaveBeenCalledTimes(1); + expect(onChange.mock.calls[0][0]).toEqual(updated); + }); + }); +});