jac-client 0.2.3__tar.gz → 0.2.9__tar.gz

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.
Files changed (242) hide show
  1. {jac_client-0.2.3 → jac_client-0.2.9}/PKG-INFO +41 -34
  2. {jac_client-0.2.3 → jac_client-0.2.9}/README.md +29 -17
  3. jac_client-0.2.9/jac_client/examples/all-in-one/assets/workers/worker.py +5 -0
  4. {jac_client-0.2.3 → jac_client-0.2.9}/jac_client/examples/all-in-one/button.jac +1 -1
  5. jac_client-0.2.9/jac_client/examples/all-in-one/components/CategoryFilter.jac +35 -0
  6. jac_client-0.2.9/jac_client/examples/all-in-one/components/Header.jac +13 -0
  7. jac_client-0.2.9/jac_client/examples/all-in-one/components/ProfitOverview.jac +50 -0
  8. jac_client-0.2.9/jac_client/examples/all-in-one/components/Summary.jac +53 -0
  9. jac_client-0.2.9/jac_client/examples/all-in-one/components/TransactionForm.jac +158 -0
  10. jac_client-0.2.9/jac_client/examples/all-in-one/components/TransactionItem.jac +55 -0
  11. jac_client-0.2.9/jac_client/examples/all-in-one/components/TransactionList.jac +37 -0
  12. {jac_client-0.2.3 → jac_client-0.2.9}/jac_client/examples/all-in-one/components/button.jac +1 -1
  13. jac_client-0.2.9/jac_client/examples/all-in-one/components/navigation.jac +132 -0
  14. jac_client-0.2.9/jac_client/examples/all-in-one/constants/categories.jac +37 -0
  15. jac_client-0.2.9/jac_client/examples/all-in-one/constants/clients.jac +13 -0
  16. jac_client-0.2.9/jac_client/examples/all-in-one/context/BudgetContext.jac +28 -0
  17. jac_client-0.2.9/jac_client/examples/all-in-one/hooks/useBudget.jac +116 -0
  18. jac_client-0.2.9/jac_client/examples/all-in-one/hooks/useLocalStorage.jac +36 -0
  19. jac_client-0.2.9/jac_client/examples/all-in-one/main.jac +573 -0
  20. jac_client-0.2.9/jac_client/examples/all-in-one/pages/BudgetPlanner.jac +133 -0
  21. jac_client-0.2.9/jac_client/examples/all-in-one/pages/FeaturesTest.jac +141 -0
  22. jac_client-0.2.9/jac_client/examples/all-in-one/pages/LandingPage.jac +101 -0
  23. jac_client-0.2.9/jac_client/examples/all-in-one/pages/budget_planner_ui.cl.jac +70 -0
  24. jac_client-0.2.9/jac_client/examples/all-in-one/pages/features_test_ui.cl.jac +563 -0
  25. jac_client-0.2.9/jac_client/examples/all-in-one/pages/loginPage.jac +132 -0
  26. jac_client-0.2.9/jac_client/examples/all-in-one/pages/nestedDemo.jac +61 -0
  27. jac_client-0.2.9/jac_client/examples/all-in-one/pages/notFound.jac +19 -0
  28. jac_client-0.2.9/jac_client/examples/all-in-one/pages/signupPage.jac +133 -0
  29. jac_client-0.2.9/jac_client/examples/all-in-one/utils/formatters.jac +52 -0
  30. jac_client-0.2.3/jac_client/examples/asset-serving/css-with-image/app.jac → jac_client-0.2.9/jac_client/examples/asset-serving/css-with-image/main.jac +4 -4
  31. jac_client-0.2.3/jac_client/examples/asset-serving/image-asset/app.jac → jac_client-0.2.9/jac_client/examples/asset-serving/image-asset/main.jac +4 -4
  32. jac_client-0.2.3/jac_client/examples/asset-serving/import-alias/app.jac → jac_client-0.2.9/jac_client/examples/asset-serving/import-alias/main.jac +5 -5
  33. jac_client-0.2.3/jac_client/examples/basic/app.jac → jac_client-0.2.9/jac_client/examples/basic/main.jac +4 -4
  34. jac_client-0.2.9/jac_client/examples/basic-auth/main.jac +371 -0
  35. jac_client-0.2.3/jac_client/examples/basic-auth-with-router/app.jac → jac_client-0.2.9/jac_client/examples/basic-auth-with-router/main.jac +28 -28
  36. jac_client-0.2.3/jac_client/examples/basic-full-stack/app.jac → jac_client-0.2.9/jac_client/examples/basic-full-stack/main.jac +166 -127
  37. jac_client-0.2.3/jac_client/examples/css-styling/js-styling/app.jac → jac_client-0.2.9/jac_client/examples/css-styling/js-styling/main.jac +7 -7
  38. jac_client-0.2.3/jac_client/examples/css-styling/material-ui/app.jac → jac_client-0.2.9/jac_client/examples/css-styling/material-ui/main.jac +6 -6
  39. jac_client-0.2.3/jac_client/examples/css-styling/pure-css/app.jac → jac_client-0.2.9/jac_client/examples/css-styling/pure-css/main.jac +7 -7
  40. jac_client-0.2.3/jac_client/examples/css-styling/sass-example/app.jac → jac_client-0.2.9/jac_client/examples/css-styling/sass-example/main.jac +7 -7
  41. jac_client-0.2.3/jac_client/examples/css-styling/styled-components/app.jac → jac_client-0.2.9/jac_client/examples/css-styling/styled-components/main.jac +6 -6
  42. jac_client-0.2.3/jac_client/examples/css-styling/tailwind-example/app.jac → jac_client-0.2.9/jac_client/examples/css-styling/tailwind-example/main.jac +7 -7
  43. jac_client-0.2.3/jac_client/examples/full-stack-with-auth/app.jac → jac_client-0.2.9/jac_client/examples/full-stack-with-auth/main.jac +47 -47
  44. jac_client-0.2.3/jac_client/examples/little-x/app.jac → jac_client-0.2.9/jac_client/examples/little-x/main.jac +27 -32
  45. jac_client-0.2.9/jac_client/examples/little-x/src/submit-button.jac +16 -0
  46. jac_client-0.2.3/jac_client/examples/nested-folders/nested-advance/app.jac → jac_client-0.2.9/jac_client/examples/nested-folders/nested-advance/main.jac +1 -1
  47. {jac_client-0.2.3/jac_client/examples/nested-folders/nested-advance → jac_client-0.2.9/jac_client/examples/nested-folders/nested-advance/src}/ButtonRoot.jac +1 -1
  48. {jac_client-0.2.3/jac_client/examples/nested-folders/nested-advance → jac_client-0.2.9/jac_client/examples/nested-folders/nested-advance/src}/level1/ButtonSecondL.jac +1 -1
  49. {jac_client-0.2.3/jac_client/examples/nested-folders/nested-advance → jac_client-0.2.9/jac_client/examples/nested-folders/nested-advance/src}/level1/Card.jac +1 -1
  50. {jac_client-0.2.3/jac_client/examples/nested-folders/nested-advance → jac_client-0.2.9/jac_client/examples/nested-folders/nested-advance/src}/level1/level2/ButtonThirdL.jac +1 -1
  51. jac_client-0.2.3/jac_client/examples/nested-folders/nested-basic/app.jac → jac_client-0.2.9/jac_client/examples/nested-folders/nested-basic/main.jac +2 -2
  52. {jac_client-0.2.3/jac_client/examples/nested-folders/nested-basic → jac_client-0.2.9/jac_client/examples/nested-folders/nested-basic/src}/button.jac +1 -1
  53. {jac_client-0.2.3/jac_client/tests/fixtures/relative_import → jac_client-0.2.9/jac_client/examples/nested-folders/nested-basic/src/components}/button.jac +1 -1
  54. jac_client-0.2.9/jac_client/examples/ts-support/main.jac +35 -0
  55. jac_client-0.2.3/jac_client/examples/with-router/app.jac → jac_client-0.2.9/jac_client/examples/with-router/main.jac +15 -15
  56. jac_client-0.2.9/jac_client/plugin/cli.jac +231 -0
  57. jac_client-0.2.9/jac_client/plugin/client.jac +70 -0
  58. jac_client-0.2.9/jac_client/plugin/client_runtime.cl.jac +46 -0
  59. jac_client-0.2.9/jac_client/plugin/impl/client.impl.jac +234 -0
  60. jac_client-0.2.9/jac_client/plugin/impl/client_runtime.impl.jac +349 -0
  61. jac_client-0.2.9/jac_client/plugin/impl/vite_client_bundle.impl.jac +72 -0
  62. jac_client-0.2.9/jac_client/plugin/plugin_config.jac +423 -0
  63. jac_client-0.2.9/jac_client/plugin/src/__init__.jac +20 -0
  64. jac_client-0.2.9/jac_client/plugin/src/asset_processor.jac +33 -0
  65. jac_client-0.2.9/jac_client/plugin/src/babel_processor.jac +18 -0
  66. jac_client-0.2.9/jac_client/plugin/src/compiler.jac +67 -0
  67. jac_client-0.2.9/jac_client/plugin/src/config_loader.jac +33 -0
  68. jac_client-0.2.9/jac_client/plugin/src/impl/asset_processor.impl.jac +127 -0
  69. jac_client-0.2.9/jac_client/plugin/src/impl/babel_processor.impl.jac +89 -0
  70. jac_client-0.2.9/jac_client/plugin/src/impl/compiler.impl.jac +288 -0
  71. jac_client-0.2.9/jac_client/plugin/src/impl/config_loader.impl.jac +127 -0
  72. jac_client-0.2.9/jac_client/plugin/src/impl/import_processor.impl.jac +33 -0
  73. jac_client-0.2.9/jac_client/plugin/src/impl/jac_to_js.impl.jac +41 -0
  74. jac_client-0.2.9/jac_client/plugin/src/impl/package_installer.impl.jac +105 -0
  75. jac_client-0.2.9/jac_client/plugin/src/impl/vite_bundler.impl.jac +707 -0
  76. jac_client-0.2.9/jac_client/plugin/src/import_processor.jac +19 -0
  77. jac_client-0.2.9/jac_client/plugin/src/jac_to_js.jac +35 -0
  78. jac_client-0.2.9/jac_client/plugin/src/package_installer.jac +26 -0
  79. jac_client-0.2.9/jac_client/plugin/src/vite_bundler.jac +50 -0
  80. jac_client-0.2.9/jac_client/plugin/utils/__init__.jac +1 -0
  81. jac_client-0.2.9/jac_client/plugin/utils/impl/node_installer.impl.jac +249 -0
  82. jac_client-0.2.9/jac_client/plugin/utils/node_installer.jac +41 -0
  83. jac_client-0.2.9/jac_client/plugin/vite_client_bundle.jac +31 -0
  84. jac_client-0.2.9/jac_client/templates/client.jacpack +72 -0
  85. jac_client-0.2.9/jac_client/templates/fullstack.jacpack +61 -0
  86. jac_client-0.2.9/jac_client/tests/conftest.py +324 -0
  87. {jac_client-0.2.3 → jac_client-0.2.9}/jac_client/tests/fixtures/basic-app/app.jac +2 -2
  88. {jac_client-0.2.3 → jac_client-0.2.9}/jac_client/tests/fixtures/cl_file/app.cl.jac +2 -2
  89. {jac_client-0.2.3 → jac_client-0.2.9}/jac_client/tests/fixtures/client_app_with_antd/app.jac +1 -1
  90. {jac_client-0.2.3 → jac_client-0.2.9}/jac_client/tests/fixtures/js_import/app.jac +5 -5
  91. {jac_client-0.2.3 → jac_client-0.2.9}/jac_client/tests/fixtures/spawn_test/app.jac +15 -18
  92. jac_client-0.2.9/jac_client/tests/fixtures/with-ts/app.jac +35 -0
  93. jac_client-0.2.9/jac_client/tests/test_cli.py +925 -0
  94. jac_client-0.2.9/jac_client/tests/test_e2e.py +232 -0
  95. jac_client-0.2.9/jac_client/tests/test_helpers.py +65 -0
  96. jac_client-0.2.9/jac_client/tests/test_it.py +780 -0
  97. jac_client-0.2.9/jac_client.egg-info/PKG-INFO +197 -0
  98. jac_client-0.2.9/jac_client.egg-info/SOURCES.txt +107 -0
  99. jac_client-0.2.9/jac_client.egg-info/dependency_links.txt +1 -0
  100. jac_client-0.2.9/jac_client.egg-info/entry_points.txt +4 -0
  101. jac_client-0.2.9/jac_client.egg-info/requires.txt +5 -0
  102. jac_client-0.2.9/jac_client.egg-info/top_level.txt +1 -0
  103. jac_client-0.2.9/pyproject.toml +48 -0
  104. jac_client-0.2.9/setup.cfg +4 -0
  105. jac_client-0.2.3/jac_client/docs/README.md +0 -689
  106. jac_client-0.2.3/jac_client/docs/advanced-state.md +0 -1265
  107. jac_client-0.2.3/jac_client/docs/asset-serving/intro.md +0 -209
  108. jac_client-0.2.3/jac_client/docs/assets/pipe_line-v2.svg +0 -32
  109. jac_client-0.2.3/jac_client/docs/assets/pipe_line.png +0 -0
  110. jac_client-0.2.3/jac_client/docs/file-system/app.jac.md +0 -121
  111. jac_client-0.2.3/jac_client/docs/file-system/backend-frontend.md +0 -217
  112. jac_client-0.2.3/jac_client/docs/file-system/intro.md +0 -72
  113. jac_client-0.2.3/jac_client/docs/file-system/nested-imports.md +0 -348
  114. jac_client-0.2.3/jac_client/docs/guide-example/intro.md +0 -115
  115. jac_client-0.2.3/jac_client/docs/guide-example/step-01-setup.md +0 -270
  116. jac_client-0.2.3/jac_client/docs/guide-example/step-02-components.md +0 -416
  117. jac_client-0.2.3/jac_client/docs/guide-example/step-03-styling.md +0 -478
  118. jac_client-0.2.3/jac_client/docs/guide-example/step-04-todo-ui.md +0 -477
  119. jac_client-0.2.3/jac_client/docs/guide-example/step-05-local-state.md +0 -530
  120. jac_client-0.2.3/jac_client/docs/guide-example/step-06-events.md +0 -749
  121. jac_client-0.2.3/jac_client/docs/guide-example/step-07-effects.md +0 -468
  122. jac_client-0.2.3/jac_client/docs/guide-example/step-08-walkers.md +0 -534
  123. jac_client-0.2.3/jac_client/docs/guide-example/step-09-authentication.md +0 -586
  124. jac_client-0.2.3/jac_client/docs/guide-example/step-10-routing.md +0 -539
  125. jac_client-0.2.3/jac_client/docs/guide-example/step-11-final.md +0 -963
  126. jac_client-0.2.3/jac_client/docs/imports.md +0 -1141
  127. jac_client-0.2.3/jac_client/docs/lifecycle-hooks.md +0 -773
  128. jac_client-0.2.3/jac_client/docs/routing.md +0 -659
  129. jac_client-0.2.3/jac_client/docs/styling/intro.md +0 -249
  130. jac_client-0.2.3/jac_client/docs/styling/js-styling.md +0 -367
  131. jac_client-0.2.3/jac_client/docs/styling/material-ui.md +0 -341
  132. jac_client-0.2.3/jac_client/docs/styling/pure-css.md +0 -299
  133. jac_client-0.2.3/jac_client/docs/styling/sass.md +0 -403
  134. jac_client-0.2.3/jac_client/docs/styling/styled-components.md +0 -395
  135. jac_client-0.2.3/jac_client/docs/styling/tailwind.md +0 -298
  136. jac_client-0.2.3/jac_client/examples/all-in-one/.babelrc +0 -9
  137. jac_client-0.2.3/jac_client/examples/all-in-one/README.md +0 -16
  138. jac_client-0.2.3/jac_client/examples/all-in-one/app.jac +0 -426
  139. jac_client-0.2.3/jac_client/examples/all-in-one/assets/burger.png +0 -0
  140. jac_client-0.2.3/jac_client/examples/all-in-one/package.json +0 -29
  141. jac_client-0.2.3/jac_client/examples/all-in-one/styles.css +0 -26
  142. jac_client-0.2.3/jac_client/examples/all-in-one/vite.config.js +0 -28
  143. jac_client-0.2.3/jac_client/examples/asset-serving/css-with-image/.babelrc +0 -9
  144. jac_client-0.2.3/jac_client/examples/asset-serving/css-with-image/README.md +0 -91
  145. jac_client-0.2.3/jac_client/examples/asset-serving/css-with-image/assets/burger.png +0 -0
  146. jac_client-0.2.3/jac_client/examples/asset-serving/css-with-image/package.json +0 -28
  147. jac_client-0.2.3/jac_client/examples/asset-serving/css-with-image/styles.css +0 -26
  148. jac_client-0.2.3/jac_client/examples/asset-serving/css-with-image/vite.config.js +0 -28
  149. jac_client-0.2.3/jac_client/examples/asset-serving/image-asset/.babelrc +0 -9
  150. jac_client-0.2.3/jac_client/examples/asset-serving/image-asset/README.md +0 -119
  151. jac_client-0.2.3/jac_client/examples/asset-serving/image-asset/assets/burger.png +0 -0
  152. jac_client-0.2.3/jac_client/examples/asset-serving/image-asset/package.json +0 -28
  153. jac_client-0.2.3/jac_client/examples/asset-serving/image-asset/styles.css +0 -26
  154. jac_client-0.2.3/jac_client/examples/asset-serving/image-asset/vite.config.js +0 -28
  155. jac_client-0.2.3/jac_client/examples/asset-serving/import-alias/.babelrc +0 -9
  156. jac_client-0.2.3/jac_client/examples/asset-serving/import-alias/README.md +0 -83
  157. jac_client-0.2.3/jac_client/examples/asset-serving/import-alias/assets/burger.png +0 -0
  158. jac_client-0.2.3/jac_client/examples/asset-serving/import-alias/package.json +0 -28
  159. jac_client-0.2.3/jac_client/examples/asset-serving/import-alias/vite.config.js +0 -28
  160. jac_client-0.2.3/jac_client/examples/basic/.babelrc +0 -9
  161. jac_client-0.2.3/jac_client/examples/basic/README.md +0 -16
  162. jac_client-0.2.3/jac_client/examples/basic/package.json +0 -27
  163. jac_client-0.2.3/jac_client/examples/basic/vite.config.js +0 -27
  164. jac_client-0.2.3/jac_client/examples/basic-auth/.babelrc +0 -9
  165. jac_client-0.2.3/jac_client/examples/basic-auth/README.md +0 -16
  166. jac_client-0.2.3/jac_client/examples/basic-auth/app.jac +0 -308
  167. jac_client-0.2.3/jac_client/examples/basic-auth/package.json +0 -27
  168. jac_client-0.2.3/jac_client/examples/basic-auth/vite.config.js +0 -27
  169. jac_client-0.2.3/jac_client/examples/basic-auth-with-router/.babelrc +0 -9
  170. jac_client-0.2.3/jac_client/examples/basic-auth-with-router/README.md +0 -60
  171. jac_client-0.2.3/jac_client/examples/basic-auth-with-router/package.json +0 -28
  172. jac_client-0.2.3/jac_client/examples/basic-auth-with-router/vite.config.js +0 -27
  173. jac_client-0.2.3/jac_client/examples/basic-full-stack/.babelrc +0 -9
  174. jac_client-0.2.3/jac_client/examples/basic-full-stack/README.md +0 -18
  175. jac_client-0.2.3/jac_client/examples/basic-full-stack/package.json +0 -28
  176. jac_client-0.2.3/jac_client/examples/basic-full-stack/vite.config.js +0 -27
  177. jac_client-0.2.3/jac_client/examples/css-styling/js-styling/.babelrc +0 -9
  178. jac_client-0.2.3/jac_client/examples/css-styling/js-styling/README.md +0 -183
  179. jac_client-0.2.3/jac_client/examples/css-styling/js-styling/package.json +0 -28
  180. jac_client-0.2.3/jac_client/examples/css-styling/js-styling/styles.js +0 -100
  181. jac_client-0.2.3/jac_client/examples/css-styling/js-styling/vite.config.js +0 -27
  182. jac_client-0.2.3/jac_client/examples/css-styling/material-ui/.babelrc +0 -9
  183. jac_client-0.2.3/jac_client/examples/css-styling/material-ui/README.md +0 -16
  184. jac_client-0.2.3/jac_client/examples/css-styling/material-ui/package.json +0 -32
  185. jac_client-0.2.3/jac_client/examples/css-styling/material-ui/vite.config.js +0 -27
  186. jac_client-0.2.3/jac_client/examples/css-styling/pure-css/.babelrc +0 -9
  187. jac_client-0.2.3/jac_client/examples/css-styling/pure-css/README.md +0 -16
  188. jac_client-0.2.3/jac_client/examples/css-styling/pure-css/package.json +0 -28
  189. jac_client-0.2.3/jac_client/examples/css-styling/pure-css/styles.css +0 -111
  190. jac_client-0.2.3/jac_client/examples/css-styling/pure-css/vite.config.js +0 -27
  191. jac_client-0.2.3/jac_client/examples/css-styling/sass-example/.babelrc +0 -9
  192. jac_client-0.2.3/jac_client/examples/css-styling/sass-example/README.md +0 -16
  193. jac_client-0.2.3/jac_client/examples/css-styling/sass-example/package.json +0 -29
  194. jac_client-0.2.3/jac_client/examples/css-styling/sass-example/styles.scss +0 -153
  195. jac_client-0.2.3/jac_client/examples/css-styling/sass-example/vite.config.js +0 -27
  196. jac_client-0.2.3/jac_client/examples/css-styling/styled-components/.babelrc +0 -9
  197. jac_client-0.2.3/jac_client/examples/css-styling/styled-components/README.md +0 -16
  198. jac_client-0.2.3/jac_client/examples/css-styling/styled-components/package.json +0 -29
  199. jac_client-0.2.3/jac_client/examples/css-styling/styled-components/styled.js +0 -90
  200. jac_client-0.2.3/jac_client/examples/css-styling/styled-components/vite.config.js +0 -27
  201. jac_client-0.2.3/jac_client/examples/css-styling/tailwind-example/.babelrc +0 -9
  202. jac_client-0.2.3/jac_client/examples/css-styling/tailwind-example/README.md +0 -16
  203. jac_client-0.2.3/jac_client/examples/css-styling/tailwind-example/global.css +0 -1
  204. jac_client-0.2.3/jac_client/examples/css-styling/tailwind-example/package.json +0 -30
  205. jac_client-0.2.3/jac_client/examples/css-styling/tailwind-example/vite.config.js +0 -29
  206. jac_client-0.2.3/jac_client/examples/full-stack-with-auth/.babelrc +0 -9
  207. jac_client-0.2.3/jac_client/examples/full-stack-with-auth/README.md +0 -16
  208. jac_client-0.2.3/jac_client/examples/full-stack-with-auth/package.json +0 -28
  209. jac_client-0.2.3/jac_client/examples/full-stack-with-auth/vite.config.js +0 -29
  210. jac_client-0.2.3/jac_client/examples/little-x/package.json +0 -23
  211. jac_client-0.2.3/jac_client/examples/little-x/submit-button.jac +0 -8
  212. jac_client-0.2.3/jac_client/examples/nested-folders/nested-advance/.babelrc +0 -9
  213. jac_client-0.2.3/jac_client/examples/nested-folders/nested-advance/README.md +0 -77
  214. jac_client-0.2.3/jac_client/examples/nested-folders/nested-advance/package.json +0 -29
  215. jac_client-0.2.3/jac_client/examples/nested-folders/nested-advance/vite.config.js +0 -28
  216. jac_client-0.2.3/jac_client/examples/nested-folders/nested-basic/.babelrc +0 -9
  217. jac_client-0.2.3/jac_client/examples/nested-folders/nested-basic/README.md +0 -183
  218. jac_client-0.2.3/jac_client/examples/nested-folders/nested-basic/app.js +0 -7
  219. jac_client-0.2.3/jac_client/examples/nested-folders/nested-basic/package.json +0 -28
  220. jac_client-0.2.3/jac_client/examples/nested-folders/nested-basic/vite.config.js +0 -27
  221. jac_client-0.2.3/jac_client/examples/with-router/.babelrc +0 -9
  222. jac_client-0.2.3/jac_client/examples/with-router/README.md +0 -17
  223. jac_client-0.2.3/jac_client/examples/with-router/package.json +0 -28
  224. jac_client-0.2.3/jac_client/examples/with-router/vite.config.js +0 -27
  225. jac_client-0.2.3/jac_client/plugin/cli.py +0 -244
  226. jac_client-0.2.3/jac_client/plugin/client.py +0 -152
  227. jac_client-0.2.3/jac_client/plugin/client_runtime.jac +0 -234
  228. jac_client-0.2.3/jac_client/plugin/vite_client_bundle.py +0 -503
  229. jac_client-0.2.3/jac_client/tests/fixtures/js_import/utils.js +0 -21
  230. jac_client-0.2.3/jac_client/tests/fixtures/package-lock.json +0 -329
  231. jac_client-0.2.3/jac_client/tests/fixtures/package.json +0 -11
  232. jac_client-0.2.3/jac_client/tests/test_asset_examples.py +0 -322
  233. jac_client-0.2.3/jac_client/tests/test_cl.py +0 -530
  234. jac_client-0.2.3/jac_client/tests/test_create_jac_app.py +0 -131
  235. jac_client-0.2.3/jac_client/tests/test_it.py +0 -329
  236. jac_client-0.2.3/jac_client/tests/test_nested_file.py +0 -374
  237. jac_client-0.2.3/pyproject.toml +0 -36
  238. {jac_client-0.2.3 → jac_client-0.2.9}/jac_client/tests/__init__.py +0 -0
  239. {jac_client-0.2.3 → jac_client-0.2.9}/jac_client/tests/fixtures/cl_file/app.jac +0 -0
  240. {jac_client-0.2.3 → jac_client-0.2.9}/jac_client/tests/fixtures/relative_import/app.jac +0 -0
  241. {jac_client-0.2.3/jac_client/examples/nested-folders/nested-basic/components → jac_client-0.2.9/jac_client/tests/fixtures/relative_import}/button.jac +0 -0
  242. {jac_client-0.2.3 → jac_client-0.2.9}/jac_client/tests/fixtures/test_fragments_spread/app.jac +0 -0
