@bgroup/wise-form 1.0.1

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 (319) hide show
  1. package/README.md +34 -0
  2. package/dist/components/ui/Checkbox.d.ts +14 -0
  3. package/dist/components/ui/Checkbox.d.ts.map +1 -0
  4. package/dist/components/ui/Checkbox.js +43 -0
  5. package/dist/components/ui/Checkbox.js.map +1 -0
  6. package/dist/components/ui/CheckboxGroup.d.ts +15 -0
  7. package/dist/components/ui/CheckboxGroup.d.ts.map +1 -0
  8. package/dist/components/ui/CheckboxGroup.js +33 -0
  9. package/dist/components/ui/CheckboxGroup.js.map +1 -0
  10. package/dist/components/ui/Input.d.ts +14 -0
  11. package/dist/components/ui/Input.d.ts.map +1 -0
  12. package/dist/components/ui/Input.js +49 -0
  13. package/dist/components/ui/Input.js.map +1 -0
  14. package/dist/components/ui/Radio.d.ts +14 -0
  15. package/dist/components/ui/Radio.d.ts.map +1 -0
  16. package/dist/components/ui/Radio.js +43 -0
  17. package/dist/components/ui/Radio.js.map +1 -0
  18. package/dist/components/ui/Select.d.ts +18 -0
  19. package/dist/components/ui/Select.d.ts.map +1 -0
  20. package/dist/components/ui/Select.js +44 -0
  21. package/dist/components/ui/Select.js.map +1 -0
  22. package/dist/components/ui/Textarea.d.ts +13 -0
  23. package/dist/components/ui/Textarea.d.ts.map +1 -0
  24. package/dist/components/ui/Textarea.js +42 -0
  25. package/dist/components/ui/Textarea.js.map +1 -0
  26. package/dist/components/ui/index.d.ts +13 -0
  27. package/dist/components/ui/index.d.ts.map +1 -0
  28. package/dist/components/ui/index.js +7 -0
  29. package/dist/components/ui/index.js.map +1 -0
  30. package/dist/form/index.d.ts +10 -0
  31. package/dist/form/index.d.ts.map +1 -0
  32. package/dist/form/index.js +5 -0
  33. package/dist/form/index.js.map +1 -0
  34. package/dist/form/interfaces/field-container.d.ts +8 -0
  35. package/dist/form/interfaces/field-container.d.ts.map +1 -0
  36. package/dist/form/interfaces/field-container.js +2 -0
  37. package/dist/form/interfaces/field-container.js.map +1 -0
  38. package/dist/form/interfaces/interfaces.d.ts +8 -0
  39. package/dist/form/interfaces/interfaces.d.ts.map +1 -0
  40. package/dist/form/interfaces/interfaces.js +2 -0
  41. package/dist/form/interfaces/interfaces.js.map +1 -0
  42. package/dist/form/interfaces/settings.d.ts +10 -0
  43. package/dist/form/interfaces/settings.d.ts.map +1 -0
  44. package/dist/form/interfaces/settings.js +2 -0
  45. package/dist/form/interfaces/settings.js.map +1 -0
  46. package/dist/form/interfaces/template.d.ts +6 -0
  47. package/dist/form/interfaces/template.d.ts.map +1 -0
  48. package/dist/form/interfaces/template.js +2 -0
  49. package/dist/form/interfaces/template.js.map +1 -0
  50. package/dist/form/interfaces/wise-form-specs.d.ts +9 -0
  51. package/dist/form/interfaces/wise-form-specs.d.ts.map +1 -0
  52. package/dist/form/interfaces/wise-form-specs.js +2 -0
  53. package/dist/form/interfaces/wise-form-specs.js.map +1 -0
  54. package/dist/form/view/components/containers/index.d.ts +3 -0
  55. package/dist/form/view/components/containers/index.d.ts.map +1 -0
  56. package/dist/form/view/components/containers/index.js +12 -0
  57. package/dist/form/view/components/containers/index.js.map +1 -0
  58. package/dist/form/view/components/error.d.ts +5 -0
  59. package/dist/form/view/components/error.d.ts.map +1 -0
  60. package/dist/form/view/components/error.js +8 -0
  61. package/dist/form/view/components/error.js.map +1 -0
  62. package/dist/form/view/components/field/container.d.ts +5 -0
  63. package/dist/form/view/components/field/container.d.ts.map +1 -0
  64. package/dist/form/view/components/field/container.js +5 -0
  65. package/dist/form/view/components/field/container.js.map +1 -0
  66. package/dist/form/view/components/field/index.d.ts +18 -0
  67. package/dist/form/view/components/field/index.d.ts.map +1 -0
  68. package/dist/form/view/components/field/index.js +89 -0
  69. package/dist/form/view/components/field/index.js.map +1 -0
  70. package/dist/form/view/components/field/selection.d.ts +2 -0
  71. package/dist/form/view/components/field/selection.d.ts.map +1 -0
  72. package/dist/form/view/components/field/selection.js +35 -0
  73. package/dist/form/view/components/field/selection.js.map +1 -0
  74. package/dist/form/view/components/field/use-field.d.ts +4 -0
  75. package/dist/form/view/components/field/use-field.d.ts.map +1 -0
  76. package/dist/form/view/components/field/use-field.js +41 -0
  77. package/dist/form/view/components/field/use-field.js.map +1 -0
  78. package/dist/form/view/components/rows/row-container.d.ts +18 -0
  79. package/dist/form/view/components/rows/row-container.d.ts.map +1 -0
  80. package/dist/form/view/components/rows/row-container.js +89 -0
  81. package/dist/form/view/components/rows/row-container.js.map +1 -0
  82. package/dist/form/view/components/rows/wrapper.d.ts +12 -0
  83. package/dist/form/view/components/rows/wrapper.d.ts.map +1 -0
  84. package/dist/form/view/components/rows/wrapper.js +27 -0
  85. package/dist/form/view/components/rows/wrapper.js.map +1 -0
  86. package/dist/form/view/components/wrapped-form.d.ts +6 -0
  87. package/dist/form/view/components/wrapped-form.d.ts.map +1 -0
  88. package/dist/form/view/components/wrapped-form.js +26 -0
  89. package/dist/form/view/components/wrapped-form.js.map +1 -0
  90. package/dist/form/view/context.d.ts +23 -0
  91. package/dist/form/view/context.d.ts.map +1 -0
  92. package/dist/form/view/context.js +7 -0
  93. package/dist/form/view/context.js.map +1 -0
  94. package/dist/form/view/hooks/use-model.d.ts +10 -0
  95. package/dist/form/view/hooks/use-model.d.ts.map +1 -0
  96. package/dist/form/view/hooks/use-model.js +31 -0
  97. package/dist/form/view/hooks/use-model.js.map +1 -0
  98. package/dist/form/view/hooks/use-template.d.ts +14 -0
  99. package/dist/form/view/hooks/use-template.d.ts.map +1 -0
  100. package/dist/form/view/hooks/use-template.js +57 -0
  101. package/dist/form/view/hooks/use-template.js.map +1 -0
  102. package/dist/form/view/hooks/use-types.d.ts +2 -0
  103. package/dist/form/view/hooks/use-types.d.ts.map +1 -0
  104. package/dist/form/view/hooks/use-types.js +19 -0
  105. package/dist/form/view/hooks/use-types.js.map +1 -0
  106. package/dist/form/view/index.d.ts +3 -0
  107. package/dist/form/view/index.d.ts.map +1 -0
  108. package/dist/form/view/index.js +38 -0
  109. package/dist/form/view/index.js.map +1 -0
  110. package/dist/formulas/helpers/condition-types.d.ts +5 -0
  111. package/dist/formulas/helpers/condition-types.d.ts.map +1 -0
  112. package/dist/formulas/helpers/condition-types.js +5 -0
  113. package/dist/formulas/helpers/condition-types.js.map +1 -0
  114. package/dist/formulas/helpers/evaluations.d.ts +15 -0
  115. package/dist/formulas/helpers/evaluations.d.ts.map +1 -0
  116. package/dist/formulas/helpers/evaluations.js +44 -0
  117. package/dist/formulas/helpers/evaluations.js.map +1 -0
  118. package/dist/formulas/helpers/formula.d.ts +6 -0
  119. package/dist/formulas/helpers/formula.d.ts.map +1 -0
  120. package/dist/formulas/helpers/formula.js +26 -0
  121. package/dist/formulas/helpers/formula.js.map +1 -0
  122. package/dist/formulas/helpers/lexer.d.ts +10 -0
  123. package/dist/formulas/helpers/lexer.d.ts.map +1 -0
  124. package/dist/formulas/helpers/lexer.js +73 -0
  125. package/dist/formulas/helpers/lexer.js.map +1 -0
  126. package/dist/formulas/helpers/parser.d.ts +24 -0
  127. package/dist/formulas/helpers/parser.d.ts.map +1 -0
  128. package/dist/formulas/helpers/parser.js +48 -0
  129. package/dist/formulas/helpers/parser.js.map +1 -0
  130. package/dist/formulas/helpers/token.d.ts +14 -0
  131. package/dist/formulas/helpers/token.d.ts.map +1 -0
  132. package/dist/formulas/helpers/token.js +14 -0
  133. package/dist/formulas/helpers/token.js.map +1 -0
  134. package/dist/formulas/index.d.ts +59 -0
  135. package/dist/formulas/index.d.ts.map +1 -0
  136. package/dist/formulas/index.js +186 -0
  137. package/dist/formulas/index.js.map +1 -0
  138. package/dist/formulas/types/formulas.d.ts +68 -0
  139. package/dist/formulas/types/formulas.d.ts.map +1 -0
  140. package/dist/formulas/types/formulas.js +2 -0
  141. package/dist/formulas/types/formulas.js.map +1 -0
  142. package/dist/formulas/types/index.d.ts +5 -0
  143. package/dist/formulas/types/index.d.ts.map +1 -0
  144. package/dist/formulas/types/index.js +2 -0
  145. package/dist/formulas/types/index.js.map +1 -0
  146. package/dist/formulas/variants/array-formula.d.ts +24 -0
  147. package/dist/formulas/variants/array-formula.d.ts.map +1 -0
  148. package/dist/formulas/variants/array-formula.js +142 -0
  149. package/dist/formulas/variants/array-formula.js.map +1 -0
  150. package/dist/formulas/variants/base.d.ts +6 -0
  151. package/dist/formulas/variants/base.d.ts.map +1 -0
  152. package/dist/formulas/variants/base.js +3 -0
  153. package/dist/formulas/variants/base.js.map +1 -0
  154. package/dist/formulas/variants/basic.d.ts +18 -0
  155. package/dist/formulas/variants/basic.d.ts.map +1 -0
  156. package/dist/formulas/variants/basic.js +128 -0
  157. package/dist/formulas/variants/basic.js.map +1 -0
  158. package/dist/formulas/variants/comparison.d.ts +25 -0
  159. package/dist/formulas/variants/comparison.d.ts.map +1 -0
  160. package/dist/formulas/variants/comparison.js +153 -0
  161. package/dist/formulas/variants/comparison.js.map +1 -0
  162. package/dist/formulas/variants/conditional.d.ts +18 -0
  163. package/dist/formulas/variants/conditional.d.ts.map +1 -0
  164. package/dist/formulas/variants/conditional.js +183 -0
  165. package/dist/formulas/variants/conditional.js.map +1 -0
  166. package/dist/formulas/variants/iterative-array.d.ts +20 -0
  167. package/dist/formulas/variants/iterative-array.d.ts.map +1 -0
  168. package/dist/formulas/variants/iterative-array.js +155 -0
  169. package/dist/formulas/variants/iterative-array.js.map +1 -0
  170. package/dist/formulas/variants/per-value.d.ts +20 -0
  171. package/dist/formulas/variants/per-value.d.ts.map +1 -0
  172. package/dist/formulas/variants/per-value.js +154 -0
  173. package/dist/formulas/variants/per-value.js.map +1 -0
  174. package/dist/index.d.ts +5 -0
  175. package/dist/index.d.ts.map +1 -0
  176. package/dist/index.js +6 -0
  177. package/dist/index.js.map +1 -0
  178. package/dist/models/base.d.ts +55 -0
  179. package/dist/models/base.d.ts.map +1 -0
  180. package/dist/models/base.js +146 -0
  181. package/dist/models/base.js.map +1 -0
  182. package/dist/models/callback-manager.d.ts +7 -0
  183. package/dist/models/callback-manager.d.ts.map +1 -0
  184. package/dist/models/callback-manager.js +89 -0
  185. package/dist/models/callback-manager.js.map +1 -0
  186. package/dist/models/field.d.ts +121 -0
  187. package/dist/models/field.d.ts.map +1 -0
  188. package/dist/models/field.js +374 -0
  189. package/dist/models/field.js.map +1 -0
  190. package/dist/models/index.d.ts +13 -0
  191. package/dist/models/index.d.ts.map +1 -0
  192. package/dist/models/index.js +7 -0
  193. package/dist/models/index.js.map +1 -0
  194. package/dist/models/model.d.ts +37 -0
  195. package/dist/models/model.d.ts.map +1 -0
  196. package/dist/models/model.js +245 -0
  197. package/dist/models/model.js.map +1 -0
  198. package/dist/models/plugins/base.d.ts +9 -0
  199. package/dist/models/plugins/base.d.ts.map +1 -0
  200. package/dist/models/plugins/base.js +3 -0
  201. package/dist/models/plugins/base.js.map +1 -0
  202. package/dist/models/plugins/formula.d.ts +18 -0
  203. package/dist/models/plugins/formula.d.ts.map +1 -0
  204. package/dist/models/plugins/formula.js +82 -0
  205. package/dist/models/plugins/formula.js.map +1 -0
  206. package/dist/models/plugins/index.d.ts +11 -0
  207. package/dist/models/plugins/index.d.ts.map +1 -0
  208. package/dist/models/plugins/index.js +52 -0
  209. package/dist/models/plugins/index.js.map +1 -0
  210. package/dist/models/plugins/plugins.d.ts +7 -0
  211. package/dist/models/plugins/plugins.d.ts.map +1 -0
  212. package/dist/models/plugins/plugins.js +7 -0
  213. package/dist/models/plugins/plugins.js.map +1 -0
  214. package/dist/models/types/base-wise-model.d.ts +7 -0
  215. package/dist/models/types/base-wise-model.d.ts.map +1 -0
  216. package/dist/models/types/base-wise-model.js +2 -0
  217. package/dist/models/types/base-wise-model.js.map +1 -0
  218. package/dist/models/types/callbacks.d.ts +19 -0
  219. package/dist/models/types/callbacks.d.ts.map +1 -0
  220. package/dist/models/types/callbacks.js +2 -0
  221. package/dist/models/types/callbacks.js.map +1 -0
  222. package/dist/models/types/disabled.d.ts +8 -0
  223. package/dist/models/types/disabled.d.ts.map +1 -0
  224. package/dist/models/types/disabled.js +2 -0
  225. package/dist/models/types/disabled.js.map +1 -0
  226. package/dist/models/types/form-field.d.ts +25 -0
  227. package/dist/models/types/form-field.d.ts.map +1 -0
  228. package/dist/models/types/form-field.js +2 -0
  229. package/dist/models/types/form-field.js.map +1 -0
  230. package/dist/models/types/model.d.ts +13 -0
  231. package/dist/models/types/model.d.ts.map +1 -0
  232. package/dist/models/types/model.js +2 -0
  233. package/dist/models/types/model.js.map +1 -0
  234. package/dist/models/types/plugins.d.ts +13 -0
  235. package/dist/models/types/plugins.d.ts.map +1 -0
  236. package/dist/models/types/plugins.js +2 -0
  237. package/dist/models/types/plugins.js.map +1 -0
  238. package/dist/models/types/wrapped-form-model-props.d.ts +11 -0
  239. package/dist/models/types/wrapped-form-model-props.d.ts.map +1 -0
  240. package/dist/models/types/wrapped-form-model-props.js +2 -0
  241. package/dist/models/types/wrapped-form-model-props.js.map +1 -0
  242. package/dist/models/wrapper.d.ts +30 -0
  243. package/dist/models/wrapper.d.ts.map +1 -0
  244. package/dist/models/wrapper.js +213 -0
  245. package/dist/models/wrapper.js.map +1 -0
  246. package/dist/settings/index.d.ts +7 -0
  247. package/dist/settings/index.d.ts.map +1 -0
  248. package/dist/settings/index.js +26 -0
  249. package/dist/settings/index.js.map +1 -0
  250. package/dist/utils/pending-promise.d.ts +6 -0
  251. package/dist/utils/pending-promise.d.ts.map +1 -0
  252. package/dist/utils/pending-promise.js +24 -0
  253. package/dist/utils/pending-promise.js.map +1 -0
  254. package/package.json +38 -0
  255. package/src/components/ui/Checkbox.tsx +68 -0
  256. package/src/components/ui/CheckboxGroup.tsx +60 -0
  257. package/src/components/ui/Input.tsx +72 -0
  258. package/src/components/ui/Radio.tsx +68 -0
  259. package/src/components/ui/Select.tsx +73 -0
  260. package/src/components/ui/Textarea.tsx +63 -0
  261. package/src/components/ui/index.ts +14 -0
  262. package/src/form/index.ts +11 -0
  263. package/src/form/interfaces/field-container.ts +9 -0
  264. package/src/form/interfaces/interfaces.ts +12 -0
  265. package/src/form/interfaces/settings.ts +11 -0
  266. package/src/form/interfaces/template.ts +7 -0
  267. package/src/form/interfaces/wise-form-specs.ts +10 -0
  268. package/src/form/styles.css +40 -0
  269. package/src/form/view/components/containers/index.tsx +18 -0
  270. package/src/form/view/components/error.tsx +9 -0
  271. package/src/form/view/components/field/container.tsx +6 -0
  272. package/src/form/view/components/field/index.tsx +107 -0
  273. package/src/form/view/components/field/selection.tsx +39 -0
  274. package/src/form/view/components/field/use-field.tsx +49 -0
  275. package/src/form/view/components/rows/row-container.tsx +96 -0
  276. package/src/form/view/components/rows/wrapper.tsx +28 -0
  277. package/src/form/view/components/wrapped-form.tsx +32 -0
  278. package/src/form/view/context.tsx +26 -0
  279. package/src/form/view/hooks/use-model.ts +37 -0
  280. package/src/form/view/hooks/use-template.tsx +64 -0
  281. package/src/form/view/hooks/use-types.ts +21 -0
  282. package/src/form/view/index.tsx +48 -0
  283. package/src/formulas/helpers/condition-types.ts +5 -0
  284. package/src/formulas/helpers/evaluations.ts +48 -0
  285. package/src/formulas/helpers/formula.ts +27 -0
  286. package/src/formulas/helpers/lexer.ts +82 -0
  287. package/src/formulas/helpers/parser.ts +55 -0
  288. package/src/formulas/helpers/token.ts +22 -0
  289. package/src/formulas/index.ts +198 -0
  290. package/src/formulas/types/formulas.ts +72 -0
  291. package/src/formulas/types/index.ts +5 -0
  292. package/src/formulas/variants/array-formula.ts +138 -0
  293. package/src/formulas/variants/base.ts +6 -0
  294. package/src/formulas/variants/basic.ts +141 -0
  295. package/src/formulas/variants/comparison.ts +156 -0
  296. package/src/formulas/variants/conditional.ts +208 -0
  297. package/src/formulas/variants/iterative-array.ts +152 -0
  298. package/src/formulas/variants/per-value.ts +152 -0
  299. package/src/index.ts +6 -0
  300. package/src/models/base.ts +164 -0
  301. package/src/models/callback-manager.ts +102 -0
  302. package/src/models/field.ts +426 -0
  303. package/src/models/index.ts +14 -0
  304. package/src/models/model.ts +260 -0
  305. package/src/models/plugins/base.ts +11 -0
  306. package/src/models/plugins/formula.ts +80 -0
  307. package/src/models/plugins/index.ts +48 -0
  308. package/src/models/plugins/plugins.ts +8 -0
  309. package/src/models/types/base-wise-model.ts +7 -0
  310. package/src/models/types/callbacks.ts +23 -0
  311. package/src/models/types/disabled.ts +8 -0
  312. package/src/models/types/form-field.ts +22 -0
  313. package/src/models/types/model.ts +14 -0
  314. package/src/models/types/plugins.ts +15 -0
  315. package/src/models/types/wrapped-form-model-props.ts +9 -0
  316. package/src/models/wrapper.ts +242 -0
  317. package/src/settings/index.ts +11 -0
  318. package/src/utils/pending-promise.ts +29 -0
  319. package/tsconfig.json +39 -0
