_GuiCoreLib.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. # Copyright 2021-2024 Avaiga Private Limited
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
  4. # the License. You may obtain a copy of the License at
  5. #
  6. # http://www.apache.org/licenses/LICENSE-2.0
  7. #
  8. # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
  9. # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
  10. # specific language governing permissions and limitations under the License.
  11. import typing as t
  12. from datetime import datetime
  13. from taipy.gui import Gui, State
  14. from taipy.gui.extension import Element, ElementLibrary, ElementProperty, PropertyType
  15. from ..version import _get_version
  16. from ._adapters import (
  17. _GuiCoreDatanodeAdapter,
  18. _GuiCoreScenarioAdapter,
  19. _GuiCoreScenarioDagAdapter,
  20. )
  21. from ._context import _GuiCoreContext
  22. class _GuiCore(ElementLibrary):
  23. __LIB_NAME = "taipy_gui_core"
  24. __CTX_VAR_NAME = f"__{__LIB_NAME}_Ctx"
  25. __SCENARIO_ADAPTER = "tgc_scenario"
  26. __DATANODE_ADAPTER = "tgc_datanode"
  27. __JOB_ADAPTER = "tgc_job"
  28. __INNER_VARS = (
  29. _GuiCoreContext._SCENARIO_SELECTOR_ERROR_VAR,
  30. _GuiCoreContext._SCENARIO_SELECTOR_ID_VAR,
  31. _GuiCoreContext._SCENARIO_VIZ_ERROR_VAR,
  32. _GuiCoreContext._JOB_SELECTOR_ERROR_VAR,
  33. _GuiCoreContext._DATANODE_VIZ_ERROR_VAR,
  34. _GuiCoreContext._DATANODE_VIZ_OWNER_ID_VAR,
  35. _GuiCoreContext._DATANODE_VIZ_HISTORY_ID_VAR,
  36. _GuiCoreContext._DATANODE_VIZ_DATA_ID_VAR,
  37. _GuiCoreContext._DATANODE_VIZ_DATA_CHART_ID_VAR,
  38. _GuiCoreContext._DATANODE_VIZ_PROPERTIES_ID_VAR,
  39. )
  40. __elts = {
  41. "scenario_selector": Element(
  42. "value",
  43. {
  44. "id": ElementProperty(PropertyType.string),
  45. "show_add_button": ElementProperty(PropertyType.boolean, True),
  46. "display_cycles": ElementProperty(PropertyType.boolean, True),
  47. "show_primary_flag": ElementProperty(PropertyType.boolean, True),
  48. "value": ElementProperty(PropertyType.lov_value),
  49. "on_change": ElementProperty(PropertyType.function),
  50. "height": ElementProperty(PropertyType.string, "50vh"),
  51. "class_name": ElementProperty(PropertyType.dynamic_string),
  52. "show_pins": ElementProperty(PropertyType.boolean, False),
  53. "on_creation": ElementProperty(PropertyType.function),
  54. "show_dialog": ElementProperty(PropertyType.boolean, True),
  55. _GuiCoreContext._SEL_SCENARIOS_PROP: ElementProperty(PropertyType.dynamic_list),
  56. "multiple": ElementProperty(PropertyType.boolean, False),
  57. },
  58. inner_properties={
  59. "inner_scenarios": ElementProperty(
  60. PropertyType.lov,
  61. f"{{{__CTX_VAR_NAME}.get_scenarios(<tp:prop:{_GuiCoreContext._SEL_SCENARIOS_PROP}>)}}",
  62. ),
  63. "on_scenario_crud": ElementProperty(PropertyType.function, f"{{{__CTX_VAR_NAME}.crud_scenario}}"),
  64. "configs": ElementProperty(PropertyType.react, f"{{{__CTX_VAR_NAME}.get_scenario_configs()}}"),
  65. "core_changed": ElementProperty(PropertyType.broadcast, _GuiCoreContext._CORE_CHANGED_NAME),
  66. "error": ElementProperty(PropertyType.react, f"{{{_GuiCoreContext._SCENARIO_SELECTOR_ERROR_VAR}}}"),
  67. "type": ElementProperty(PropertyType.inner, __SCENARIO_ADAPTER),
  68. "scenario_edit": ElementProperty(
  69. _GuiCoreScenarioAdapter,
  70. f"{{{__CTX_VAR_NAME}.get_scenario_by_id({_GuiCoreContext._SCENARIO_SELECTOR_ID_VAR})}}",
  71. ),
  72. "on_scenario_select": ElementProperty(PropertyType.function, f"{{{__CTX_VAR_NAME}.select_scenario}}"),
  73. },
  74. ),
  75. "scenario": Element(
  76. "scenario",
  77. {
  78. "id": ElementProperty(PropertyType.string),
  79. "scenario": ElementProperty(_GuiCoreScenarioAdapter),
  80. "active": ElementProperty(PropertyType.dynamic_boolean, True),
  81. "expandable": ElementProperty(PropertyType.boolean, True),
  82. "expanded": ElementProperty(PropertyType.boolean, True),
  83. "show_submit": ElementProperty(PropertyType.boolean, True),
  84. "show_delete": ElementProperty(PropertyType.boolean, True),
  85. "show_config": ElementProperty(PropertyType.boolean, False),
  86. "show_cycle": ElementProperty(PropertyType.boolean, False),
  87. "show_tags": ElementProperty(PropertyType.boolean, True),
  88. "show_properties": ElementProperty(PropertyType.boolean, True),
  89. "show_sequences": ElementProperty(PropertyType.boolean, True),
  90. "show_submit_sequences": ElementProperty(PropertyType.boolean, True),
  91. "class_name": ElementProperty(PropertyType.dynamic_string),
  92. "on_submission_change": ElementProperty(PropertyType.function),
  93. },
  94. inner_properties={
  95. "on_edit": ElementProperty(PropertyType.function, f"{{{__CTX_VAR_NAME}.edit_entity}}"),
  96. "on_submit": ElementProperty(PropertyType.function, f"{{{__CTX_VAR_NAME}.submit_entity}}"),
  97. "on_delete": ElementProperty(PropertyType.function, f"{{{__CTX_VAR_NAME}.crud_scenario}}"),
  98. "core_changed": ElementProperty(PropertyType.broadcast, _GuiCoreContext._CORE_CHANGED_NAME),
  99. "error": ElementProperty(PropertyType.react, f"{{{_GuiCoreContext._SCENARIO_VIZ_ERROR_VAR}}}"),
  100. },
  101. ),
  102. "scenario_dag": Element(
  103. "scenario",
  104. {
  105. "id": ElementProperty(PropertyType.string),
  106. "scenario": ElementProperty(_GuiCoreScenarioDagAdapter),
  107. "render": ElementProperty(PropertyType.dynamic_boolean, True),
  108. "show_toolbar": ElementProperty(PropertyType.boolean, True),
  109. "width": ElementProperty(PropertyType.string),
  110. "height": ElementProperty(PropertyType.string),
  111. "class_name": ElementProperty(PropertyType.dynamic_string),
  112. "on_action": ElementProperty(PropertyType.function),
  113. },
  114. inner_properties={
  115. "core_changed": ElementProperty(PropertyType.broadcast, _GuiCoreContext._CORE_CHANGED_NAME),
  116. "on_select": ElementProperty(PropertyType.function, f"{{{__CTX_VAR_NAME}.on_dag_select}}"),
  117. },
  118. ),
  119. "data_node_selector": Element(
  120. "value",
  121. {
  122. "id": ElementProperty(PropertyType.string),
  123. "display_cycles": ElementProperty(PropertyType.boolean, True),
  124. "show_primary_flag": ElementProperty(PropertyType.boolean, True),
  125. "value": ElementProperty(PropertyType.lov_value),
  126. "on_change": ElementProperty(PropertyType.function),
  127. "height": ElementProperty(PropertyType.string, "50vh"),
  128. "class_name": ElementProperty(PropertyType.dynamic_string),
  129. "show_pins": ElementProperty(PropertyType.boolean, True),
  130. _GuiCoreContext._DATANODE_SEL_SCENARIO_PROP: ElementProperty(PropertyType.dynamic_list),
  131. "multiple": ElementProperty(PropertyType.boolean, False),
  132. },
  133. inner_properties={
  134. "datanodes": ElementProperty(
  135. PropertyType.lov,
  136. f"{{{__CTX_VAR_NAME}.get_datanodes_tree(<tp:prop:{_GuiCoreContext._DATANODE_SEL_SCENARIO_PROP}>)}}",
  137. ),
  138. "core_changed": ElementProperty(PropertyType.broadcast, _GuiCoreContext._CORE_CHANGED_NAME),
  139. "type": ElementProperty(PropertyType.inner, __DATANODE_ADAPTER),
  140. },
  141. ),
  142. "data_node": Element(
  143. _GuiCoreContext._DATANODE_VIZ_DATA_NODE_PROP,
  144. {
  145. "id": ElementProperty(PropertyType.string),
  146. _GuiCoreContext._DATANODE_VIZ_DATA_NODE_PROP: ElementProperty(_GuiCoreDatanodeAdapter),
  147. "active": ElementProperty(PropertyType.dynamic_boolean, True),
  148. "expandable": ElementProperty(PropertyType.boolean, True),
  149. "expanded": ElementProperty(PropertyType.boolean, True),
  150. "show_config": ElementProperty(PropertyType.boolean, False),
  151. "show_owner": ElementProperty(PropertyType.boolean, True),
  152. "show_edit_date": ElementProperty(PropertyType.boolean, False),
  153. "show_expiration_date": ElementProperty(PropertyType.boolean, False),
  154. "show_properties": ElementProperty(PropertyType.boolean, True),
  155. "show_history": ElementProperty(PropertyType.boolean, True),
  156. "show_data": ElementProperty(PropertyType.boolean, True),
  157. "chart_configs": ElementProperty(PropertyType.dict),
  158. "class_name": ElementProperty(PropertyType.dynamic_string),
  159. "scenario": ElementProperty(PropertyType.lov_value, "optional"),
  160. "width": ElementProperty(PropertyType.string),
  161. },
  162. inner_properties={
  163. "on_edit": ElementProperty(PropertyType.function, f"{{{__CTX_VAR_NAME}.edit_data_node}}"),
  164. "core_changed": ElementProperty(PropertyType.broadcast, _GuiCoreContext._CORE_CHANGED_NAME),
  165. "error": ElementProperty(PropertyType.react, f"{{{_GuiCoreContext._DATANODE_VIZ_ERROR_VAR}}}"),
  166. "scenarios": ElementProperty(
  167. PropertyType.lov,
  168. f"{{{__CTX_VAR_NAME}.get_scenarios_for_owner({_GuiCoreContext._DATANODE_VIZ_OWNER_ID_VAR},"
  169. + "<tp:uniq:dn>)}",
  170. ),
  171. "type": ElementProperty(PropertyType.inner, __SCENARIO_ADAPTER),
  172. "dn_properties": ElementProperty(
  173. PropertyType.react,
  174. f"{{{__CTX_VAR_NAME}.get_data_node_properties("
  175. + f"{_GuiCoreContext._DATANODE_VIZ_PROPERTIES_ID_VAR},"
  176. + "<tp:uniq:dn>)}",
  177. ),
  178. "history": ElementProperty(
  179. PropertyType.react,
  180. f"{{{__CTX_VAR_NAME}.get_data_node_history("
  181. + f"{_GuiCoreContext._DATANODE_VIZ_HISTORY_ID_VAR},"
  182. + "<tp:uniq:dn>)}",
  183. ),
  184. "tabular_data": ElementProperty(
  185. PropertyType.data,
  186. f"{{{__CTX_VAR_NAME}.get_data_node_tabular_data("
  187. + f"{_GuiCoreContext._DATANODE_VIZ_DATA_ID_VAR},"
  188. + "<tp:uniq:dn>)}",
  189. ),
  190. "tabular_columns": ElementProperty(
  191. PropertyType.dynamic_string,
  192. f"{{{__CTX_VAR_NAME}.get_data_node_tabular_columns("
  193. + f"{_GuiCoreContext._DATANODE_VIZ_DATA_ID_VAR},"
  194. + "<tp:uniq:dn>)}",
  195. with_update=True,
  196. ),
  197. "chart_config": ElementProperty(
  198. PropertyType.dynamic_string,
  199. f"{{{__CTX_VAR_NAME}.get_data_node_chart_config("
  200. + f"{_GuiCoreContext._DATANODE_VIZ_DATA_CHART_ID_VAR},"
  201. + "<tp:uniq:dn>)}",
  202. with_update=True,
  203. ),
  204. "on_data_value": ElementProperty(PropertyType.function, f"{{{__CTX_VAR_NAME}.update_data}}"),
  205. "on_tabular_data_edit": ElementProperty(
  206. PropertyType.function, f"{{{__CTX_VAR_NAME}.tabular_data_edit}}"
  207. ),
  208. "on_lock": ElementProperty(PropertyType.function, f"{{{__CTX_VAR_NAME}.lock_datanode_for_edit}}"),
  209. "update_dn_vars": ElementProperty(
  210. PropertyType.string,
  211. f"data_id={_GuiCoreContext._DATANODE_VIZ_DATA_ID_VAR};"
  212. + f"history_id={_GuiCoreContext._DATANODE_VIZ_HISTORY_ID_VAR};"
  213. + f"owner_id={_GuiCoreContext._DATANODE_VIZ_OWNER_ID_VAR};"
  214. + f"chart_id={_GuiCoreContext._DATANODE_VIZ_DATA_CHART_ID_VAR};"
  215. + f"properties_id={_GuiCoreContext._DATANODE_VIZ_PROPERTIES_ID_VAR}",
  216. ),
  217. },
  218. ),
  219. "job_selector": Element(
  220. "value",
  221. {
  222. "id": ElementProperty(PropertyType.string),
  223. "class_name": ElementProperty(PropertyType.dynamic_string),
  224. "value": ElementProperty(PropertyType.lov_value),
  225. "show_id": ElementProperty(PropertyType.boolean, True),
  226. "show_submitted_label": ElementProperty(PropertyType.boolean, True),
  227. "show_submitted_id": ElementProperty(PropertyType.boolean, False),
  228. "show_submission_id": ElementProperty(PropertyType.boolean, False),
  229. "show_date": ElementProperty(PropertyType.boolean, True),
  230. "show_cancel": ElementProperty(PropertyType.boolean, True),
  231. "show_delete": ElementProperty(PropertyType.boolean, True),
  232. "on_change": ElementProperty(PropertyType.function),
  233. "height": ElementProperty(PropertyType.string, "50vh"),
  234. },
  235. inner_properties={
  236. "jobs": ElementProperty(PropertyType.lov, f"{{{__CTX_VAR_NAME}.get_jobs_list()}}"),
  237. "core_changed": ElementProperty(PropertyType.broadcast, _GuiCoreContext._CORE_CHANGED_NAME),
  238. "type": ElementProperty(PropertyType.inner, __JOB_ADAPTER),
  239. "on_job_action": ElementProperty(PropertyType.function, f"{{{__CTX_VAR_NAME}.act_on_jobs}}"),
  240. "error": ElementProperty(PropertyType.dynamic_string, f"{{{_GuiCoreContext._JOB_SELECTOR_ERROR_VAR}}}"),
  241. },
  242. ),
  243. }
  244. def get_name(self) -> str:
  245. return _GuiCore.__LIB_NAME
  246. def get_elements(self) -> t.Dict[str, Element]:
  247. return _GuiCore.__elts
  248. def get_scripts(self) -> t.List[str]:
  249. return ["lib/taipy-gui-core.js"]
  250. def on_init(self, gui: Gui) -> t.Optional[t.Tuple[str, t.Any]]:
  251. gui._get_default_locals_bind().update({v: "" for v in _GuiCore.__INNER_VARS})
  252. ctx = _GuiCoreContext(gui)
  253. gui._add_adapter_for_type(_GuiCore.__SCENARIO_ADAPTER, ctx.scenario_adapter)
  254. gui._add_adapter_for_type(_GuiCore.__DATANODE_ADAPTER, ctx.data_node_adapter)
  255. gui._add_adapter_for_type(_GuiCore.__JOB_ADAPTER, ctx.job_adapter)
  256. return _GuiCore.__CTX_VAR_NAME, ctx
  257. def on_user_init(self, state: State):
  258. for var in _GuiCore.__INNER_VARS:
  259. state._add_attribute(var, "")
  260. def get_version(self) -> str:
  261. if not hasattr(self, "version"):
  262. self.version = _get_version()
  263. if "dev" in self.version:
  264. self.version += str(datetime.now().timestamp())
  265. return self.version