@@ -1,24 +1,20 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jac-client
3
- Version: 0.2.3
3
+ Version: 0.2.9
4
4
  Summary: Build full-stack web applications with Jac - one language for frontend and backend.
5
- License: MIT
6
- Keywords: jac,jaclang,jaseci,frontend,full-stack,web-development
7
- Author: Jason Mars
8
- Author-email: jason@mars.ninja
9
- Maintainer: Jason Mars
10
- Maintainer-email: jason@mars.ninja
11
- Requires-Python: >=3.12.0,<4.0.0
12
- Classifier: License :: OSI Approved :: MIT License
13
- Classifier: Programming Language :: Python :: 3
14
- Classifier: Programming Language :: Python :: 3.12
15
- Classifier: Programming Language :: Python :: 3.13
16
- Classifier: Programming Language :: Python :: 3.14
17
- Requires-Dist: jaclang (==0.9.3)
18
- Project-URL: Documentation, https://jac-lang.org
19
- Project-URL: Homepage, https://jaseci.org
5
+ Author-email: Jason Mars <jason@mars.ninja>
6
+ Maintainer-email: Jason Mars <jason@mars.ninja>
7
+ License-Expression: MIT
20
8
  Project-URL: Repository, https://github.com/Jaseci-Labs/jaseci
