_GuiCoreLib.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  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.core import Cycle, DataNode, Job, Scenario, Sequence, Task
  14. from taipy.gui import Gui
  15. from taipy.gui.extension import Element, ElementLibrary, ElementProperty, PropertyType
  16. from ..version import _get_version
  17. from ._adapters import (
  18. _GuiCoreDatanodeAdapter,
  19. _GuiCoreDoNotUpdate,
  20. _GuiCoreScenarioAdapter,
  21. _GuiCoreScenarioDagAdapter,
  22. _GuiCoreScenarioFilter,
  23. _GuiCoreScenarioSort,
  24. )
  25. from ._context import _GuiCoreContext
  26. Scenario.__bases__ += (_GuiCoreDoNotUpdate,)
  27. Sequence.__bases__ += (_GuiCoreDoNotUpdate,)
  28. DataNode.__bases__ += (_GuiCoreDoNotUpdate,)
  29. Cycle.__bases__ += (_GuiCoreDoNotUpdate,)
  30. Job.__bases__ += (_GuiCoreDoNotUpdate,)
  31. Task.__bases__ += (_GuiCoreDoNotUpdate,)
  32. class _GuiCore(ElementLibrary):
  33. __LIB_NAME = "taipy_gui_core"
  34. __CTX_VAR_NAME = f"__{__LIB_NAME}_Ctx"
  35. __SCENARIO_ADAPTER = "tgc_scenario"
  36. __DATANODE_ADAPTER = "tgc_datanode"
  37. __JOB_ADAPTER = "tgc_job"
  38. __SCENARIO_SELECTOR_ERROR_VAR = "__tpgc_sc_error"
  39. __SCENARIO_SELECTOR_ID_VAR = "__tpgc_sc_id"
  40. __SCENARIO_SELECTOR_FILTER_VAR = "__tpgc_sc_filter"
  41. __SCENARIO_SELECTOR_SORT_VAR = "__tpgc_sc_sort"
  42. __SCENARIO_VIZ_ERROR_VAR = "__tpgc_sv_error"
  43. __JOB_SELECTOR_ERROR_VAR = "__tpgc_js_error"
  44. __DATANODE_VIZ_ERROR_VAR = "__tpgc_dv_error"
  45. __DATANODE_VIZ_OWNER_ID_VAR = "__tpgc_dv_owner_id"
  46. __DATANODE_VIZ_HISTORY_ID_VAR = "__tpgc_dv_history_id"
  47. __DATANODE_VIZ_PROPERTIES_ID_VAR = "__tpgc_dv_properties_id"
  48. __DATANODE_VIZ_DATA_ID_VAR = "__tpgc_dv_data_id"
  49. __DATANODE_VIZ_DATA_CHART_ID_VAR = "__tpgc_dv_data_chart_id"
  50. __DATANODE_VIZ_DATA_NODE_PROP = "data_node"
  51. __DATANODE_SEL_SCENARIO_PROP = "scenario"
  52. __SEL_SCENARIOS_PROP = "scenarios"
  53. __elts = {
  54. "scenario_selector": Element(
  55. "value",
  56. {
  57. "id": ElementProperty(PropertyType.string),
  58. "show_add_button": ElementProperty(PropertyType.boolean, True),
  59. "display_cycles": ElementProperty(PropertyType.boolean, True),
  60. "show_primary_flag": ElementProperty(PropertyType.boolean, True),
  61. "value": ElementProperty(PropertyType.lov_value),
  62. "on_change": ElementProperty(PropertyType.function),
  63. "height": ElementProperty(PropertyType.string, "50vh"),
  64. "class_name": ElementProperty(PropertyType.dynamic_string),
  65. "show_pins": ElementProperty(PropertyType.boolean, False),
  66. "on_creation": ElementProperty(PropertyType.function),
  67. "show_dialog": ElementProperty(PropertyType.boolean, True),
  68. __SEL_SCENARIOS_PROP: ElementProperty(PropertyType.dynamic_list),
  69. "multiple": ElementProperty(PropertyType.boolean, False),
  70. "filter": ElementProperty(_GuiCoreScenarioFilter, _GuiCoreScenarioFilter.DEFAULT),
  71. "sort": ElementProperty(_GuiCoreScenarioSort, _GuiCoreScenarioSort.DEFAULT),
  72. "show_search": ElementProperty(PropertyType.boolean, True),
  73. },
  74. inner_properties={
  75. "inner_scenarios": ElementProperty(
  76. PropertyType.lov,
  77. f"{{{__CTX_VAR_NAME}.get_scenarios(<tp:prop:{__SEL_SCENARIOS_PROP}>, "
  78. + f"{__SCENARIO_SELECTOR_FILTER_VAR}<tp:uniq:sc>, "
  79. + f"{__SCENARIO_SELECTOR_SORT_VAR}<tp:uniq:sc>)}}",
  80. ),
  81. "on_scenario_crud": ElementProperty(PropertyType.function, f"{{{__CTX_VAR_NAME}.crud_scenario}}"),
  82. "configs": ElementProperty(PropertyType.react, f"{{{__CTX_VAR_NAME}.get_scenario_configs()}}"),
  83. "core_changed": ElementProperty(PropertyType.broadcast, _GuiCoreContext._CORE_CHANGED_NAME),
  84. "error": ElementProperty(PropertyType.react, f"{{{__SCENARIO_SELECTOR_ERROR_VAR}<tp:uniq:sc>}}"),
  85. "type": ElementProperty(PropertyType.inner, __SCENARIO_ADAPTER),
  86. "scenario_edit": ElementProperty(
  87. _GuiCoreScenarioAdapter,
  88. f"{{{__CTX_VAR_NAME}.get_scenario_by_id({__SCENARIO_SELECTOR_ID_VAR}<tp:uniq:sc>)}}",
  89. ),
  90. "on_scenario_select": ElementProperty(PropertyType.function, f"{{{__CTX_VAR_NAME}.select_scenario}}"),
  91. "update_sc_vars": ElementProperty(
  92. PropertyType.string,
  93. f"filter={__SCENARIO_SELECTOR_FILTER_VAR}<tp:uniq:sc>;"
  94. + f"sort={__SCENARIO_SELECTOR_SORT_VAR}<tp:uniq:sc>;"
  95. + f"sc_id={__SCENARIO_SELECTOR_ID_VAR}<tp:uniq:sc>;"
  96. + f"error_id={__SCENARIO_SELECTOR_ERROR_VAR}<tp:uniq:sc>",
  97. ),
  98. },
  99. ),
  100. "scenario": Element(
  101. "scenario",
  102. {
  103. "id": ElementProperty(PropertyType.string),
  104. "scenario": ElementProperty(_GuiCoreScenarioAdapter),
  105. "active": ElementProperty(PropertyType.dynamic_boolean, True),
  106. "expandable": ElementProperty(PropertyType.boolean, True),
  107. "expanded": ElementProperty(PropertyType.boolean, True),
  108. "show_submit": ElementProperty(PropertyType.boolean, True),
  109. "show_delete": ElementProperty(PropertyType.boolean, True),
  110. "show_config": ElementProperty(PropertyType.boolean, False),
  111. "show_cycle": ElementProperty(PropertyType.boolean, False),
  112. "show_tags": ElementProperty(PropertyType.boolean, True),
  113. "show_properties": ElementProperty(PropertyType.boolean, True),
  114. "show_sequences": ElementProperty(PropertyType.boolean, True),
  115. "show_submit_sequences": ElementProperty(PropertyType.boolean, True),
  116. "class_name": ElementProperty(PropertyType.dynamic_string),
  117. "on_submission_change": ElementProperty(PropertyType.function),
  118. },
  119. inner_properties={
  120. "on_edit": ElementProperty(PropertyType.function, f"{{{__CTX_VAR_NAME}.edit_entity}}"),
  121. "on_submit": ElementProperty(PropertyType.function, f"{{{__CTX_VAR_NAME}.submit_entity}}"),
  122. "on_delete": ElementProperty(PropertyType.function, f"{{{__CTX_VAR_NAME}.crud_scenario}}"),
  123. "core_changed": ElementProperty(PropertyType.broadcast, _GuiCoreContext._CORE_CHANGED_NAME),
  124. "error": ElementProperty(PropertyType.react, f"{{{__SCENARIO_VIZ_ERROR_VAR}<tp:uniq:sv>}}"),
  125. "update_sc_vars": ElementProperty(
  126. PropertyType.string,
  127. f"error_id={__SCENARIO_SELECTOR_ERROR_VAR}<tp:uniq:sv>",
  128. ),
  129. },
  130. ),
  131. "scenario_dag": Element(
  132. "scenario",
  133. {
  134. "id": ElementProperty(PropertyType.string),
  135. "scenario": ElementProperty(_GuiCoreScenarioDagAdapter),
  136. "render": ElementProperty(PropertyType.dynamic_boolean, True),
  137. "show_toolbar": ElementProperty(PropertyType.boolean, True),
  138. "width": ElementProperty(PropertyType.string),
  139. "height": ElementProperty(PropertyType.string),
  140. "class_name": ElementProperty(PropertyType.dynamic_string),
  141. "on_action": ElementProperty(PropertyType.function),
  142. },
  143. inner_properties={
  144. "core_changed": ElementProperty(PropertyType.broadcast, _GuiCoreContext._CORE_CHANGED_NAME),
  145. "on_select": ElementProperty(PropertyType.function, f"{{{__CTX_VAR_NAME}.on_dag_select}}"),
  146. },
  147. ),
  148. "data_node_selector": Element(
  149. "value",
  150. {
  151. "id": ElementProperty(PropertyType.string),
  152. "display_cycles": ElementProperty(PropertyType.boolean, True),
  153. "show_primary_flag": ElementProperty(PropertyType.boolean, True),
  154. "value": ElementProperty(PropertyType.lov_value),
  155. "on_change": ElementProperty(PropertyType.function),
  156. "height": ElementProperty(PropertyType.string, "50vh"),
  157. "class_name": ElementProperty(PropertyType.dynamic_string),
  158. "show_pins": ElementProperty(PropertyType.boolean, True),
  159. __DATANODE_SEL_SCENARIO_PROP: ElementProperty(PropertyType.dynamic_list),
  160. "multiple": ElementProperty(PropertyType.boolean, False),
  161. },
  162. inner_properties={
  163. "datanodes": ElementProperty(
  164. PropertyType.lov,
  165. f"{{{__CTX_VAR_NAME}.get_datanodes_tree(<tp:prop:{__DATANODE_SEL_SCENARIO_PROP}>)}}",
  166. ),
  167. "core_changed": ElementProperty(PropertyType.broadcast, _GuiCoreContext._CORE_CHANGED_NAME),
  168. "type": ElementProperty(PropertyType.inner, __DATANODE_ADAPTER),
  169. },
  170. ),
  171. "data_node": Element(
  172. __DATANODE_VIZ_DATA_NODE_PROP,
  173. {
  174. "id": ElementProperty(PropertyType.string),
  175. __DATANODE_VIZ_DATA_NODE_PROP: ElementProperty(_GuiCoreDatanodeAdapter),
  176. "active": ElementProperty(PropertyType.dynamic_boolean, True),
  177. "expandable": ElementProperty(PropertyType.boolean, True),
  178. "expanded": ElementProperty(PropertyType.boolean, True),
  179. "show_config": ElementProperty(PropertyType.boolean, False),
  180. "show_owner": ElementProperty(PropertyType.boolean, True),
  181. "show_edit_date": ElementProperty(PropertyType.boolean, False),
  182. "show_expiration_date": ElementProperty(PropertyType.boolean, False),
  183. "show_properties": ElementProperty(PropertyType.boolean, True),
  184. "show_history": ElementProperty(PropertyType.boolean, True),
  185. "show_data": ElementProperty(PropertyType.boolean, True),
  186. "chart_configs": ElementProperty(PropertyType.dict),
  187. "class_name": ElementProperty(PropertyType.dynamic_string),
  188. "scenario": ElementProperty(PropertyType.lov_value, "optional"),
  189. "width": ElementProperty(PropertyType.string),
  190. },
  191. inner_properties={
  192. "on_edit": ElementProperty(PropertyType.function, f"{{{__CTX_VAR_NAME}.edit_data_node}}"),
  193. "core_changed": ElementProperty(PropertyType.broadcast, _GuiCoreContext._CORE_CHANGED_NAME),
  194. "error": ElementProperty(PropertyType.react, f"{{{__DATANODE_VIZ_ERROR_VAR}<tp:uniq:dn>}}"),
  195. "scenarios": ElementProperty(
  196. PropertyType.lov,
  197. f"{{{__CTX_VAR_NAME}.get_scenarios_for_owner({__DATANODE_VIZ_OWNER_ID_VAR}<tp:uniq:dn>)}}",
  198. ),
  199. "type": ElementProperty(PropertyType.inner, __SCENARIO_ADAPTER),
  200. "dn_properties": ElementProperty(
  201. PropertyType.react,
  202. f"{{{__CTX_VAR_NAME}.get_data_node_properties("
  203. + f"{__DATANODE_VIZ_PROPERTIES_ID_VAR}<tp:uniq:dn>)}}",
  204. ),
  205. "history": ElementProperty(
  206. PropertyType.react,
  207. f"{{{__CTX_VAR_NAME}.get_data_node_history(" + f"{__DATANODE_VIZ_HISTORY_ID_VAR}<tp:uniq:dn>)}}",
  208. ),
  209. "tabular_data": ElementProperty(
  210. PropertyType.data,
  211. f"{{{__CTX_VAR_NAME}.get_data_node_tabular_data(" + f"{__DATANODE_VIZ_DATA_ID_VAR}<tp:uniq:dn>)}}",
  212. ),
  213. "tabular_columns": ElementProperty(
  214. PropertyType.dynamic_string,
  215. f"{{{__CTX_VAR_NAME}.get_data_node_tabular_columns("
  216. + f"{__DATANODE_VIZ_DATA_ID_VAR}<tp:uniq:dn>)}}",
  217. with_update=True,
  218. ),
  219. "chart_config": ElementProperty(
  220. PropertyType.dynamic_string,
  221. f"{{{__CTX_VAR_NAME}.get_data_node_chart_config("
  222. + f"{__DATANODE_VIZ_DATA_CHART_ID_VAR}<tp:uniq:dn>)}}",
  223. with_update=True,
  224. ),
  225. "on_data_value": ElementProperty(PropertyType.function, f"{{{__CTX_VAR_NAME}.update_data}}"),
  226. "on_tabular_data_edit": ElementProperty(
  227. PropertyType.function, f"{{{__CTX_VAR_NAME}.tabular_data_edit}}"
  228. ),
  229. "on_lock": ElementProperty(PropertyType.function, f"{{{__CTX_VAR_NAME}.lock_datanode_for_edit}}"),
  230. "update_dn_vars": ElementProperty(
  231. PropertyType.string,
  232. f"data_id={__DATANODE_VIZ_DATA_ID_VAR}<tp:uniq:dn>;"
  233. + f"history_id={__DATANODE_VIZ_HISTORY_ID_VAR}<tp:uniq:dn>;"
  234. + f"owner_id={__DATANODE_VIZ_OWNER_ID_VAR}<tp:uniq:dn>;"
  235. + f"chart_id={__DATANODE_VIZ_DATA_CHART_ID_VAR}<tp:uniq:dn>;"
  236. + f"properties_id={__DATANODE_VIZ_PROPERTIES_ID_VAR}<tp:uniq:dn>;"
  237. + f"error_id={__DATANODE_VIZ_ERROR_VAR}<tp:uniq:dn>",
  238. ),
  239. },
  240. ),
  241. "job_selector": Element(
  242. "value",
  243. {
  244. "id": ElementProperty(PropertyType.string),
  245. "class_name": ElementProperty(PropertyType.dynamic_string),
  246. "value": ElementProperty(PropertyType.lov_value),
  247. "show_id": ElementProperty(PropertyType.boolean, True),
  248. "show_submitted_label": ElementProperty(PropertyType.boolean, True),
  249. "show_submitted_id": ElementProperty(PropertyType.boolean, False),
  250. "show_submission_id": ElementProperty(PropertyType.boolean, False),
  251. "show_date": ElementProperty(PropertyType.boolean, True),
  252. "show_cancel": ElementProperty(PropertyType.boolean, True),
  253. "show_delete": ElementProperty(PropertyType.boolean, True),
  254. "on_change": ElementProperty(PropertyType.function),
  255. "height": ElementProperty(PropertyType.string, "50vh"),
  256. },
  257. inner_properties={
  258. "jobs": ElementProperty(PropertyType.lov, f"{{{__CTX_VAR_NAME}.get_jobs_list()}}"),
  259. "core_changed": ElementProperty(PropertyType.broadcast, _GuiCoreContext._CORE_CHANGED_NAME),
  260. "type": ElementProperty(PropertyType.inner, __JOB_ADAPTER),
  261. "on_job_action": ElementProperty(PropertyType.function, f"{{{__CTX_VAR_NAME}.act_on_jobs}}"),
  262. "error": ElementProperty(PropertyType.dynamic_string, f"{{{__JOB_SELECTOR_ERROR_VAR}<tp:uniq:jb>}}"),
  263. "update_jb_vars": ElementProperty(
  264. PropertyType.string, f"error_id={__JOB_SELECTOR_ERROR_VAR}<tp:uniq:jb>"
  265. ),
  266. },
  267. ),
  268. }
  269. def get_name(self) -> str:
  270. return _GuiCore.__LIB_NAME
  271. def get_elements(self) -> t.Dict[str, Element]:
  272. return _GuiCore.__elts
  273. def get_scripts(self) -> t.List[str]:
  274. return ["lib/taipy-gui-core.js"]
  275. def on_init(self, gui: Gui) -> t.Optional[t.Tuple[str, t.Any]]:
  276. ctx = _GuiCoreContext(gui)
  277. gui._add_adapter_for_type(_GuiCore.__SCENARIO_ADAPTER, ctx.scenario_adapter)
  278. gui._add_adapter_for_type(_GuiCore.__DATANODE_ADAPTER, ctx.data_node_adapter)
  279. gui._add_adapter_for_type(_GuiCore.__JOB_ADAPTER, ctx.job_adapter)
  280. return _GuiCore.__CTX_VAR_NAME, ctx
  281. def get_version(self) -> str:
  282. if not hasattr(self, "version"):
  283. self.version = _get_version()
  284. if "dev" in self.version:
  285. self.version += str(datetime.now().timestamp())
  286. return self.version