ex4nicegui 0.6.2__py3-none-any.whl → 0.6.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ex4nicegui/__init__.py +1 -1
- ex4nicegui/reactive/__init__.py +8 -0
- ex4nicegui/reactive/empty.js +3 -0
- ex4nicegui/reactive/empty.py +6 -0
- ex4nicegui/reactive/officials/base.py +4 -0
- ex4nicegui/reactive/officials/tab.py +57 -0
- ex4nicegui/reactive/officials/tab_panel.py +23 -0
- ex4nicegui/reactive/officials/tab_panels.py +46 -0
- ex4nicegui/reactive/officials/table.py +10 -1
- ex4nicegui/reactive/officials/tabs.py +43 -0
- ex4nicegui/reactive/transitionGroup.js +39 -0
- ex4nicegui/reactive/transitionGroup.py +25 -0
- ex4nicegui/reactive/vfor.js +12 -2
- ex4nicegui/reactive/vfor.py +71 -59
- ex4nicegui/utils/signals.py +6 -4
- {ex4nicegui-0.6.2.dist-info → ex4nicegui-0.6.3.dist-info}/METADATA +2 -2
- {ex4nicegui-0.6.2.dist-info → ex4nicegui-0.6.3.dist-info}/RECORD +20 -12
- {ex4nicegui-0.6.2.dist-info → ex4nicegui-0.6.3.dist-info}/LICENSE +0 -0
- {ex4nicegui-0.6.2.dist-info → ex4nicegui-0.6.3.dist-info}/WHEEL +0 -0
- {ex4nicegui-0.6.2.dist-info → ex4nicegui-0.6.3.dist-info}/top_level.txt +0 -0
ex4nicegui/__init__.py
CHANGED
ex4nicegui/reactive/__init__.py
CHANGED
|
@@ -46,6 +46,10 @@ from .officials.expansion import ExpansionBindableUi as expansion
|
|
|
46
46
|
from .officials.linear_progress import LinearProgressBindableUi as linear_progress
|
|
47
47
|
from .officials.knob import KnobBindableUi as knob
|
|
48
48
|
from .officials.circular_progress import CircularProgressBindableUi as circular_progress
|
|
49
|
+
from .officials.tabs import TabsBindableUi as tabs
|
|
50
|
+
from .officials.tab import TabBindableUi as tab
|
|
51
|
+
from .officials.tab_panels import TabPanelsBindableUi as tab_panels
|
|
52
|
+
from .officials.tab_panel import TabPanelBindableUi as tab_panel
|
|
49
53
|
from .q_pagination import PaginationBindableUi as q_pagination
|
|
50
54
|
|
|
51
55
|
from .local_file_picker import local_file_picker
|
|
@@ -63,6 +67,10 @@ pagination = q_pagination
|
|
|
63
67
|
|
|
64
68
|
|
|
65
69
|
__all__ = [
|
|
70
|
+
"tab_panels",
|
|
71
|
+
"tab_panel",
|
|
72
|
+
"tabs",
|
|
73
|
+
"tab",
|
|
66
74
|
"circular_progress",
|
|
67
75
|
"knob",
|
|
68
76
|
"UploadResult",
|
|
@@ -244,6 +244,10 @@ class BindableUi(Generic[TWidget]):
|
|
|
244
244
|
|
|
245
245
|
return self
|
|
246
246
|
|
|
247
|
+
def update(self):
|
|
248
|
+
"""Update the element on the client side."""
|
|
249
|
+
self.element.update()
|
|
250
|
+
|
|
247
251
|
|
|
248
252
|
# class SingleValueBindableUi(BindableUi[TWidget], Generic[T, TWidget]):
|
|
249
253
|
# def __init__(self, value: TMaybeRef[T], element: TWidget) -> None:
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
from typing import Dict, Optional
|
|
2
|
+
from ex4nicegui.reactive.utils import ParameterClassifier
|
|
3
|
+
from ex4nicegui.utils.signals import (
|
|
4
|
+
to_value,
|
|
5
|
+
_TMaybeRef as TMaybeRef,
|
|
6
|
+
)
|
|
7
|
+
from nicegui import ui
|
|
8
|
+
from .base import BindableUi
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class TabBindableUi(BindableUi[ui.tab]):
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
name: TMaybeRef[str],
|
|
15
|
+
label: Optional[TMaybeRef[str]] = None,
|
|
16
|
+
icon: Optional[TMaybeRef[str]] = None,
|
|
17
|
+
) -> None:
|
|
18
|
+
pc = ParameterClassifier(
|
|
19
|
+
locals(),
|
|
20
|
+
maybeRefs=["name", "label", "icon"],
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
value_kws = pc.get_values_kws()
|
|
24
|
+
element = ui.tab(**value_kws)
|
|
25
|
+
super().__init__(element)
|
|
26
|
+
|
|
27
|
+
bindings_kws = pc.get_bindings()
|
|
28
|
+
self.__bind_label(bindings_kws, value_kws)
|
|
29
|
+
|
|
30
|
+
if "label" in bindings_kws:
|
|
31
|
+
bindings_kws.pop("label")
|
|
32
|
+
|
|
33
|
+
for key, value in bindings_kws.items():
|
|
34
|
+
self.bind_prop(key, value) # type: ignore
|
|
35
|
+
|
|
36
|
+
# def bind_prop(self, prop: str, ref_ui: TMaybeRef):
|
|
37
|
+
# if prop == "name":
|
|
38
|
+
# return self.bind_name(ref_ui)
|
|
39
|
+
|
|
40
|
+
# return super().bind_prop(prop, ref_ui)
|
|
41
|
+
|
|
42
|
+
def __bind_label(self, binding_kws: Dict, value_kws: Dict):
|
|
43
|
+
name_ref = binding_kws.get("name") or value_kws.get("name")
|
|
44
|
+
label_ref = binding_kws.get("label") or value_kws.get("label")
|
|
45
|
+
|
|
46
|
+
@self._ui_effect
|
|
47
|
+
def _():
|
|
48
|
+
self.element._props["label"] = (
|
|
49
|
+
to_value(label_ref) if label_ref is not None else to_value(name_ref)
|
|
50
|
+
)
|
|
51
|
+
self.element.update()
|
|
52
|
+
|
|
53
|
+
# def bind_name(self, ref_ui: TMaybeRef):
|
|
54
|
+
# @self._ui_effect
|
|
55
|
+
# def _():
|
|
56
|
+
# self.element._props["name"] = to_value(ref_ui)
|
|
57
|
+
# self.element.update()
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from ex4nicegui.reactive.utils import ParameterClassifier
|
|
2
|
+
from ex4nicegui.utils.signals import (
|
|
3
|
+
_TMaybeRef as TMaybeRef,
|
|
4
|
+
)
|
|
5
|
+
from nicegui import ui
|
|
6
|
+
from .base import BindableUi
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TabPanelBindableUi(BindableUi[ui.tab_panel]):
|
|
10
|
+
def __init__(
|
|
11
|
+
self,
|
|
12
|
+
name: TMaybeRef[str],
|
|
13
|
+
) -> None:
|
|
14
|
+
pc = ParameterClassifier(
|
|
15
|
+
locals(),
|
|
16
|
+
maybeRefs=["name"],
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
element = ui.tab_panel(**pc.get_values_kws())
|
|
20
|
+
super().__init__(element)
|
|
21
|
+
|
|
22
|
+
for key, value in pc.get_bindings().items():
|
|
23
|
+
self.bind_prop(key, value) # type: ignore
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from typing import Any, Callable, Optional
|
|
2
|
+
from ex4nicegui.reactive.utils import ParameterClassifier
|
|
3
|
+
from ex4nicegui.utils.signals import (
|
|
4
|
+
to_value,
|
|
5
|
+
_TMaybeRef as TMaybeRef,
|
|
6
|
+
)
|
|
7
|
+
from nicegui import ui
|
|
8
|
+
from .base import BindableUi
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class TabPanelsBindableUi(BindableUi[ui.tab_panels]):
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
value: Optional[TMaybeRef[str]] = None,
|
|
15
|
+
*,
|
|
16
|
+
on_change: Optional[Callable[..., Any]] = None,
|
|
17
|
+
animated: TMaybeRef[bool] = True,
|
|
18
|
+
keep_alive: TMaybeRef[bool] = True,
|
|
19
|
+
) -> None:
|
|
20
|
+
pc = ParameterClassifier(
|
|
21
|
+
locals(),
|
|
22
|
+
maybeRefs=["value", "animated", "keep_alive"],
|
|
23
|
+
v_model=("value", "on_change"),
|
|
24
|
+
events=["on_change"],
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
element = ui.tab_panels(**pc.get_values_kws())
|
|
28
|
+
super().__init__(element)
|
|
29
|
+
|
|
30
|
+
for key, value in pc.get_bindings().items():
|
|
31
|
+
self.bind_prop(key, value) # type: ignore
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def value(self):
|
|
35
|
+
return self.element.value
|
|
36
|
+
|
|
37
|
+
def bind_prop(self, prop: str, ref_ui: TMaybeRef):
|
|
38
|
+
if prop == "value":
|
|
39
|
+
return self.bind_value(ref_ui)
|
|
40
|
+
|
|
41
|
+
return super().bind_prop(prop, ref_ui)
|
|
42
|
+
|
|
43
|
+
def bind_value(self, ref_ui: TMaybeRef):
|
|
44
|
+
@self._ui_effect
|
|
45
|
+
def _():
|
|
46
|
+
self.element.set_value(to_value(ref_ui))
|
|
@@ -17,6 +17,7 @@ from ex4nicegui.utils.signals import (
|
|
|
17
17
|
to_value,
|
|
18
18
|
to_raw,
|
|
19
19
|
on,
|
|
20
|
+
RefWrapper,
|
|
20
21
|
)
|
|
21
22
|
from nicegui import ui
|
|
22
23
|
from .base import BindableUi
|
|
@@ -34,8 +35,16 @@ class TableBindableUi(BindableUi[ui.table]):
|
|
|
34
35
|
on_select: Optional[Callable[..., Any]] = None,
|
|
35
36
|
on_pagination_change: Optional[Callable[..., Any]] = None,
|
|
36
37
|
) -> None:
|
|
38
|
+
local_args = locals()
|
|
39
|
+
rows_data = local_args.get("rows")
|
|
40
|
+
if isinstance(rows_data, RefWrapper):
|
|
41
|
+
local_args.update(rows=lambda: rows_data.value)
|
|
42
|
+
columns_data = local_args.get("columns") # type: ignore
|
|
43
|
+
if isinstance(columns_data, RefWrapper):
|
|
44
|
+
local_args.update(columns=lambda: columns_data.value)
|
|
45
|
+
|
|
37
46
|
pc = ParameterClassifier(
|
|
38
|
-
|
|
47
|
+
local_args,
|
|
39
48
|
maybeRefs=[
|
|
40
49
|
"columns",
|
|
41
50
|
"rows",
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from typing import Any, Callable, Optional
|
|
2
|
+
from ex4nicegui.reactive.utils import ParameterClassifier
|
|
3
|
+
from ex4nicegui.utils.signals import (
|
|
4
|
+
to_value,
|
|
5
|
+
_TMaybeRef as TMaybeRef,
|
|
6
|
+
)
|
|
7
|
+
from nicegui import ui
|
|
8
|
+
from .base import BindableUi
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class TabsBindableUi(BindableUi[ui.tabs]):
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
value: Optional[TMaybeRef[str]] = None,
|
|
15
|
+
on_change: Optional[Callable[..., Any]] = None,
|
|
16
|
+
) -> None:
|
|
17
|
+
pc = ParameterClassifier(
|
|
18
|
+
locals(),
|
|
19
|
+
maybeRefs=["value"],
|
|
20
|
+
v_model=("value", "on_change"),
|
|
21
|
+
events=["on_change"],
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
element = ui.tabs(**pc.get_values_kws())
|
|
25
|
+
super().__init__(element)
|
|
26
|
+
|
|
27
|
+
for key, value in pc.get_bindings().items():
|
|
28
|
+
self.bind_prop(key, value) # type: ignore
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def value(self):
|
|
32
|
+
return self.element.value
|
|
33
|
+
|
|
34
|
+
def bind_prop(self, prop: str, ref_ui: TMaybeRef):
|
|
35
|
+
if prop == "value":
|
|
36
|
+
return self.bind_value(ref_ui)
|
|
37
|
+
|
|
38
|
+
return super().bind_prop(prop, ref_ui)
|
|
39
|
+
|
|
40
|
+
def bind_value(self, ref_ui: TMaybeRef):
|
|
41
|
+
@self._ui_effect
|
|
42
|
+
def _():
|
|
43
|
+
self.element.set_value(to_value(ref_ui))
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
props: {
|
|
3
|
+
// childOrderKey: Array,
|
|
4
|
+
// transitionGroupArgs: Array,
|
|
5
|
+
},
|
|
6
|
+
data() {
|
|
7
|
+
return {
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
mounted() {
|
|
11
|
+
},
|
|
12
|
+
render() {
|
|
13
|
+
// debugger
|
|
14
|
+
const h = Vue.h
|
|
15
|
+
const vfgt = Vue.Fragment
|
|
16
|
+
const slotBox = this.$slots.default()
|
|
17
|
+
console.log('tg:', slotBox);
|
|
18
|
+
const wrap = () => [h(vfgt, slotBox)]
|
|
19
|
+
// const wrap = slotBox
|
|
20
|
+
console.log(wrap);
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
// slotBox[0].children = this.childOrderKey.map(idx => {
|
|
24
|
+
// return slotBox[0].children[idx]
|
|
25
|
+
// })
|
|
26
|
+
// console.log(slots);
|
|
27
|
+
|
|
28
|
+
return h(
|
|
29
|
+
Vue.TransitionGroup,
|
|
30
|
+
{
|
|
31
|
+
tag: 'span',
|
|
32
|
+
name: 'list',
|
|
33
|
+
// css: false,
|
|
34
|
+
// ...this.transitionGroupArgs
|
|
35
|
+
}, wrap
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from nicegui.element import Element
|
|
3
|
+
from typing import (
|
|
4
|
+
Any,
|
|
5
|
+
Dict,
|
|
6
|
+
List,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TransitionGroup(Element, component="transitionGroup.js"):
|
|
11
|
+
def __init__(self) -> None:
|
|
12
|
+
super().__init__()
|
|
13
|
+
|
|
14
|
+
def apply_transition_group(self, args: Dict[str, Any]):
|
|
15
|
+
self._props["transitionGroupArgs"] = args
|
|
16
|
+
self.update()
|
|
17
|
+
|
|
18
|
+
def update_child_order_keys(self, keys: List[Any]):
|
|
19
|
+
print(f"keys:{keys=}")
|
|
20
|
+
self._props["childOrderKey"] = keys
|
|
21
|
+
self.update()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def transition_group(fn):
|
|
25
|
+
pass
|
ex4nicegui/reactive/vfor.js
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
1
|
export default {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
props: { itemIds: Array },
|
|
3
|
+
|
|
4
|
+
render() {
|
|
5
|
+
const slotBox = this.$slots.default()
|
|
6
|
+
|
|
7
|
+
const slots = this.itemIds.map(({ elementId }) => {
|
|
8
|
+
return slotBox.find(v => v.key === elementId)
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
return slots
|
|
12
|
+
}
|
|
13
|
+
}
|
ex4nicegui/reactive/vfor.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
from nicegui.element import Element
|
|
3
|
-
from nicegui import
|
|
3
|
+
from nicegui import context
|
|
4
4
|
from ex4nicegui.utils.clientScope import _CLIENT_SCOPE_MANAGER
|
|
5
5
|
from ex4nicegui.utils.signals import (
|
|
6
6
|
TReadonlyRef,
|
|
@@ -8,6 +8,9 @@ from ex4nicegui.utils.signals import (
|
|
|
8
8
|
to_ref,
|
|
9
9
|
to_ref_wrapper,
|
|
10
10
|
TGetterOrReadonlyRef,
|
|
11
|
+
to_value,
|
|
12
|
+
is_reactive,
|
|
13
|
+
RefWrapper,
|
|
11
14
|
)
|
|
12
15
|
from typing import (
|
|
13
16
|
Any,
|
|
@@ -24,9 +27,25 @@ from functools import partial
|
|
|
24
27
|
from dataclasses import dataclass
|
|
25
28
|
from signe.core.scope import Scope
|
|
26
29
|
from .utils import get_attribute
|
|
30
|
+
from ex4nicegui.reactive.empty import Empty
|
|
31
|
+
# from .transitionGroup import TransitionGroup
|
|
27
32
|
|
|
28
33
|
_T = TypeVar("_T")
|
|
29
|
-
_T_data = TGetterOrReadonlyRef[List[Any]]
|
|
34
|
+
_T_data = Union[List[Any], TGetterOrReadonlyRef[List[Any]], RefWrapper]
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class VforItem(Empty):
|
|
38
|
+
pass
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class VforContainer(Element, component="vfor.js"):
|
|
42
|
+
def __init__(self) -> None:
|
|
43
|
+
super().__init__()
|
|
44
|
+
self._props["itemIds"] = []
|
|
45
|
+
|
|
46
|
+
def update_items(self, item_ids: List[Dict]):
|
|
47
|
+
self._props["itemIds"] = item_ids
|
|
48
|
+
self.update()
|
|
30
49
|
|
|
31
50
|
|
|
32
51
|
class VforStore(Generic[_T]):
|
|
@@ -40,10 +59,10 @@ class VforStore(Generic[_T]):
|
|
|
40
59
|
|
|
41
60
|
def get(self) -> TReadonlyRef[_T]:
|
|
42
61
|
def base_setter(value):
|
|
43
|
-
self._source
|
|
62
|
+
to_value(self._source)[self._data_index.value] = value
|
|
44
63
|
|
|
45
64
|
wrapper = to_ref_wrapper(
|
|
46
|
-
lambda: self._source
|
|
65
|
+
lambda: to_value(self._source)[self._data_index.value],
|
|
47
66
|
base_setter,
|
|
48
67
|
)
|
|
49
68
|
wrapper._is_readonly = True
|
|
@@ -62,10 +81,6 @@ class StoreItem:
|
|
|
62
81
|
scope: Scope
|
|
63
82
|
|
|
64
83
|
|
|
65
|
-
class VforContainer(Element, component="vfor.js"):
|
|
66
|
-
pass
|
|
67
|
-
|
|
68
|
-
|
|
69
84
|
def _get_key_with_index(idx: int, data: Any):
|
|
70
85
|
return idx
|
|
71
86
|
|
|
@@ -112,20 +127,25 @@ class vfor(Generic[_T]):
|
|
|
112
127
|
self,
|
|
113
128
|
data: _T_data,
|
|
114
129
|
*,
|
|
115
|
-
key: Optional[str] = None,
|
|
130
|
+
key: Optional[Union[str, Callable[[int, Any], Any]]] = None,
|
|
116
131
|
) -> None:
|
|
117
|
-
self.
|
|
118
|
-
self._data = data
|
|
119
|
-
self._get_key =
|
|
120
|
-
|
|
121
|
-
)
|
|
132
|
+
self._vfor_container = VforContainer()
|
|
133
|
+
self._data = to_ref_wrapper(lambda: data) if is_reactive(data) else data
|
|
134
|
+
self._get_key = _get_key_with_index
|
|
135
|
+
|
|
136
|
+
if isinstance(key, str):
|
|
137
|
+
self._get_key = partial(_get_key_with_getter, key)
|
|
138
|
+
elif isinstance(key, Callable):
|
|
139
|
+
self._get_key = key
|
|
140
|
+
|
|
122
141
|
self._store_map: Dict[Union[Any, int], StoreItem] = {}
|
|
123
142
|
|
|
124
143
|
def __call__(self, fn: Callable[[Any], None]):
|
|
125
144
|
def build_element(index: int, value):
|
|
126
145
|
key = self._get_key(index, value)
|
|
127
|
-
|
|
128
|
-
|
|
146
|
+
|
|
147
|
+
with self._vfor_container, VforItem() as element:
|
|
148
|
+
store = VforStore(self._data, index) # type: ignore
|
|
129
149
|
scope = _CLIENT_SCOPE_MANAGER.new_scope()
|
|
130
150
|
|
|
131
151
|
@scope.run
|
|
@@ -134,54 +154,46 @@ class vfor(Generic[_T]):
|
|
|
134
154
|
|
|
135
155
|
return key, element, store, scope
|
|
136
156
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
157
|
+
for idx, value in enumerate(to_value(self._data)): # type: ignore
|
|
158
|
+
key, element, store, scope = build_element(idx, value)
|
|
159
|
+
self._store_map[key] = StoreItem(store, element.id, scope)
|
|
160
|
+
|
|
161
|
+
ng_client = context.get_client()
|
|
141
162
|
|
|
142
163
|
@on(self._data, deep=True)
|
|
143
164
|
def _():
|
|
144
165
|
data_map = {
|
|
145
|
-
self._get_key(idx, d): d for idx, d in enumerate(self._data
|
|
166
|
+
self._get_key(idx, d): d for idx, d in enumerate(to_value(self._data))
|
|
146
167
|
}
|
|
147
168
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
store_item.store.update(idx)
|
|
164
|
-
element = element_map.get(store_item.elementId)
|
|
165
|
-
assert element
|
|
166
|
-
element.move(self._container)
|
|
167
|
-
|
|
168
|
-
new_store_map[key] = store_item
|
|
169
|
-
else:
|
|
170
|
-
# new row item
|
|
171
|
-
key, element, store, score = build_element(idx, value)
|
|
172
|
-
store_item = StoreItem(store, element.id, score)
|
|
173
|
-
element.move(self._container)
|
|
174
|
-
new_store_map[key] = store_item
|
|
175
|
-
|
|
176
|
-
del_store_items = tuple(
|
|
177
|
-
value
|
|
169
|
+
for idx, (key, value) in enumerate(data_map.items()):
|
|
170
|
+
store_item = self._store_map.get(key)
|
|
171
|
+
if store_item:
|
|
172
|
+
# `data` may have changed the value of a dictionary item,
|
|
173
|
+
# so should update the values in the store one by one.
|
|
174
|
+
store_item.store.update(idx)
|
|
175
|
+
|
|
176
|
+
else:
|
|
177
|
+
# new row item
|
|
178
|
+
key, element, store, score = build_element(idx, value)
|
|
179
|
+
self._store_map[key] = StoreItem(store, element.id, score)
|
|
180
|
+
|
|
181
|
+
# remove item
|
|
182
|
+
remove_items = [
|
|
183
|
+
(key, value)
|
|
178
184
|
for key, value in self._store_map.items()
|
|
179
|
-
if key not in
|
|
185
|
+
if key not in data_map
|
|
186
|
+
]
|
|
187
|
+
|
|
188
|
+
for key, item in remove_items:
|
|
189
|
+
target = ng_client.elements.get(item.elementId)
|
|
190
|
+
self._vfor_container.remove(target) # type: ignore
|
|
191
|
+
item.scope.dispose()
|
|
192
|
+
del self._store_map[key]
|
|
193
|
+
|
|
194
|
+
self._vfor_container.update_items(
|
|
195
|
+
[
|
|
196
|
+
{"key": key, "elementId": self._store_map.get(key).elementId} # type: ignore
|
|
197
|
+
for key in data_map.keys()
|
|
198
|
+
]
|
|
180
199
|
)
|
|
181
|
-
|
|
182
|
-
for store_item in del_store_items:
|
|
183
|
-
store_item.scope.dispose()
|
|
184
|
-
|
|
185
|
-
self._store_map.clear()
|
|
186
|
-
self._store_map = new_store_map
|
|
187
|
-
temp_box.delete()
|
ex4nicegui/utils/signals.py
CHANGED
|
@@ -99,7 +99,7 @@ def is_ref(obj):
|
|
|
99
99
|
return signe.is_signal(obj) or isinstance(obj, (RefWrapper))
|
|
100
100
|
|
|
101
101
|
|
|
102
|
-
def to_value(obj: _TMaybeRef[T]) -> T:
|
|
102
|
+
def to_value(obj: Union[_TMaybeRef[T], RefWrapper]) -> T:
|
|
103
103
|
if is_ref(obj):
|
|
104
104
|
return obj.value # type: ignore
|
|
105
105
|
if isinstance(obj, Callable):
|
|
@@ -329,7 +329,7 @@ class effect_refreshable:
|
|
|
329
329
|
|
|
330
330
|
|
|
331
331
|
def on(
|
|
332
|
-
refs: Union[TGetterOrReadonlyRef, Sequence[TGetterOrReadonlyRef]],
|
|
332
|
+
refs: Union[TGetterOrReadonlyRef, RefWrapper, Sequence[TGetterOrReadonlyRef]],
|
|
333
333
|
onchanges=False,
|
|
334
334
|
priority_level=1,
|
|
335
335
|
effect_kws: Optional[Dict[str, Any]] = None,
|
|
@@ -349,8 +349,10 @@ def on(
|
|
|
349
349
|
|
|
350
350
|
"""
|
|
351
351
|
effect_kws = effect_kws or {}
|
|
352
|
-
|
|
353
|
-
|
|
352
|
+
if not isinstance(refs, Sequence):
|
|
353
|
+
refs = [refs] # type: ignore
|
|
354
|
+
|
|
355
|
+
refs = [(lambda: ref.value) if isinstance(ref, RefWrapper) else ref for ref in refs] # type: ignore
|
|
354
356
|
|
|
355
357
|
effect_kws.update({"priority_level": priority_level})
|
|
356
358
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ex4nicegui
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.3
|
|
4
4
|
Summary: Extension library based on nicegui, providing data responsive,BI functionality modules
|
|
5
5
|
Home-page:
|
|
6
6
|
Author: carson_jia
|
|
@@ -14,7 +14,7 @@ Classifier: Programming Language :: Python :: 3.8
|
|
|
14
14
|
Requires-Python: >=3.8
|
|
15
15
|
Description-Content-Type: text/markdown
|
|
16
16
|
License-File: LICENSE
|
|
17
|
-
Requires-Dist: signe (>=0.4.
|
|
17
|
+
Requires-Dist: signe (>=0.4.14)
|
|
18
18
|
Requires-Dist: nicegui (>=1.4.0)
|
|
19
19
|
Requires-Dist: typing-extensions
|
|
20
20
|
Requires-Dist: executing
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
ex4nicegui/__init__.py,sha256=
|
|
1
|
+
ex4nicegui/__init__.py,sha256=4qmuKMR7xYKdce4byUKEYP8jNnl6o_n-rxHZwFvCYCo,818
|
|
2
2
|
ex4nicegui/bi/__init__.py,sha256=eu-2CuzzrcHCyKQOfoo87v6C9nSwFDdeLhjY0cRV13M,315
|
|
3
3
|
ex4nicegui/bi/dataSource.py,sha256=sQzuQvNWBf20n9cz--1OX5gxT6RUAhwrq_xTQEpSa0o,7691
|
|
4
4
|
ex4nicegui/bi/dataSourceFacade.py,sha256=6NuAyrTIk_L2Tz9IRFpuHKRQY_OwJINDzxoM6JYOc14,8186
|
|
@@ -66,15 +66,19 @@ ex4nicegui/libs/gsap/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
|
|
|
66
66
|
ex4nicegui/libs/gsap/utils/matrix.js,sha256=77scrxbQZXx4ex5HkvnT9IkhMG1rQoDNp4TSYgUeYVk,15235
|
|
67
67
|
ex4nicegui/libs/gsap/utils/paths.js,sha256=2SPaRHQ7zgba9cH8hGhkTYPCZdrrEhE2qhh6ECAEvSA,49314
|
|
68
68
|
ex4nicegui/libs/gsap/utils/strings.js,sha256=47G9slz5ltG9mDSwrfQDtWzzdV5QJ-AIMLRMNK0VSiM,10472
|
|
69
|
-
ex4nicegui/reactive/__init__.py,sha256=
|
|
69
|
+
ex4nicegui/reactive/__init__.py,sha256=PxPRQonNUdgz6Kp6eP0QaYp09tM_zN-S0V9LncYrXS4,3637
|
|
70
|
+
ex4nicegui/reactive/empty.js,sha256=Y-caS4CN8jUq59LgGgcvgfkndze-RgWF_ZMmAcxOrbw,50
|
|
71
|
+
ex4nicegui/reactive/empty.py,sha256=kB851B12V1_VCNsFKW6OmjcdIiuZqGEGjLgA6k6yug8,132
|
|
70
72
|
ex4nicegui/reactive/fileWatcher.py,sha256=gjeZhgar02f-qGQa47Tj5SMaCP_ftRtSU898XUmXl1U,1472
|
|
71
73
|
ex4nicegui/reactive/local_file_picker.py,sha256=d3ERoTOGiPGgE3osCdDwklvERqMl_CVbh-qokTLaAuI,6225
|
|
72
74
|
ex4nicegui/reactive/q_pagination.py,sha256=WcSYpB75NH3lffw3HXwZRcvnh0l6EA1Eqp5bcJKIJaw,1505
|
|
73
75
|
ex4nicegui/reactive/rxui.py,sha256=gZ8ZEjGuJFKcedEZhcm4PIZguNkY-Wv5yQx80QnsBKI,31
|
|
76
|
+
ex4nicegui/reactive/transitionGroup.js,sha256=rbfNU3Jrz9WFDQih3BgZOgC1MBr6j9cODZ9XggMAaTs,898
|
|
77
|
+
ex4nicegui/reactive/transitionGroup.py,sha256=VWyYL3QUfX6YQXuxwBFF4sJ4P5VP1S-bCjLKUr28KEY,597
|
|
74
78
|
ex4nicegui/reactive/usePagination.py,sha256=Gop9KV780DcQK5bH4zQZ5sRpV3jOD2sRX_Bpmb1LTFI,2598
|
|
75
79
|
ex4nicegui/reactive/utils.py,sha256=DZ77y0qQAeHUb52yyCKlLE5_3MQlE_OAUH_M1s31_Qg,4360
|
|
76
|
-
ex4nicegui/reactive/vfor.js,sha256=
|
|
77
|
-
ex4nicegui/reactive/vfor.py,sha256=
|
|
80
|
+
ex4nicegui/reactive/vfor.js,sha256=xtKVUPSN0BP99H0BO6LRUYFqxqTGIRttQh5UjoUTwBc,282
|
|
81
|
+
ex4nicegui/reactive/vfor.py,sha256=MirlPrwDSy0YR85i4wcGGGX4QjuN5iek3fIxhIpFbGo,5786
|
|
78
82
|
ex4nicegui/reactive/vmodel.py,sha256=SgmchPVfM6uQAH60VlVyNobfuTg3ScuxlXNFJLRD-r8,5091
|
|
79
83
|
ex4nicegui/reactive/EChartsComponent/ECharts.js,sha256=HMmgXlDl548H4JpozDSbLWv-opvPi3OdJz_XY_MHbnY,3326
|
|
80
84
|
ex4nicegui/reactive/EChartsComponent/ECharts.py,sha256=hoUZ7h-KOUKNd-1BybSX4xxv33gYuTkky70yEzv-oIA,6344
|
|
@@ -90,7 +94,7 @@ ex4nicegui/reactive/mermaid/mermaid.js,sha256=Ds5VevGWZE1_N0WKf-uITd8xSCO9gQzVUs
|
|
|
90
94
|
ex4nicegui/reactive/mermaid/mermaid.py,sha256=uP321QiNj_S5E5I2KF9h03WlSFdRITE8tvObGdk6m7M,2144
|
|
91
95
|
ex4nicegui/reactive/officials/__init__.py,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
|
92
96
|
ex4nicegui/reactive/officials/aggrid.py,sha256=aSaRgpdX3IXlqcq8E1xm3HOD8qDvuwz0H_rU5A7AAEk,2929
|
|
93
|
-
ex4nicegui/reactive/officials/base.py,sha256=
|
|
97
|
+
ex4nicegui/reactive/officials/base.py,sha256=V4Bg33sJnlTY5LUGbRphoXtQhVlVyvo_AVJqrmVCLO8,10440
|
|
94
98
|
ex4nicegui/reactive/officials/button.py,sha256=12FZ2cQGFsTsivSHT9YfDD_wP_D4xrpHHfKmVNNKLJE,1660
|
|
95
99
|
ex4nicegui/reactive/officials/card.py,sha256=8-tBwm3xfVybolQ87i8lAYUpBV6FdaVdeSH6xu0736U,1275
|
|
96
100
|
ex4nicegui/reactive/officials/checkbox.py,sha256=BcSbWuMTA2UgwOeuBTtpvzqdOivb2xbkLazfGqwuboo,1562
|
|
@@ -116,7 +120,11 @@ ex4nicegui/reactive/officials/row.py,sha256=pwFJBdv3_D5-E-oga-OG5t57ahHcYXGSI_-U
|
|
|
116
120
|
ex4nicegui/reactive/officials/select.py,sha256=Fj4V96ju2tpsP1ok0RFokN1K7TxzNS9YLVCz55O788Y,2980
|
|
117
121
|
ex4nicegui/reactive/officials/slider.py,sha256=6E6UeyX_hXIDz_-0v6WEIfTM5oqzukonRyqDRJHT-PA,2954
|
|
118
122
|
ex4nicegui/reactive/officials/switch.py,sha256=-QDXbOQllnWRE28pAH74qrgpN1TXs-1snLDqN6pdiVM,1605
|
|
119
|
-
ex4nicegui/reactive/officials/
|
|
123
|
+
ex4nicegui/reactive/officials/tab.py,sha256=RaS152hfUBz4aOidahzwy7GPV3jR4eWBWKnVXrITXUw,1796
|
|
124
|
+
ex4nicegui/reactive/officials/tab_panel.py,sha256=96aR6Y8oqVFnZo_U8lX5V8mpXR7YIUldSvQMI3oFYQ0,630
|
|
125
|
+
ex4nicegui/reactive/officials/tab_panels.py,sha256=kHxr5JdMvyW2pnmhT6oHsXu9XxqHC898AVrt9skJk84,1375
|
|
126
|
+
ex4nicegui/reactive/officials/table.py,sha256=lisS7PN-3rUo-7i5Fa7h-nssq1xh0Pjq5tyf5ew0sQo,6042
|
|
127
|
+
ex4nicegui/reactive/officials/tabs.py,sha256=mKIz9qsMeTxeZfpAKk4mErpK4m7XrwFQ-jpYm29P8yw,1232
|
|
120
128
|
ex4nicegui/reactive/officials/textarea.py,sha256=EeimLMd1oycdhlrzdET29riv9HaSlQyNxvGkXu00nsc,3044
|
|
121
129
|
ex4nicegui/reactive/officials/upload.py,sha256=WYbbOqAcgnVUuqfF4WAMawldRHB9DthP6NSTyc-4Bwo,2360
|
|
122
130
|
ex4nicegui/reactive/officials/utils.py,sha256=-fnRjyb4Yx7_6jmVeQIZKXFRNV3BWbI7JR_EemMEoTg,213
|
|
@@ -132,9 +140,9 @@ ex4nicegui/utils/clientScope.py,sha256=-KJnrZGqdAQUNNbQbqMAqNzWHCVon-lC3aaQGuaTd
|
|
|
132
140
|
ex4nicegui/utils/common.py,sha256=7P0vboDadLun6EMxNi3br9rKJgKt0QT4sy_66cHEwb4,994
|
|
133
141
|
ex4nicegui/utils/effect.py,sha256=MgvWuAP3OFs2bR4ef6uXPwGCkKORUK-4hmx1oSwl04Y,2310
|
|
134
142
|
ex4nicegui/utils/scheduler.py,sha256=Wa963Df3UDvWHjXXoVYGIBevIILzCFoz-yAWjvxeyfQ,1218
|
|
135
|
-
ex4nicegui/utils/signals.py,sha256
|
|
136
|
-
ex4nicegui-0.6.
|
|
137
|
-
ex4nicegui-0.6.
|
|
138
|
-
ex4nicegui-0.6.
|
|
139
|
-
ex4nicegui-0.6.
|
|
140
|
-
ex4nicegui-0.6.
|
|
143
|
+
ex4nicegui/utils/signals.py,sha256=-80iaAzIyUDR_7LBr8TfOY59Fj4dSq92klWXoRy538g,11346
|
|
144
|
+
ex4nicegui-0.6.3.dist-info/LICENSE,sha256=0KDDElS2dl-HIsWvbpy8ywbLzJMBFzXLev57LnMIZXs,1094
|
|
145
|
+
ex4nicegui-0.6.3.dist-info/METADATA,sha256=wmIPVn_YKEZWuMghpS4n3k86j___PqFROxrmOR9CQrc,27618
|
|
146
|
+
ex4nicegui-0.6.3.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
|
147
|
+
ex4nicegui-0.6.3.dist-info/top_level.txt,sha256=VFwMiO9AFjj5rfLMJwN1ipLRASk9fJXB8tM6DNrpvPQ,11
|
|
148
|
+
ex4nicegui-0.6.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|