9
+ Project-URL: Homepage, https://jaseci.org
10
+ Project-URL: Documentation, https://jac-lang.org
11
+ Keywords: jac,jaclang,jaseci,frontend,full-stack,web-development
12
+ Requires-Python: >=3.12
21
13
  Description-Content-Type: text/markdown
14
+ Requires-Dist: jaclang>=0.9.9
15
+ Provides-Extra: dev
16
+ Requires-Dist: python-dotenv==1.0.1; extra == "dev"
17
+ Requires-Dist: pytest==8.3.5; extra == "dev"
22
18
 
23
19
  # Jac Client
24
20
 
@@ -28,11 +24,11 @@ Jac Client enables you to write React-like components, manage state, and build i
28
24
 
29
25
  ---
30
26
 
31
- ## Features
27
+ ## Features
32
28
 
33
29
  - **Single Language**: Write frontend and backend in Jac
34
30
  - **No HTTP Client**: Use `jacSpawn()` instead of fetch/axios
35
- - **React Hooks**: Use standard React `useState` and `useEffect` hooks
31
+ - **React Hooks**: Use standard React `useState` and `useEffect` hooks (useState is auto-injected when using `has` variables)
36
32
  - **Component-Based**: Build reusable UI components with JSX
37
33
  - **Graph Database**: Built-in graph data model eliminates need for SQL/NoSQL
