Skip to content

Commit fcf62a6

Browse files
committed
accessing nested state properties
1 parent 402bd45 commit fcf62a6

File tree

2 files changed

+62
-26
lines changed

2 files changed

+62
-26
lines changed

dashi/src/lib/actions/helpers/getInputValues.test.ts

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,39 +26,51 @@ const componentState: ComponentState = {
2626
describe("Test that getInputValueFromComponent()", () => {
2727
it("works on 1st level", () => {
2828
expect(
29-
getInputValueFromComponent(componentState, {
30-
link: "component",
31-
id: "b1",
32-
property: "value",
33-
}),
29+
getInputValueFromComponent(
30+
{
31+
link: "component",
32+
id: "b1",
33+
property: "value",
34+
},
35+
componentState,
36+
),
3437
).toEqual(14);
3538
});
3639

3740
it("works on 2nd level", () => {
3841
expect(
39-
getInputValueFromComponent(componentState, {
40-
link: "component",
41-
id: "p1",
42-
property: "chart",
43-
}),
42+
getInputValueFromComponent(
43+
{
44+
link: "component",
45+
id: "p1",
46+
property: "chart",
47+
},
48+
componentState,
49+
),
4450
).toEqual(null);
4551
});
4652

4753
it("works on 3rd level", () => {
4854
expect(
49-
getInputValueFromComponent(componentState, {
50-
link: "component",
51-
id: "cb1",
52-
property: "value",
53-
}),
55+
getInputValueFromComponent(
56+
{
57+
link: "component",
58+
id: "cb1",
59+
property: "value",
60+
},
61+
componentState,
62+
),
5463
).toEqual(true);
5564

5665
expect(
57-
getInputValueFromComponent(componentState, {
58-
link: "component",
59-
id: "dd1",
60-
property: "value",
61-
}),
66+
getInputValueFromComponent(
67+
{
68+
link: "component",
69+
id: "dd1",
70+
property: "value",
71+
},
72+
componentState,
73+
),
6274
).toEqual(13);
6375
});
6476
});
@@ -90,4 +102,18 @@ describe("Test that getInputValueFromState()", () => {
90102
getInputValueFromState({ link: "container", property: "x" }, state),
91103
).toEqual([4, 5, 6]);
92104
});
105+
106+
it("works on 2nd level", () => {
107+
const state = { x: { y: 15 } };
108+
expect(
109+
getInputValueFromState({ link: "container", property: "x.y" }, state),
110+
).toEqual(15);
111+
});
112+
113+
it("works on 3nd level", () => {
114+
const state = { x: { y: [4, 5, 6] } };
115+
expect(
116+
getInputValueFromState({ link: "container", property: "x.y.2" }, state),
117+
).toEqual(6);
118+
});
93119
});

dashi/src/lib/actions/helpers/getInputValues.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { ContributionState } from "@/lib/types/state/contribution";
33
import type { ComponentState } from "@/lib/types/state/component";
44
import { isSubscriptable } from "@/lib/utils/isSubscriptable";
55
import { isContainerState } from "@/lib/actions/helpers/isContainerState";
6+
import { getValue } from "@/lib/utils/getValue";
67

78
export function getInputValues<S extends object = object>(
89
inputs: Input[],
@@ -24,11 +25,11 @@ export function getInputValue<S extends object = object>(
2425
let inputValue: unknown = undefined;
2526
const dataSource = input.link || "component";
2627
if (dataSource === "component" && contributionState.component) {
27-
// Return value of a property of some component in the tree
28-
inputValue = getInputValueFromComponent(contributionState.component, input);
28+
inputValue = getInputValueFromComponent(input, contributionState.component);
2929
} else if (dataSource === "container" && contributionState.container) {
30-
inputValue = getInputValueFromState(input, hostState);
30+
inputValue = getInputValueFromState(input, contributionState.container);
3131
} else if (dataSource === "app" && hostState) {
32+
console.log();
3233
inputValue = getInputValueFromState(input, hostState);
3334
} else {
3435
console.warn(`input with unknown data source:`, input);
@@ -43,8 +44,8 @@ export function getInputValue<S extends object = object>(
4344

4445
// we export for testing only
4546
export function getInputValueFromComponent(
46-
componentState: ComponentState,
4747
input: Input,
48+
componentState: ComponentState,
4849
): unknown {
4950
if (componentState.id === input.id && input.property) {
5051
return (componentState as unknown as Record<string, unknown>)[
@@ -53,7 +54,7 @@ export function getInputValueFromComponent(
5354
} else if (isContainerState(componentState)) {
5455
for (let i = 0; i < componentState.components.length; i++) {
5556
const item = componentState.components[i];
56-
const itemValue = getInputValueFromComponent(item, input);
57+
const itemValue = getInputValueFromComponent(input, item);
5758
if (itemValue !== noValue) {
5859
return itemValue;
5960
}
@@ -72,7 +73,16 @@ export function getInputValueFromState(
7273
inputValue = inputValue[input.id];
7374
}
7475
if (isSubscriptable(inputValue)) {
75-
inputValue = inputValue[input.property];
76+
const property = input.property;
77+
// TODO: The Input.property should be normalized to be a path
78+
// and have type string[].
79+
// See also interface Input in types/model/channel.ts
80+
if (property.includes(".")) {
81+
const path = property.split(".");
82+
inputValue = getValue(inputValue, path);
83+
} else {
84+
inputValue = inputValue[property];
85+
}
7686
}
7787
return inputValue;
7888
}

0 commit comments

Comments
 (0)