Skip to content

Commit 36a9fe7

Browse files
authored
Merge pull request #4 from bcdev/forman-no_local_ui_state
Avoid local state in Widgets
2 parents e558ea4 + 3bb3586 commit 36a9fe7

File tree

5 files changed

+64
-43
lines changed

5 files changed

+64
-43
lines changed

dashi/src/actions/handleComponentPropertyChange.ts

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,9 @@ import {
55
isContainerModel,
66
PropertyChangeEvent,
77
} from "../model/component";
8-
import {
9-
CallbackCallRequest,
10-
CallbackCallResult,
11-
ComputedOutput,
12-
} from "../model/callback";
8+
import { CallbackCallRequest, ChangeRequest, Change } from "../model/callback";
139
import fetchApiResult from "../utils/fetchApiResult";
14-
import { fetchCallbackCallResults } from "../api";
10+
import { fetchChangeRequests } from "../api";
1511
import { updateArray } from "../utils/updateArray";
1612

1713
export default function handleComponentPropertyChange(
@@ -27,6 +23,8 @@ export default function handleComponentPropertyChange(
2723
const componentPropertyValue = contribEvent.propertyValue;
2824
const contributionModel = contributionModels[contribIndex];
2925
const callRequests: CallbackCallRequest[] = [];
26+
// Prepare calling all callbacks of the contribution
27+
// that are triggered by the property change
3028
(contributionModel.callbacks || []).forEach((callback, callbackIndex) => {
3129
if (callback.inputs && callback.inputs.length > 0) {
3230
let triggerIndex: number = -1;
@@ -38,11 +36,12 @@ export default function handleComponentPropertyChange(
3836
input.id === componentId &&
3937
input.property === componentPropertyName
4038
) {
39+
// Ok - the current callback is triggered by the property change
4140
triggerIndex = inputIndex;
4241
return componentPropertyValue;
4342
} else {
4443
// TODO: get inputValue from other component with given id/property.
45-
// For time being we use null as it is JSON-serializable
44+
// For time being we use null as it is JSON-serializable
4645
}
4746
} else {
4847
// TODO: get inputValue from other kinds.
@@ -62,44 +61,64 @@ export default function handleComponentPropertyChange(
6261
}
6362
}
6463
});
64+
const originalChangeRequest: ChangeRequest = {
65+
contribPoint,
66+
contribIndex,
67+
changes: [
68+
{
69+
kind: "Component",
70+
id: componentId,
71+
property: componentPropertyName,
72+
value: componentPropertyValue,
73+
},
74+
],
75+
};
6576
console.debug("callRequests", callRequests);
66-
if (callRequests.length) {
67-
fetchApiResult(fetchCallbackCallResults, callRequests).then(
68-
(callResultResult) => {
69-
if (callResultResult.data) {
70-
applyCallbackCallResults(callResultResult.data);
77+
if (callRequests.length == 0) {
78+
applyChangeRequests([originalChangeRequest]);
79+
} else {
80+
fetchApiResult(fetchChangeRequests, callRequests).then(
81+
(changeRequestsResult) => {
82+
if (changeRequestsResult.data) {
83+
applyChangeRequests(
84+
[originalChangeRequest].concat(changeRequestsResult.data),
85+
);
7186
} else {
72-
console.error("callback failed:", callResultResult.error);
73-
console.error(" for requests:", callRequests);
87+
console.error(
88+
"callback failed:",
89+
changeRequestsResult.error,
90+
"for call requests:",
91+
callRequests,
92+
);
7493
}
7594
},
7695
);
7796
}
7897
}
7998

80-
function applyCallbackCallResults(callResults: CallbackCallResult[]) {
81-
console.log("processing call results", callResults);
82-
callResults.forEach(({ contribPoint, contribIndex, computedOutputs }) => {
99+
function applyChangeRequests(changeRequests: ChangeRequest[]) {
100+
console.log("applying change requests", changeRequests);
101+
changeRequests.forEach(({ contribPoint, contribIndex, changes }) => {
83102
console.log(
84-
"processing output of",
103+
"processing change request",
85104
contribPoint,
86105
contribIndex,
87-
computedOutputs,
106+
changes,
88107
);
89108
const contributionStatesRecord =
90109
appStore.getState().contributionStatesRecord;
91110
const contributionStates = contributionStatesRecord[contribPoint];
92111
const contributionState = contributionStates[contribIndex];
93112
const componentModelOld = contributionState.componentModelResult.data;
94113
let componentModel = componentModelOld;
95-
computedOutputs.forEach((output) => {
96-
if (componentModel && (!output.kind || output.kind === "Component")) {
97-
componentModel = updateComponentState(componentModel, output);
114+
changes.forEach((change) => {
115+
if (componentModel && (!change.kind || change.kind === "Component")) {
116+
componentModel = updateComponentState(componentModel, change);
98117
} else {
99118
// TODO: process other output kinds which may not require componentModel.
100119
console.warn(
101120
"processing of this kind of output not supported yet:",
102-
output,
121+
change,
103122
);
104123
}
105124
});
@@ -126,16 +145,16 @@ function applyCallbackCallResults(callResults: CallbackCallResult[]) {
126145

127146
function updateComponentState(
128147
componentModel: ComponentModel,
129-
output: ComputedOutput,
148+
change: Change,
130149
): ComponentModel {
131-
if (componentModel.id === output.id) {
132-
return { ...componentModel, [output.property]: output.value };
150+
if (componentModel.id === change.id) {
151+
return { ...componentModel, [change.property]: change.value };
133152
} else if (isContainerModel(componentModel)) {
134153
const containerModelOld: ContainerModel = componentModel;
135154
let containerModelNew: ContainerModel = containerModelOld;
136155
for (let i = 0; i < containerModelOld.components.length; i++) {
137156
const itemOld = containerModelOld.components[i];
138-
const itemNew = updateComponentState(itemOld, output);
157+
const itemNew = updateComponentState(itemOld, change);
139158
if (itemNew !== itemOld) {
140159
if (containerModelNew === containerModelOld) {
141160
containerModelNew = {

dashi/src/api.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ComponentModel } from "./model/component";
22
import { Extension } from "./model/extension";
33
import { Contribution } from "./model/contribution";
4-
import { CallbackCallRequest, CallbackCallResult } from "./model/callback";
4+
import { CallbackCallRequest, ChangeRequest } from "./model/callback";
55
import { callApi } from "./utils/fetchApiResult";
66
import { ContribPoint } from "./store/appStore";
77

@@ -28,9 +28,9 @@ export async function fetchComponentModel(
2828
});
2929
}
3030

31-
export async function fetchCallbackCallResults(
31+
export async function fetchChangeRequests(
3232
callRequests: CallbackCallRequest[],
33-
): Promise<CallbackCallResult[]> {
33+
): Promise<ChangeRequest[]> {
3434
return callApi(`${serverUrl}/dashi/callback`, {
3535
body: JSON.stringify({ callRequests }),
3636
method: "post",

dashi/src/components/DashiDropdown.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import "react";
22
import { DropdownModel, PropertyChangeHandler } from "../model/component";
3-
import React from "react";
43
import {
54
// Box,
65
FormControl,
@@ -24,7 +23,6 @@ function DashiDropdown({
2423
label,
2524
onPropertyChange,
2625
}: DashiDropdownProps) {
27-
const [dropdownValue, setDropdownValue] = React.useState(value);
2826
const handleChange = (event: SelectChangeEvent) => {
2927
if (!id) {
3028
return;
@@ -34,7 +32,6 @@ function DashiDropdown({
3432
newValue = Number.parseInt(newValue);
3533
}
3634

37-
setDropdownValue(newValue);
3835
return onPropertyChange({
3936
componentType: "Dropdown",
4037
componentId: id,
@@ -49,7 +46,7 @@ function DashiDropdown({
4946
labelId={`${id}-label`}
5047
id={id}
5148
name={name}
52-
value={`${dropdownValue}`}
49+
value={`${value}`}
5350
disabled={disabled}
5451
onChange={handleChange}
5552
>

dashi/src/model/callback.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,23 @@ export interface Input extends InputOutput {}
1717
export interface Output extends InputOutput {}
1818

1919
export interface CallbackCallRequest {
20+
// The contribution that requests the callback call
2021
contribPoint: string;
2122
contribIndex: number;
23+
// The callback of the contribution
2224
callbackIndex: number;
25+
// The input values for the callback
2326
inputValues: unknown[];
2427
}
2528

26-
export interface CallbackCallResult {
29+
export interface ChangeRequest {
30+
// The contribution that requests the changes
2731
contribPoint: string;
2832
contribIndex: number;
29-
computedOutputs: ComputedOutput[];
33+
// The changes requested by the contribution
34+
changes: Change[];
3035
}
3136

32-
export interface ComputedOutput extends Output {
37+
export interface Change extends Output {
3338
value: unknown;
3439
}

dashipy/dashipy/server.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ def post(self):
135135
context: Context = self.settings[DASHI_CONTEXT_KEY]
136136

137137
# TODO: assert correctness, set status code on error
138-
call_results: list[dict] = []
138+
change_requests: list[dict] = []
139139
for call_request in call_requests:
140140
contrib_point_name: str = call_request["contribPoint"]
141141
contrib_index: int = call_request["contribIndex"]
@@ -151,10 +151,10 @@ def post(self):
151151
if len(callback.outputs) == 1:
152152
output_values = (output_values,)
153153

154-
computed_outputs: list[dict] = []
154+
changes: list[dict] = []
155155
for output_index, output in enumerate(callback.outputs):
156156
output_value = output_values[output_index]
157-
computed_outputs.append(
157+
changes.append(
158158
{
159159
**output.to_dict(),
160160
"value": (
@@ -167,16 +167,16 @@ def post(self):
167167
}
168168
)
169169

170-
call_results.append(
170+
change_requests.append(
171171
{
172172
"contribPoint": contrib_point_name,
173173
"contribIndex": contrib_index,
174-
"computedOutputs": computed_outputs,
174+
"changes": changes,
175175
}
176176
)
177177

178178
self.set_header("Content-Type", "text/json")
179-
self.write({"result": call_results})
179+
self.write({"result": change_requests})
180180

181181

182182
def print_usage(app, port):

0 commit comments

Comments
 (0)