38
34
  - **Type Safety**: Type checking across frontend and backend
@@ -40,7 +36,7 @@ Jac Client enables you to write React-like components, manage state, and build i
40
36
 
41
37
  ---
42
38
 
43
- ## 🚀 Quick Start
39
+ ## Quick Start
44
40
 
45
41
  ### Installation
46
42
 
@@ -51,16 +47,20 @@ pip install jac-client
51
47
  ### Create a New App
52
48
 
53
49
  ```bash
54
- jac create_jac_app my-app
50
+ jac create --use client my-app
55
51
  cd my-app
56
- jac serve app.jac
52
+ jac start src/app.jac
57
53
  ```
58
54
 
59
- Visit `http://localhost:8000/page/app` to see your app!
55
+ Visit `http://localhost:8000` to see your app! (The `app` component is served at the root by default.)
56
+
57
+ You can also access the app at `http://localhost:8000/cl/app`.
58
+
59
+ > **Note**: The `--npm` flag creates a client-side project with an organized folder structure. Without `--npm`, `jac create` creates a standard Jac project.
60
60
 
61
61
  ---
62
62
 
63
- ## 📚 Documentation
63
+ ## Documentation
64
64
 
65
65
  For detailed guides and tutorials, see the **[docs folder](jac_client/docs/)**:
