Skip to content

Commit 44cbee3

Browse files
authored
Merge pull request #2758 from BSd3v/expose-setprops
Expose setprops
2 parents a7daa0d + 46c6d2b commit 44cbee3

File tree

8 files changed

+103
-2
lines changed

8 files changed

+103
-2
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@ This project adheres to [Semantic Versioning](https://semver.org/).
77
## Fixed
88

99
- [#2756](https://github.com/plotly/dash/pull/2756) Prevent false dangerous link warning. Fixes [#2743](https://github.com/plotly/dash/issues/2743)
10+
- [#2752](https://github.com/plotly/dash/pull/2752) Fixed issue with Windows build, for first time build on Windows, the dev needs to use `npm run first-build`
1011

1112
## Changed
1213

1314
- [#2734](https://github.com/plotly/dash/pull/2734) Configure CI for Python 3.10 [#1863](https://github.com/plotly/dash/issues/1863)
1415
- [#2735](https://github.com/plotly/dash/pull/2735) Configure CI for Python 3.8 and 3.12, drop support for Python 3.6 and Python 3.7 [#2736](https://github.com/plotly/dash/issues/2736)
1516

1617
## Added
18+
- [#2758](https://github.com/plotly/dash/pull/2758)
19+
- exposing `setProps` to `dash_clientside.clientSide_setProps` to allow for JS code to interact directly with the dash eco-system
1720
- [#2730](https://github.com/plotly/dash/pull/2721) Load script files with `.mjs` ending as js modules
1821

1922
## [2.15.0] - 2024-01-31

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ $ npm ci
2323
#
2424
$ npm run build # runs `renderer build` and `npm build` in dcc, html, table
2525
# build and install components used in tests
26+
# on windows, the developer will need to use `npm run first-build` this performs additional first steps
2627
#
2728
# Alternatively one could run part of the build process e.g.
2829
$ dash-update-components "dash-core-components"

dash/dash-renderer/renderer-test.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/bash
2+
file=./build/dash_renderer.min.js
3+
if [ ! -f "$file" ]; then
4+
echo "dash-renderer did not build correctly"
5+
exit 1
6+
fi

dash/dash-renderer/src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {DashRenderer} from './DashRenderer';
2+
import './utils/clientsideFunctions';
23

34
// make DashRenderer globally available
45
window.DashRenderer = DashRenderer;

dash/dash-renderer/src/store.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ export default class RendererStore {
5656
private createAppStore = (reducer: any, middleware: any) => {
5757
this.__store = createStore(reducer, middleware);
5858
this.storeObserver.setStore(this.__store);
59+
const ds = ((window as any).dash_stores =
60+
(window as any).dash_stores || []);
61+
if (!ds.includes(this.__store)) {
62+
ds.push(this.__store);
63+
}
5964
this.setObservers();
6065
};
6166

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import {updateProps, notifyObservers} from '../actions/index';
2+
import {getPath} from '../actions/paths';
3+
4+
const set_props = (id: string | object, props: {[k: string]: any}) => {
5+
const ds = ((window as any).dash_stores =
6+
(window as any).dash_stores || []);
7+
for (let y = 0; y < ds.length; y++) {
8+
const {dispatch, getState} = ds[y];
9+
const {paths} = getState();
10+
const componentPath = getPath(paths, id);
11+
dispatch(
12+
updateProps({
13+
props,
14+
itempath: componentPath
15+
})
16+
);
17+
dispatch(notifyObservers({id, props}));
18+
}
19+
};
20+
21+
const dc = ((window as any).dash_clientside =
22+
(window as any).dash_clientside || {});
23+
dc['set_props'] = set_props;

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"private::initialize.renderer": "cd dash/dash-renderer && npm ci",
99
"private::cibuild.components": "python dash/development/update_components.py 'all' --ci True",
1010
"private::build.components": "python dash/development/update_components.py 'all'",
11-
"private::cibuild.renderer": "cd dash/dash-renderer && renderer build",
12-
"private::build.renderer": "cd dash/dash-renderer && renderer build",
11+
"private::cibuild.renderer": "cd dash/dash-renderer && rimraf build/dash_renderer.min.js && renderer build && sh renderer-test.sh",
12+
"private::build.renderer": "cd dash/dash-renderer && rimraf build/dash_renderer.min.js && renderer build && sh renderer-test.sh",
1313
"private::build.jupyterlab": "cd @plotly/dash-jupyterlab && jlpm install && jlpm build:pack",
1414
"private::lint.black": "black dash tests --exclude metadata_test.py --check",
1515
"private::lint.flake8": "flake8 --exclude=metadata_test.py dash tests",
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
from dash import Dash, html, Input, Output, no_update, State
2+
import json
3+
from multiprocessing import Value
4+
5+
6+
def test_sp001_clientside_setprops(dash_duo):
7+
8+
call_count = Value("i", 0)
9+
10+
app = Dash(__name__)
11+
12+
ids = [
13+
{"id": {"index": "1", "type": "test"}, "children": ["rawr"]},
14+
{"id": "two", "children": "this is a test"},
15+
{"id": "three", "children": "i see trees of green"},
16+
]
17+
18+
app.layout = html.Div(
19+
[
20+
*[html.Div(id=x["id"]) for x in ids],
21+
html.Div(id="four"),
22+
html.Button(id="setup", children="test setprops"),
23+
]
24+
)
25+
26+
app.clientside_callback(
27+
"""
28+
() => {
29+
"""
30+
+ json.dumps(ids)
31+
+ """.forEach(({id, ...props}) => window.dash_clientside.set_props(id, props))
32+
return window.dash_clientside.no_update
33+
}
34+
""",
35+
Output("setup", "id"),
36+
Input("setup", "n_clicks"),
37+
prevent_initial_call=True,
38+
)
39+
40+
for x in ids:
41+
42+
@app.callback(
43+
Output(x["id"], "id", allow_duplicate=True),
44+
Output("four", "children", allow_duplicate=True),
45+
Input(x["id"], "children"),
46+
State(x["id"], "id"),
47+
prevent_initial_call=True,
48+
)
49+
def prinout(c, id):
50+
call_count.value += 1
51+
for y in ids:
52+
if y["id"] == id:
53+
assert y["children"] == c
54+
return no_update, call_count.value
55+
56+
dash_duo.start_server(app)
57+
58+
dash_duo.wait_for_text_to_equal("#setup", "test setprops")
59+
dash_duo.find_element("#setup").click()
60+
dash_duo.wait_for_text_to_equal("#two", "this is a test")
61+
dash_duo.wait_for_text_to_equal("#three", "i see trees of green")
62+
dash_duo.wait_for_text_to_equal("#four", "3")

0 commit comments

Comments
 (0)