@@ -0,0 +1,260 @@
1
+ import { FormField } from './field';
2
+ import { WrappedFormModel } from './wrapper';
3
+ import { BaseWiseModel } from './base';
4
+ import { PluginsManager } from './plugins';
5
+ import { CallbackManager } from './callback-manager';
6
+
7
+ export
8
+ class FormModel extends BaseWiseModel {
9
+ #childWrappers: number = 0;
10
+ #plugins: PluginsManager;
11
+ get plugins() {
12
+ return this.#plugins;
13
+ }
14
+
15
+ /**
16
+ * since the fields can be children of the model or a
17
+ * wrapper, this method is used to get the form model
18
+ */
19
+ get form() {
20
+ return this;
21
+ }
22
+ #mode: string;
23
+ get mode() {
24
+ return this.#mode;
25
+ }
26
+ #update: boolean;
27
+ #callbackManagers: CallbackManager[];
28
+ get update() {
29
+ return this.#update;
30
+ }
31
+ /**
32
+ * Initializes a new instance of the `FormModel`, setting up the initial state, including field configurations,
33
+ * callbacks, and reactive properties. This constructor also triggers the asynchronous setup process for the form.
34
+ *
35
+ * @param {Object} settings The configuration settings for the form, including fields, default values, and callbacks.
36
+ * @param {Object} [reactiveProps] Optional reactive properties to enhance the form's reactivity.
37
+ */
38
+ constructor(settings, reactiveProps?) {
39
+ super(settings, reactiveProps);
40
+ this.#startup(settings);
41
+ if (!globalThis._wiseForms) globalThis._wiseForms = [];
42
+ globalThis._wiseForms.push(this);
43
+ this.#update = settings.update;
44
+ this.#mode = this.#update ? 'update' : 'create';
45
+ }
46
+
47
+ #startup = async settings => {
48
+ const values = settings?.values || {};
49
+ const createItems = item => {
50
+ const instance = this.#getFieldModel(item, values);
51
+ const onChange = () => {
52
+ // FormField has value, WrappedFormModel doesn't
53
+ if ('value' in instance) {
54
+ (this as any)[item.name] = (instance as FormField).value;
55
+ }
56
+ };
57
+ instance.on('change', onChange);
58
+ this.fields.set(item.name, instance);
59
+ };
60
+
61
+ this.settings.fields.map(createItems);
62
+
63
+ await this.#checkReady();
64
+ this.#configFields();
65
+ // todo: @everyone Define if is required to wait for the plugins to be ready.
66
+ this.#plugins = new PluginsManager(this);
67
+ this.ready = true;
68
+ this.specs = settings;
69
+ this.trigger('change');
70
+ };
71
+
72
+ /**
73
+ * Checks if all wrappers and fields within the form are loaded and sets the form to a loaded state. This method ensures that the form is fully operational before any interaction.
74
+ * Its used for the start to listen the dependencies
75
+ */
76
+ #checkReady = () => {
77
+ const onReady = () => {
78
+ const areAllWrappersLoaded = this.childWrappersReady === this.#childWrappers;
79
+
80
+ if (!areAllWrappersLoaded) {
81
+ this.childWrappersReady = this.childWrappersReady + 1;
82
+ return;
83
+ }
84
+
85
+ this.loaded = true;
86
+ this.loadedPromise.resolve(true);
87
+ this.off('wrappers.children.loaded', onReady);
88
+ };
89
+
90
+ if (this.loaded) return this.loaded;
91
+
92
+ if (!this.wrappers.size) {
93
+ onReady();
94
+ return this.loaded;
95
+ }
96
+
97
+ this.on('wrappers.children.loaded', onReady);
98
+ return this.loadedPromise;
99
+ };
100
+
101
+ /**
102
+ * Configures all fields by initializing them and setting up dependencies. This method ensures that each field is ready for interaction and that any field dependencies are respected.
103
+ */
104
+ #configFields = () => {
105
+ this.fields.forEach(this.#listenDependencies);
106
+ this.fields.forEach(field => field.initialize());
107
+ };
108
+
109
+ /**
110
+ * Creates a new instance of a field or a wrapper based on the provided item configuration. It initializes the field or wrapper with specified values and properties.
111
+ * @param {Object} item - The field or wrapper configuration.
112
+ * @param {Object} values - The initial values for the fields.
113
+ * @returns {FormField|WrappedFormModel} A new field or wrapper instance.
114
+ */
115
+ #getFieldModel = (item, values: Record<string, unknown>) => {
116
+ let externalValues: Record<string, any> = {};
117
+
118
+ // @todo: @veD-tnayrB: Review this code and document it
119
+ if (Array.isArray(item?.properties)) {
120
+ item?.properties.forEach(item => (externalValues[item.name] = item.value));
121
+ }
122
+ if (item.type === 'wrapper') return this.#getWrapper(item);
123
+
124
+ const instance = new FormField({
125
+ parent: this,
126
+ specs: {
127
+ ...item,
128
+ value: values[item.name] || item?.value,
129
+ properties: item?.properties || [],
130
+ },
131
+ });
132
+
133
+ /**
134
+ * @todo: review it. why we need it.?
135
+ */
136
+ if (item?.properties) {
137
+ let toSet = {};
138
+ item?.properties.forEach(property => (toSet[property] = item[property] || ''));
139
+ instance.set(toSet);
140
+ }
141
+
142
+ return instance;
143
+ };
144
+
145
+ /**
146
+ * Examines each field for dependencies and sets up listeners to respond to changes in dependent fields. This ensures dynamic interactions within the form based on field dependencies.
147
+ * @param {FormField|WrappedFormModel} instance - The field or wrapper instance to check for dependencies.
148
+ */
149
+ #listenDependencies = instance => {
150
+ if (!instance?.specs?.dependentOn?.length) return;
151
+ const manager = new CallbackManager(this, instance);
152
+ };
153
+
154
+ /**
155
+ *
156
+ * @param item
157
+ * @param values
158
+ * @returns
159
+ */
160
+
161
+ #getWrapper = item => {
162
+ let instance: WrappedFormModel | FormField;
163
+ if (!item.fields) throw new Error(`Wrapper ${item.name} must have fields property`);
164
+ const fieldsProperties = item.fields.map(item => item.name);
165
+
166
+ const properties = [...fieldsProperties, ...(item?.properties || [])];
167
+ const defaultValues = item.values || {};
168
+
169
+ instance = new WrappedFormModel({
170
+ parent: this,
171
+ settings: { ...item, form: this },
172
+ specs: { properties: properties || [], ...defaultValues },
173
+ });
174
+
175
+ let toSet = {};
176
+ Object.keys(instance?.getProperties()).forEach(property => (toSet[property] = item[property] || ''));
177
+ instance.set(toSet);
178
+
179
+ this.registerWrapper(instance);
180
+ this.#childWrappers = this.#childWrappers + 1;
181
+
182
+ return instance;
183
+ };
184
+
185
+ /**
186
+ * Registers a wrapper model within the form model, allowing for nested form structures.
187
+ * This method is crucial for managing complex forms where fields might be grouped into sections or wrappers.
188
+ * @param {WrappedFormModel} wrapper - The wrapper instance to register.
189
+ */
190
+ registerWrapper = (wrapper: WrappedFormModel) => {
191
+ this.wrappers.set(wrapper.name, wrapper);
192
+ };
193
+
194
+ getForm() {
195
+ return this;
196
+ }
197
+
198
+ hide = (fields: string[]) => {
199
+ fields.forEach(field => {
200
+ const instance = this.getField(field);
201
+ if (!instance) throw new Error(`Field ${field} does not exist in form ${this.name}`);
202
+
203
+ instance.hide();
204
+ });
205
+ };
206
+
207
+ show = (fields: string[]) => {
208
+ fields.forEach(field => {
209
+ const instance = this.getField(field);
210
+ if (!instance) throw new Error(`Field ${field} does not exist in form ${this.name}`);
211
+
212
+ instance.show();
213
+ });
214
+ };
215
+
216
+ disable = (fields: string[]) => {
217
+ fields.forEach(field => {
218
+ const instance = this.getField(field);
219
+ if (!instance) throw new Error(`Field ${field} does not exist in form ${this.name}`);
220
+
221
+ instance.disabled = true;
222
+ });
223
+ };
224
+
225
+ enable = (fields: string[]) => {
226
+ fields.forEach(field => {
227
+ const instance = this.getField(field);
228
+ if (!instance) throw new Error(`Field ${field} does not exist in form ${this.name}`);
229
+
230
+ instance.disabled = false;
231
+ });
232
+ };
233
+
234
+ reset = (fields: string[]) => {
235
+ fields.forEach(field => {
236
+ const instance = this.getField(field);
237
+ if (!instance) throw new Error(`Field ${field} does not exist in form ${this.name}`);
238
+
239
+ instance.clear();
240
+ });
241
+ };
242
+
243
+ static create = settings => {
244
+ const properties = settings.fields.map(item => item.name);
245
+ const values = settings.values || {};
246
+ const instance = new FormModel(settings, { ...properties, ...values });
247
+
248
+ return instance;
249
+ };
250
+
251
+ public getFormula(name: string) {
252
+ if (!name) return null;
253
+ const formulaPlugin = this.#plugins.instances.get("formula");
254
+ if (!formulaPlugin || !formulaPlugin.formulas) return;
255
+ const formula = formulaPlugin.formulas.get(name);
256
+ if (!formula) return null;
257
+ return formula;
258
+ }
259
+ }
260
+
@@ -0,0 +1,11 @@
1
+ import { FormModel } from '../model';
2
+ import { IPluginFormSpecs } from '../types/plugins';
3
+
4
+ export abstract class WiseFormPluginBase {
5
+ abstract readonly name: string;
6
+ abstract readonly ready: boolean;
7
+ abstract init(): Promise<void>;
8
+
9
+ static settings?(model: FormModel, specs: IPluginFormSpecs): Promise<WiseFormPluginBase>;
10
+ }
11
+
@@ -0,0 +1,80 @@
1
+ // esta interfaz existe para poder esperar
2
+ // a que el plugin esté listo.
3
+ import { parse } from 'mathjs';
4
+ import type { FormModel } from '../model';
5
+ import { IPluginFormSpecs } from '../types/plugins';
6
+ import { FormulaManager } from '@bgroup/wise-form/formulas';
7
+ import { FormField } from '../field';
8
+ import { WiseFormPluginBase } from './base';
9
+ // pensar porque no manejarlo con eventos.
10
+ export class FormulaPlugin extends WiseFormPluginBase {
11
+ #form: FormModel;
12
+ get form() {
13
+ return this.#form;
14
+ }
15
+ #settings: IPluginFormSpecs;
16
+ get name() {
17
+ return 'formula';
18
+ }
19
+
20
+ get ready() {
21
+ return true;
22
+ }
23
+ #formulas: Map<string, any> = new Map();
24
+ get formulas() {
25
+ return this.#formulas;
26
+ }
27
+
28
+ #value: string | number = 0;
29
+ get value() {
30
+ return this.#value;
31
+ }
32
+
33
+ set value(v) {
34
+ if (v === this.#value) return;
35
+ this.#value = v;
36
+ }
37
+
38
+ constructor(form: FormModel, settings: IPluginFormSpecs) {
39
+ super();
40
+ this.#form = form;
41
+ this.#settings = settings;
42
+ }
43
+
44
+ async init() {
45
+ if (!this.#form.settings?.observers) return;
46
+ const promises = this.#form.settings.observers.map(this.create.bind(this));
47
+ const formulas = await Promise.all(promises);
48
+ formulas.forEach(formula => {
49
+ this.#formulas.set(formula.name, formula);
50
+ });
51
+ this.#formulas.forEach(formula => {
52
+ if (!formula.initialize) console.log(-1, formula);
53
+ formula.initialize();
54
+ });
55
+ }
56
+
57
+ async create(observer) {
58
+ const { formula } = observer;
59
+
60
+ if (!observer.name) {
61
+ throw new Error(`Observer in form "${this.#form.name}" must have a name`);
62
+ }
63
+ if (!formula) {
64
+ throw new Error(`Observer ${observer.name} in form "${this.#form.name}" must have a formula`);
65
+ }
66
+
67
+ return FormulaManager.create(this, observer);
68
+ }
69
+
70
+ static async settings(model, settings): Promise<WiseFormPluginBase> {
71
+ try {
72
+ const instance = new FormulaPlugin(model, settings);
73
+ await instance.init();
74
+ return instance;
75
+ } catch (e) {
76
+ console.error(e);
77
+ }
78
+ }
79
+ }
80
+
@@ -0,0 +1,48 @@
1
+ import { ReactiveModel } from '@beyond-js/reactive/model';
2
+ import type { FormModel } from '../model';
3
+ import { PLUGINS } from './plugins';
4
+ import { IPluginForm } from '../types/plugins';
5
+ export class PluginsManager extends ReactiveModel<PluginsManager> {
6
+ #plugins: Record<string, any> = ['formula'];
7
+
8
+ private static items: Map<string, any> = new Map();
9
+ #instances = new Map<string, IPluginForm>();
10
+ get instances() {
11
+ return this.#instances;
12
+ };
13
+ static formulas: Record<string, any> = {};
14
+ #model: FormModel;
15
+ constructor(model) {
16
+ super();
17
+ this.#model = model;
18
+
19
+ globalThis.f = model;
20
+ this.initialize();
21
+ }
22
+
23
+ private async initialize() {
24
+ const plugins = Object.keys(PLUGINS);
25
+ const promises: Promise<IPluginForm>[] = [];
26
+
27
+ plugins.forEach(plugin => {
28
+ const manager = PLUGINS[plugin].object;
29
+ const instance = manager.settings(this.#model);
30
+ promises.push(instance);
31
+ });
32
+
33
+ const results = await Promise.allSettled(promises);
34
+
35
+ const installed = results
36
+ .filter(result => result.status === 'fulfilled')
37
+ .map(result => (result as PromiseFulfilledResult<any>).value);
38
+
39
+ const failed = results.filter(result => result.status === 'rejected');
40
+ if (failed.length) {
41
+ console.warn('Failed to install plugins', failed);
42
+ }
43
+ installed.forEach((plugin: IPluginForm) => this.#instances.set(plugin.name, plugin));
44
+
45
+ this.ready = true;
46
+ }
47
+ }
48
+
@@ -0,0 +1,8 @@
1
+ import { FormulaManager } from '@bgroup/wise-form/formulas';
2
+ import { FormulaPlugin } from './formula';
3
+ export const PLUGINS = {
4
+ formula: {
5
+ object: FormulaPlugin,
6
+ },
7
+ };
8
+
@@ -0,0 +1,7 @@
1
+ export interface IBaseWiseModel {
2
+ name?: string;
3
+ className?: string;
4
+ hidden?: boolean;
5
+ [key: string]: any;
6
+ }
7
+
@@ -0,0 +1,23 @@
1
+ import { FormField } from '../field';
2
+ import { FormModel } from '../model';
3
+
4
+ // Define un tipo que puede ser un string o un objeto con cualquier número de propiedades de tipo string,
5
+ // donde la clave es el nombre del campo y el valor es el alias.
6
+ export type FieldOrAlias = string | { [fieldName: string]: string };
7
+
8
+ export interface ICallbackProps {
9
+ form: FormModel;
10
+ field: FieldOrAlias;
11
+ [string: string]: any;
12
+ /**
13
+ * Additional fields to be passed to the callback.
14
+ */
15
+ fields?: Record<string, any>;
16
+ /**
17
+ * Additional data registered in the WiseForm settings.
18
+ */
19
+ specs?: Record<string, any>;
20
+ }
21
+
22
+ export type CallbackFunction = (props: ICallbackProps) => void;
23
+
@@ -0,0 +1,8 @@
1
+ export type TDisabledSettings = {
2
+ name: string;
3
+ value: any;
4
+ };
5
+ export interface IDisabled {
6
+ fields: string[] | TDisabledSettings[];
7
+ }
8
+
@@ -0,0 +1,22 @@
1
+ export interface IFormField {
2
+ name?: string;
3
+ type?: string;
4
+ placeholder?: string;
5
+ required?: boolean;
6
+ label?: string;
7
+ variant?: string;
8
+ disabled?: boolean;
9
+ value?: any;
10
+ hidden?: boolean;
11
+ options?: Array<{ value: any; label?: string; [key: string]: any }>;
12
+ className?: string;
13
+ checked?: boolean;
14
+ id?: string;
15
+ icon?: string;
16
+ [key: string]: any;
17
+ }
18
+
19
+ export interface IFormFieldProps extends IFormField {
20
+ properties?: string[];
21
+ }
22
+
@@ -0,0 +1,14 @@
1
+ import { IFormField } from './form-field';
2
+
3
+ type Callback = (...args: any[]) => void | Promise<any>;
4
+
5
+ export interface IFormModelProps {
6
+ name?: string;
7
+ params?: Record<string, any>;
8
+ callbacks?: Record<string, Callback>;
9
+ fields?: IFormField[];
10
+ template?: Array<string | number>;
11
+ properties?: string[];
12
+ [key: string]: any;
13
+ }
14
+
@@ -0,0 +1,15 @@
1
+ import type { FormModel } from '../model';
2
+
3
+ export interface IPluginFormSpecs {
4
+ object: IPluginForm;
5
+ property: string;
6
+ }
7
+
8
+ export interface IPluginForm {
9
+ readonly ready: boolean;
10
+ readonly name: string;
11
+ formulas?: Map<string, any>;
12
+ settings: (model: FormModel, specs: IPluginFormSpecs) => Promise<IPluginForm>;
13
+ [key: string]: any;
14
+ }
15
+
@@ -0,0 +1,9 @@
1
+ import type { FormModel } from '../model';
2
+ import type { WrappedFormModel } from '../wrapper';
3
+
4
+ export interface IWrapperFormModelProps {
5
+ parent: FormModel | WrappedFormModel;
6
+ settings: any;
7
+ specs: { properties?: string[]; [key: string]: any };
8
+ }
9
+