66
66
 
@@ -72,16 +72,19 @@ For detailed guides and tutorials, see the **[docs folder](jac_client/docs/)**:
72
72
 
73
73
  ---
74
74
 
75
- ## 💡 Example
75
+ ## Example
76
76
 
77
77
  ### Simple Counter with React Hooks
78
78
 
79
79
  ```jac
80
- cl import from react { useState, useEffect }
80
+ # Note: useState is auto-injected when using has variables in cl blocks
81
+ # Only useEffect needs explicit import
82
+ cl import from react { useEffect }
81
83
 
82
84
  cl {
83
85
  def Counter() -> any {
84
- let [count, setCount] = useState(0);
86
+ # useState is automatically available - no import needed!
87
+ [count, setCount] = useState(0);
85
88
 
86
89
  useEffect(lambda -> None {
87
90
  console.log("Count changed:", count);
@@ -103,10 +106,13 @@ cl {
103
106
  }
104
107
  ```
105
108
 
109
+ > **Note:** When using `has` variables in `cl {}` blocks or `.cl.jac` files, the `useState` import is automatically injected. You only need to explicitly import other hooks like `useEffect`.
110
+
106
111
  ### Full-Stack Todo App
107
112
 
108
113
  ```jac
109
- cl import from react { useState, useEffect }
114
+ # useState is auto-injected, only import useEffect
115
+ cl import from react { useEffect }
110
116
  cl import from '@jac-client/utils' { jacSpawn }
111
117
 
112
118
  # Backend: Jac nodes and walkers
@@ -132,7 +138,8 @@ walker read_todos {
132
138
  # Frontend: React component
133
139
  cl {
134
140
  def app() -> any {
135
- let [todos, setTodos] = useState([]);
141
+ # useState is automatically available - no import needed!
142
+ [todos, setTodos] = useState([]);
136
143
 
137
144
  useEffect(lambda -> None {
138
145
  async def loadTodos() -> None {
@@ -154,7 +161,7 @@ cl {
154
161
 
155
162
  ---
156
163
 
157
- ## 🔧 Requirements
164
+ ## Requirements
158
165
 
159
166
  - Python: 3.12+
160
167
  - Node.js: For npm and Vite
@@ -162,9 +169,10 @@ cl {
162
169
 
163
170
  ---
164
171
 
165
- ## 🛠️ How It Works
172
+ ## How It Works
166
173
 
167
174
  Jac Client is a plugin that:
175
+
168
176
  1. Compiles your `.jac` client code to JavaScript
169
177
  2. Bundles dependencies with Vite for optimal performance
170
178
  3. Provides a runtime for reactive state and components
@@ -172,7 +180,7 @@ Jac Client is a plugin that:
172
180
 
173
181
  ---
174
182
 
175
- ## 📖 Learn More
183
+ ## Learn More
176
184
 
177
185
  - **Full Documentation**: See [docs/](jac_client/docs/) for comprehensive guides
178
186
  - **Examples**: Check `jac_client/examples/` for working examples
@@ -180,11 +188,10 @@ Jac Client is a plugin that:
180
188
 
181
189
  ---
182
190
 
183
- ## 📄 License
191
+ ## License
184
192
 
185
193
  MIT License - see [LICENSE](../LICENSE) file.
186
194
 
187
195
  ---
188
196
 
189
- **Happy coding with Jac!** 🎉
190
-
197
+ **Happy coding with Jac!**
@@ -6,11 +6,11 @@ Jac Client enables you to write React-like components, manage state, and build i
6
6
 
7
7
  ---
8
8
 
9
- ## Features
9
+ ## Features
10
10
 
11
11
  - **Single Language**: Write frontend and backend in Jac
12
12
  - **No HTTP Client**: Use `jacSpawn()` instead of fetch/axios
13
- - **React Hooks**: Use standard React `useState` and `useEffect` hooks
13
+ - **React Hooks**: Use standard React `useState` and `useEffect` hooks (useState is auto-injected when using `has` variables)
14
14
  - **Component-Based**: Build reusable UI components with JSX
15
15
  - **Graph Database**: Built-in graph data model eliminates need for SQL/NoSQL
16
16
  - **Type Safety**: Type checking across frontend and backend
@@ -18,7 +18,7 @@ Jac Client enables you to write React-like components, manage state, and build i
18
18
 
19
19
  ---
20
20
 
21
- ## 🚀 Quick Start
21
+ ## Quick Start
22
22
 
23
23
  ### Installation
24
24
 
@@ -29,16 +29,20 @@ pip install jac-client
29
29
  ### Create a New App
30
30
 
31
31
  ```bash
32
- jac create_jac_app my-app
32
+ jac create --use client my-app
33
33
  cd my-app
34
- jac serve app.jac
34
+ jac start src/app.jac
35
35
  ```
36
36
 
37
- Visit `http://localhost:8000/page/app` to see your app!
37
+ Visit `http://localhost:8000` to see your app! (The `app` component is served at the root by default.)
38
+
39
+ You can also access the app at `http://localhost:8000/cl/app`.
40
+
41
+ > **Note**: The `--npm` flag creates a client-side project with an organized folder structure. Without `--npm`, `jac create` creates a standard Jac project.
38
42
 
39
43
  ---
40
44
 
41
- ## 📚 Documentation
45
+ ## Documentation
42
46
 
43
47
  For detailed guides and tutorials, see the **[docs folder](jac_client/docs/)**:
44
48
 
@@ -50,16 +54,19 @@ For detailed guides and tutorials, see the **[docs folder](jac_client/docs/)**:
50
54
 
51
55
  ---
52
56
 
53
- ## 💡 Example
57
+ ## Example
54
58
 
55
59
  ### Simple Counter with React Hooks
56
60
 
57
61
  ```jac
58
- cl import from react { useState, useEffect }
62
+ # Note: useState is auto-injected when using has variables in cl blocks
63
+ # Only useEffect needs explicit import
64
+ cl import from react { useEffect }
59
65
 
60
66
  cl {
61
67
  def Counter() -> any {
62
- let [count, setCount] = useState(0);
68
+ # useState is automatically available - no import needed!
69
+ [count, setCount] = useState(0);
63
70
 
64
71
  useEffect(lambda -> None {
65
72
  console.log("Count changed:", count);
@@ -81,10 +88,13 @@ cl {
81
88
  }
82
89
  ```
83
90
 
91
+ > **Note:** When using `has` variables in `cl {}` blocks or `.cl.jac` files, the `useState` import is automatically injected. You only need to explicitly import other hooks like `useEffect`.
92
+
84
93
  ### Full-Stack Todo App
85
94
 
86
95
  ```jac
87
- cl import from react { useState, useEffect }
96
+ # useState is auto-injected, only import useEffect
97
+ cl import from react { useEffect }
88
98
  cl import from '@jac-client/utils' { jacSpawn }
89
99
 
90
100
  # Backend: Jac nodes and walkers
@@ -110,7 +120,8 @@ walker read_todos {
110
120
  # Frontend: React component
111
121
  cl {
112
122
  def app() -> any {
113
- let [todos, setTodos] = useState([]);
123
+ # useState is automatically available - no import needed!
124
+ [todos, setTodos] = useState([]);
114
125
 
115
126
  useEffect(lambda -> None {
116
127
  async def loadTodos() -> None {
@@ -132,7 +143,7 @@ cl {
132
143
 
133
144
  ---
134
145
 
135
- ## 🔧 Requirements
146
+ ## Requirements
136
147
 
137
148
  - Python: 3.12+
138
149
  - Node.js: For npm and Vite
@@ -140,9 +151,10 @@ cl {
140
151
 
141
152
  ---
142
153
 
143
- ## 🛠️ How It Works
154
+ ## How It Works
144
155
 
145
156
  Jac Client is a plugin that:
157
+
146
158
  1. Compiles your `.jac` client code to JavaScript
147
159
  2. Bundles dependencies with Vite for optimal performance
148
160
  3. Provides a runtime for reactive state and components
@@ -150,7 +162,7 @@ Jac Client is a plugin that:
150
162
 
151
163
  ---
152
164
 
153
- ## 📖 Learn More
165
+ ## Learn More
154
166
 
155
167
  - **Full Documentation**: See [docs/](jac_client/docs/) for comprehensive guides
156
168
  - **Examples**: Check `jac_client/examples/` for working examples
@@ -158,10 +170,10 @@ Jac Client is a plugin that:
158
170
 
159
171
  ---
160
172
 
161
- ## 📄 License
173
+ ## License
162
174
 
163
175
  MIT License - see [LICENSE](../LICENSE) file.
164
176
 
165
177
  ---
166
178
 
167
- **Happy coding with Jac!** 🎉
179
+ **Happy coding with Jac!**
@@ -0,0 +1,5 @@
1
+ # worker.py
2
+
3
+
4
+ def handle_message() -> str:
5
+ return "✓ Message processed by Python Worker | Successfully handled by worker.py"
@@ -1,6 +1,6 @@
1
1
  cl import from antd { Button }
2
2
 
3
- cl def CustomButtonRoot() -> any {
3
+ cl def:pub CustomButtonRoot -> any {
4
4
  return <Button>
5
5
  Root Button
6
6
  </Button>;
@@ -0,0 +1,35 @@
1
+ # Category filter component
2
+ # Demonstrates: iteration with map, conditional classes, events
3
+
4
+ cl import from ..constants.categories { CATEGORIES, CATEGORY_LABELS, CATEGORY_COLORS }
5
+
6
+ cl {
7
+ # Filter buttons for categories
8
+ def:pub CategoryFilter(selectedCategory: str, onSelect: any) -> any {
9
+ # Add "ALL" to the beginning of categories
10
+ allCategories = ["ALL"].concat(CATEGORIES);
11
+
12
+ return <div className="category-filter">
13
+ <h3 className="filter-title">Filter by Category</h3>
14
+ <div className="filter-buttons">
15
+ {allCategories.map(lambda cat: str -> any {
16
+ isActive = selectedCategory == cat;
17
+ color = CATEGORY_COLORS[cat] if cat != "ALL" else "#374151";
18
+
19
+ return <button
20
+ key={cat}
21
+ className={("filter-btn active") if isActive else ("filter-btn")}
22
+ style={{
23
+ "borderColor": color,
24
+ "backgroundColor": (color) if isActive else ("transparent"),
25
+ "color": ("#fff") if isActive else (color)
26
+ }}
27
+ onClick={lambda: onSelect(cat)}
28
+ >
29
+ {(cat) if cat == "ALL" else (CATEGORY_LABELS[cat])}
30
+ </button>;
31
+ })}
32
+ </div>
33
+ </div>;
34
+ }
35
+ }
@@ -0,0 +1,13 @@
1
+ # Header component
2
+ # Demonstrates: simple component, CSS classes
3
+
4
+ cl {
5
+ def:pub Header() -> any {
6
+ return <header className="header">
7
+ <div className="header-content">
8
+ <h1 className="header-title">Budget Planner</h1>
9
+ <p className="header-subtitle">Track your income and expenses</p>
10
+ </div>
11
+ </header>;
12
+ }
13
+ }
@@ -0,0 +1,50 @@
1
+ # Profit Overview component - monthly profit snapshot
2
+ # Demonstrates: context usage, calculated displays, formatting
3
+
4
+ cl import from ..context.BudgetContext { useBudgetContext }
5
+ cl import from ..utils.formatters { formatCurrency }
6
+
7
+ cl {
8
+ def:pub ProfitOverview() -> any {
9
+ budget = useBudgetContext();
10
+
11
+ businessIncome = budget["businessIncome"];
12
+ businessExpenses = budget["businessExpenses"];
13
+ taxReserve = budget["taxReserve"];
14
+ netProfit = budget["netProfit"];
15
+
16
+ return <div className="profit-overview">
17
+ <h3 className="profit-title">Monthly Profit Snapshot</h3>
18
+
19
+ <div className="profit-breakdown">
20
+ <div className="profit-row income">
21
+ <span className="profit-label">Business Income</span>
22
+ <span className="profit-value positive">
23
+ +{formatCurrency(businessIncome)}
24
+ </span>
25
+ </div>
26
+
27
+ <div className="profit-row expense">
28
+ <span className="profit-label">Business Expenses</span>
29
+ <span className="profit-value negative">
30
+ -{formatCurrency(businessExpenses)}
31
+ </span>
32
+ </div>
33
+
34
+ <div className="profit-row tax">
35
+ <span className="profit-label">Tax Reserve (20%)</span>
36
+ <span className="profit-value negative">
37
+ -{formatCurrency(taxReserve)}
38
+ </span>
39
+ </div>
40
+
41
+ <div className="profit-row total">
42
+ <span className="profit-label">Net Profit</span>
43
+ <span className={("profit-value bold positive") if netProfit >= 0 else ("profit-value bold negative")}>
44
+ {("+") if netProfit > 0 else ("")}{formatCurrency(netProfit)}
45
+ </span>
46
+ </div>
47
+ </div>
48
+ </div>;
49
+ }
50
+ }
@@ -0,0 +1,53 @@
1
+ # Summary component - displays budget totals with business/personal breakdown
2
+ # Demonstrates: context usage, conditional rendering, ternary operator, 6-card layout
3
+
4
+ cl import from ..context.BudgetContext { useBudgetContext }
5
+ cl import from ..utils.formatters { formatCurrency }
6
+
7
+ cl {
8
+ def:pub Summary() -> any {
9
+ budget = useBudgetContext();
10
+
11
+ # Business/Personal breakdown
12
+ businessIncome = budget["businessIncome"];
13
+ businessExpenses = budget["businessExpenses"];
14
+ personalIncome = budget["personalIncome"];
15
+ personalExpenses = budget["personalExpenses"];
16
+ taxReserve = budget["taxReserve"];
17
+ netProfit = budget["netProfit"];
18
+
19
+ return <div className="summary">
20
+ <div className="summary-card business-income">
21
+ <span className="summary-label">Business Income</span>
22
+ <span className="summary-value">{formatCurrency(businessIncome)}</span>
23
+ </div>
24
+
25
+ <div className="summary-card business-expenses">
26
+ <span className="summary-label">Business Expenses</span>
27
+ <span className="summary-value">{formatCurrency(businessExpenses)}</span>
28
+ </div>
29
+
30
+ <div className="summary-card personal-income">
31
+ <span className="summary-label">Personal Income</span>
32
+ <span className="summary-value">{formatCurrency(personalIncome)}</span>
33
+ </div>
34
+
35
+ <div className="summary-card personal-expenses">
36
+ <span className="summary-label">Personal Expenses</span>
37
+ <span className="summary-value">{formatCurrency(personalExpenses)}</span>
38
+ </div>
39
+
40
+ <div className="summary-card tax-reserve">
41
+ <span className="summary-label">Tax Reserve (20%)</span>
42
+ <span className="summary-value">{formatCurrency(taxReserve)}</span>
43
+ </div>
44
+
45
+ <div className={("summary-card net-profit positive") if netProfit >= 0 else ("summary-card net-profit negative")}>
46
+ <span className="summary-label">Net Profit</span>
47
+ <span className="summary-value">
48
+ {("+") if netProfit > 0 else ("")}{formatCurrency(netProfit)}
49
+ </span>
50
+ </div>
51
+ </div>;
52
+ }
53
+ }
@@ -0,0 +1,158 @@
1
+ # Transaction form component
2
+ # Demonstrates: form handling, useState, events, select options
3
+
4
+ cl import from ..context.BudgetContext { useBudgetContext }
5
+ cl import from ..constants.categories { CATEGORIES, CATEGORY_LABELS }
6
+ cl import from ..constants.clients { CLIENTS }
7
+
8
+ cl {
9
+ def:pub TransactionForm() -> any {
10
+ [description, setDescription] = useState("");
11
+ [amount, setAmount] = useState("");
12
+ [category, setCategory] = useState("OTHER");
13
+ [txType, setTxType] = useState("expense");
14
+ [isBusiness, setIsBusiness] = useState(false);
15
+ [clientName, setClientName] = useState("");
16
+ budget = useBudgetContext();
17
+
18
+ def handleSubmit(e: any) -> None {
19
+ e.preventDefault();
20
+
21
+ # Validate inputs
22
+ trimmedDesc = description.trim();
23
+ if trimmedDesc == "" or amount == "" {
24
+ return;
25
+ }
26
+
27
+ parsedAmount = parseFloat(amount);
28
+ if isNaN(parsedAmount) or parsedAmount <= 0 {
29
+ return;
30
+ }
31
+
32
+ # Add the transaction
33
+ budget["addTransaction"](trimmedDesc, parsedAmount, category, txType, isBusiness, clientName);
34
+
35
+ # Reset form
36
+ setDescription("");
37
+ setAmount("");
38
+ setCategory("OTHER");
39
+ setIsBusiness(false);
40
+ setClientName("");
41
+ }
42
+
43
+ # Filter categories based on type (income only has INCOME category)
44
+ availableCategories = CATEGORIES.filter(lambda cat: str -> bool {
45
+ if txType == "income" {
46
+ return cat == "INCOME";
47
+ }
48
+ return cat != "INCOME";
49
+ });
50
+
51
+ # Show client dropdown only for business income
52
+ showClientDropdown = (txType == "income" and isBusiness);
53
+
54
+ return <form className="transaction-form" onSubmit={handleSubmit}>
55
+ <div className="form-row">
56
+ <div className="form-group type-toggle">
57
+ <button
58
+ type="button"
59
+ className={("toggle-btn active") if txType == "expense" else ("toggle-btn")}
60
+ onClick={lambda: setTxType("expense")}
61
+ >
62
+ Expense
63
+ </button>
64
+ <button
65
+ type="button"
66
+ className={("toggle-btn active income") if txType == "income" else ("toggle-btn")}
67
+ onClick={lambda: setTxType("income")}
68
+ >
69
+ Income
70
+ </button>
71
+ </div>
72
+
73
+ <div className="form-group business-toggle">
74
+ <button
75
+ type="button"
76
+ className={("toggle-btn active") if isBusiness else ("toggle-btn")}
77
+ onClick={lambda: setIsBusiness(true)}
78
+ >
79
+ Business
80
+ </button>
81
+ <button
82
+ type="button"
83
+ className={("toggle-btn active") if not isBusiness else ("toggle-btn")}
84
+ onClick={lambda: setIsBusiness(false)}
85
+ >
86
+ Personal
87
+ </button>
88
+ </div>
89
+ </div>
90
+
91
+ <div className="form-row">
92
+ <div className="form-group">
93
+ <label htmlFor="description">Description</label>
94
+ <input
95
+ id="description"
96
+ type="text"
97
+ value={description}
98
+ onChange={lambda e: any -> None { setDescription(e.target.value); }}
99
+ placeholder="Enter description..."
100
+ className="form-input"
101
+ />
102
+ </div>
103
+
104
+ <div className="form-group">
105
+ <label htmlFor="amount">Amount</label>
106
+ <input
107
+ id="amount"
108
+ type="number"
109
+ value={amount}
110
+ onChange={lambda e: any -> None { setAmount(e.target.value); }}
111
+ placeholder="0.00"
112
+ min="0"
113
+ step="0.01"
114
+ className="form-input"
115
+ />
116
+ </div>
117
+
118
+ <div className="form-group">
119
+ <label htmlFor="category">Category</label>
120
+ <select
121
+ id="category"
122
+ value={category}
123
+ onChange={lambda e: any -> None { setCategory(e.target.value); }}
124
+ className="form-select"
125
+ >
126
+ {availableCategories.map(lambda cat: str -> any {
127
+ return <option key={cat} value={cat}>
128
+ {CATEGORY_LABELS[cat]}
129
+ </option>;
130
+ })}
131
+ </select>
132
+ </div>
133
+
134
+ {showClientDropdown and <div className="form-group">
135
+ <label htmlFor="client">Client</label>
136
+ <select
137
+ id="client"
138
+ value={clientName}
139
+ onChange={lambda e: any -> None { setClientName(e.target.value); }}
140
+ className="form-select"
141
+ >
142
+ <option value="">Select Client (Optional)</option>
143
+ {CLIENTS.map(lambda client: str -> any {
144
+ return <option key={client} value={client}>{client}</option>;
145
+ })}
146
+ </select>
147
+ </div>}
148
+
149
+ <div className="form-group">
150
+ <label>Action</label>
151
+ <button type="submit" className="submit-btn">
152
+ Add {(txType[0].toUpperCase() + txType.slice(1))}
153
+ </button>
154
+ </div>
155
+ </div>
156
+ </form>;
157
+ }
158
+ }