@gisce/ooui 0.1.0

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 (191) hide show
  1. package/README.md +10 -0
  2. package/dist/Binary.d.ts +14 -0
  3. package/dist/Binary.js +46 -0
  4. package/dist/Binary.js.map +1 -0
  5. package/dist/Boolean.d.ts +8 -0
  6. package/dist/Boolean.js +26 -0
  7. package/dist/Boolean.js.map +1 -0
  8. package/dist/Button.d.ts +29 -0
  9. package/dist/Button.js +108 -0
  10. package/dist/Button.js.map +1 -0
  11. package/dist/Char.d.ts +26 -0
  12. package/dist/Char.js +89 -0
  13. package/dist/Char.js.map +1 -0
  14. package/dist/Container.d.ts +44 -0
  15. package/dist/Container.js +148 -0
  16. package/dist/Container.js.map +1 -0
  17. package/dist/ContainerWidget.d.ts +42 -0
  18. package/dist/ContainerWidget.js +125 -0
  19. package/dist/ContainerWidget.js.map +1 -0
  20. package/dist/Date.d.ts +8 -0
  21. package/dist/Date.js +26 -0
  22. package/dist/Date.js.map +1 -0
  23. package/dist/DateTime.d.ts +8 -0
  24. package/dist/DateTime.js +26 -0
  25. package/dist/DateTime.js.map +1 -0
  26. package/dist/FiberGrid.d.ts +5 -0
  27. package/dist/FiberGrid.js +23 -0
  28. package/dist/FiberGrid.js.map +1 -0
  29. package/dist/Field.d.ts +59 -0
  30. package/dist/Field.js +162 -0
  31. package/dist/Field.js.map +1 -0
  32. package/dist/Float.d.ts +24 -0
  33. package/dist/Float.js +64 -0
  34. package/dist/Float.js.map +1 -0
  35. package/dist/FloatTime.d.ts +7 -0
  36. package/dist/FloatTime.js +26 -0
  37. package/dist/FloatTime.js.map +1 -0
  38. package/dist/Form.d.ts +53 -0
  39. package/dist/Form.js +199 -0
  40. package/dist/Form.js.map +1 -0
  41. package/dist/Group.d.ts +5 -0
  42. package/dist/Group.js +23 -0
  43. package/dist/Group.js.map +1 -0
  44. package/dist/Image.d.ts +7 -0
  45. package/dist/Image.js +26 -0
  46. package/dist/Image.js.map +1 -0
  47. package/dist/Integer.d.ts +8 -0
  48. package/dist/Integer.js +26 -0
  49. package/dist/Integer.js.map +1 -0
  50. package/dist/Label.d.ts +23 -0
  51. package/dist/Label.js +80 -0
  52. package/dist/Label.js.map +1 -0
  53. package/dist/Many2many.d.ts +26 -0
  54. package/dist/Many2many.js +80 -0
  55. package/dist/Many2many.js.map +1 -0
  56. package/dist/Many2one.d.ts +20 -0
  57. package/dist/Many2one.js +63 -0
  58. package/dist/Many2one.js.map +1 -0
  59. package/dist/NewLine.d.ts +5 -0
  60. package/dist/NewLine.js +26 -0
  61. package/dist/NewLine.js.map +1 -0
  62. package/dist/Notebook.d.ts +8 -0
  63. package/dist/Notebook.js +41 -0
  64. package/dist/Notebook.js.map +1 -0
  65. package/dist/One2many.d.ts +44 -0
  66. package/dist/One2many.js +130 -0
  67. package/dist/One2many.js.map +1 -0
  68. package/dist/Page.d.ts +5 -0
  69. package/dist/Page.js +23 -0
  70. package/dist/Page.js.map +1 -0
  71. package/dist/ProgressBar.d.ts +7 -0
  72. package/dist/ProgressBar.js +26 -0
  73. package/dist/ProgressBar.js.map +1 -0
  74. package/dist/Reference.d.ts +7 -0
  75. package/dist/Reference.js +26 -0
  76. package/dist/Reference.js.map +1 -0
  77. package/dist/SearchFilter.d.ts +28 -0
  78. package/dist/SearchFilter.js +81 -0
  79. package/dist/SearchFilter.js.map +1 -0
  80. package/dist/Selection.d.ts +20 -0
  81. package/dist/Selection.js +63 -0
  82. package/dist/Selection.js.map +1 -0
  83. package/dist/Separator.d.ts +12 -0
  84. package/dist/Separator.js +46 -0
  85. package/dist/Separator.js.map +1 -0
  86. package/dist/Text.d.ts +29 -0
  87. package/dist/Text.js +96 -0
  88. package/dist/Text.js.map +1 -0
  89. package/dist/Timeline.d.ts +17 -0
  90. package/dist/Timeline.js +56 -0
  91. package/dist/Timeline.js.map +1 -0
  92. package/dist/Tree.d.ts +31 -0
  93. package/dist/Tree.js +96 -0
  94. package/dist/Tree.js.map +1 -0
  95. package/dist/Widget.d.ts +47 -0
  96. package/dist/Widget.js +116 -0
  97. package/dist/Widget.js.map +1 -0
  98. package/dist/WidgetFactory.d.ts +9 -0
  99. package/dist/WidgetFactory.js +157 -0
  100. package/dist/WidgetFactory.js.map +1 -0
  101. package/dist/helpers/attributeParser.d.ts +6 -0
  102. package/dist/helpers/attributeParser.js +83 -0
  103. package/dist/helpers/attributeParser.js.map +1 -0
  104. package/dist/helpers/contextParser.d.ts +5 -0
  105. package/dist/helpers/contextParser.js +52 -0
  106. package/dist/helpers/contextParser.js.map +1 -0
  107. package/dist/helpers/domainParser.d.ts +5 -0
  108. package/dist/helpers/domainParser.js +26 -0
  109. package/dist/helpers/domainParser.js.map +1 -0
  110. package/dist/helpers/fieldParser.d.ts +5 -0
  111. package/dist/helpers/fieldParser.js +20 -0
  112. package/dist/helpers/fieldParser.js.map +1 -0
  113. package/dist/helpers/nodeParser.d.ts +7 -0
  114. package/dist/helpers/nodeParser.js +50 -0
  115. package/dist/helpers/nodeParser.js.map +1 -0
  116. package/dist/helpers/onChangeParser.d.ts +5 -0
  117. package/dist/helpers/onChangeParser.js +16 -0
  118. package/dist/helpers/onChangeParser.js.map +1 -0
  119. package/dist/helpers/stateParser.d.ts +14 -0
  120. package/dist/helpers/stateParser.js +46 -0
  121. package/dist/helpers/stateParser.js.map +1 -0
  122. package/dist/index.d.ts +33 -0
  123. package/dist/index.js +34 -0
  124. package/dist/index.js.map +1 -0
  125. package/package.json +49 -0
  126. package/src/Binary.ts +29 -0
  127. package/src/Boolean.ts +12 -0
  128. package/src/Button.ts +78 -0
  129. package/src/Char.ts +65 -0
  130. package/src/Container.ts +171 -0
  131. package/src/ContainerWidget.ts +105 -0
  132. package/src/Date.ts +12 -0
  133. package/src/DateTime.ts +12 -0
  134. package/src/FiberGrid.ts +9 -0
  135. package/src/Field.ts +147 -0
  136. package/src/Float.ts +45 -0
  137. package/src/FloatTime.ts +8 -0
  138. package/src/Form.ts +212 -0
  139. package/src/Group.ts +9 -0
  140. package/src/Image.ts +8 -0
  141. package/src/Integer.ts +13 -0
  142. package/src/Label.ts +46 -0
  143. package/src/Many2many.ts +59 -0
  144. package/src/Many2one.ts +44 -0
  145. package/src/NewLine.ts +9 -0
  146. package/src/Notebook.ts +24 -0
  147. package/src/One2many.ts +106 -0
  148. package/src/Page.ts +9 -0
  149. package/src/ProgressBar.ts +8 -0
  150. package/src/Reference.ts +10 -0
  151. package/src/SearchFilter.ts +81 -0
  152. package/src/Selection.ts +44 -0
  153. package/src/Separator.ts +30 -0
  154. package/src/Text.ts +76 -0
  155. package/src/Timeline.ts +44 -0
  156. package/src/Tree.ts +93 -0
  157. package/src/Widget.ts +121 -0
  158. package/src/WidgetFactory.ts +158 -0
  159. package/src/helpers/attributeParser.ts +108 -0
  160. package/src/helpers/contextParser.ts +66 -0
  161. package/src/helpers/domainParser.ts +39 -0
  162. package/src/helpers/fieldParser.ts +27 -0
  163. package/src/helpers/nodeParser.ts +57 -0
  164. package/src/helpers/onChangeParser.ts +18 -0
  165. package/src/helpers/stateParser.ts +62 -0
  166. package/src/index.ts +67 -0
  167. package/src/spec/Boolean.spec.ts +36 -0
  168. package/src/spec/Button.spec.ts +58 -0
  169. package/src/spec/Char.spec.ts +80 -0
  170. package/src/spec/Container.spec.ts +47 -0
  171. package/src/spec/ContainerWidget.spec.ts +35 -0
  172. package/src/spec/Date.spec.ts +36 -0
  173. package/src/spec/DateTime.spec.ts +36 -0
  174. package/src/spec/Float.spec.ts +29 -0
  175. package/src/spec/Form.spec.ts +976 -0
  176. package/src/spec/Group.spec.ts +32 -0
  177. package/src/spec/Label.spec.ts +46 -0
  178. package/src/spec/Many2many.spec.ts +36 -0
  179. package/src/spec/Many2one.spec.ts +36 -0
  180. package/src/spec/One2many.spec.ts +354 -0
  181. package/src/spec/SearchFilter.spec.ts +955 -0
  182. package/src/spec/Selection.spec.ts +52 -0
  183. package/src/spec/Separator.spec.ts +14 -0
  184. package/src/spec/Tree.spec.ts +214 -0
  185. package/src/spec/Widget.spec.ts +45 -0
  186. package/src/spec/WidgetFactory.spec.ts +40 -0
  187. package/src/spec/attributeParser.spec.ts +173 -0
  188. package/src/spec/contextParser.spec.ts +57 -0
  189. package/src/spec/domainParser.spec.ts +40 -0
  190. package/src/spec/fixtures/WidgetImpl.ts +10 -0
  191. package/src/spec/stateParser.spec.ts +161 -0
@@ -0,0 +1,30 @@
1
+ import Widget from "./Widget";
2
+
3
+ class Separator extends Widget {
4
+ /**
5
+ * Label
6
+ */
7
+ _label: string = "";
8
+ get label(): string {
9
+ return this._label;
10
+ }
11
+ set label(value: string) {
12
+ this._label = value;
13
+ }
14
+
15
+ constructor(props: any) {
16
+ super(props);
17
+
18
+ if (props) {
19
+ if (props.string) {
20
+ this._label = props.string;
21
+ }
22
+ }
23
+ }
24
+
25
+ findById(id: string): null {
26
+ return null;
27
+ }
28
+ }
29
+
30
+ export default Separator;
package/src/Text.ts ADDED
@@ -0,0 +1,76 @@
1
+ import Field from "./Field";
2
+
3
+ /**
4
+ * Multiline input with no length limit.
5
+ */
6
+ class Text extends Field {
7
+ /**
8
+ * Field place holder
9
+ */
10
+ _placeholder: string = "";
11
+ get placeholder(): string {
12
+ return this._placeholder;
13
+ }
14
+ set placeholder(value: string) {
15
+ this._placeholder = value;
16
+ }
17
+
18
+ /**
19
+ * Must expand widget
20
+ */
21
+ _mustExpand: boolean = false;
22
+ get mustExpand(): boolean {
23
+ return this._mustExpand;
24
+ }
25
+ set mustExpand(value: boolean) {
26
+ this._mustExpand = value;
27
+ }
28
+
29
+ /**
30
+ * Height
31
+ */
32
+ _height: number | undefined;
33
+ get height(): number | undefined {
34
+ return this._height;
35
+ }
36
+ set height(value: number | undefined) {
37
+ this._height = value;
38
+ }
39
+
40
+ _translatable: boolean = false;
41
+ get translatable(): boolean {
42
+ return this._translatable;
43
+ }
44
+ set translatable(value: boolean) {
45
+ this._translatable = value;
46
+ }
47
+
48
+ constructor(props: any) {
49
+ super(props);
50
+
51
+ if (props) {
52
+ if (props.placeholder) {
53
+ this._placeholder = props.placeholder;
54
+ }
55
+
56
+ if (!props.colspan) {
57
+ this._mustExpand = true;
58
+ }
59
+
60
+ if (props.height) {
61
+ try {
62
+ this._height = parseInt(props.height);
63
+ } catch (e) {
64
+ this._height = undefined;
65
+ }
66
+ }
67
+
68
+ if (props.translate) {
69
+ this.translatable =
70
+ props.translate === "True" || props.translate === true ? true : false;
71
+ }
72
+ }
73
+ }
74
+ }
75
+
76
+ export default Text;
@@ -0,0 +1,44 @@
1
+ import One2many from "./One2many";
2
+
3
+ class Timeline extends One2many {
4
+ /**
5
+ * Title field
6
+ */
7
+ _titleField: string;
8
+ get titleField(): string {
9
+ return this._titleField;
10
+ }
11
+ set titleField(value: string) {
12
+ this._titleField = value;
13
+ }
14
+
15
+ /**
16
+ * Summary field
17
+ */
18
+ _summaryField: string;
19
+ get summaryField(): string {
20
+ return this._summaryField;
21
+ }
22
+ set summaryField(value: string) {
23
+ this._summaryField = value;
24
+ }
25
+
26
+ constructor(props: any) {
27
+ super(props);
28
+ this._titleField = "";
29
+ this._summaryField = "";
30
+
31
+ if (props?.widget_props) {
32
+
33
+ try {
34
+ const parsedWidgetProps = JSON.parse(props.widget_props.replace(/'/g, '"'));
35
+ this._titleField = parsedWidgetProps.titleField;
36
+ this._summaryField = parsedWidgetProps.summaryField;
37
+ } catch(err) {
38
+ throw new Error(`Timeline - error parsing widget_props: ${JSON.stringify(err)}`);
39
+ }
40
+ }
41
+ }
42
+ }
43
+
44
+ export default Timeline;
package/src/Tree.ts ADDED
@@ -0,0 +1,93 @@
1
+ import WidgetFactory from "./WidgetFactory";
2
+ import Widget from "./Widget";
3
+ import { parseNodes } from "./helpers/nodeParser";
4
+
5
+ class Tree {
6
+ /**
7
+ * Object containing fields specification of the form.
8
+ */
9
+ _fields: any;
10
+ get fields() {
11
+ return this._fields;
12
+ }
13
+
14
+ _columns: Array<any> = [];
15
+ get columns(): Array<any> {
16
+ return this._columns;
17
+ }
18
+
19
+ _string: string | null = null;
20
+ get string(): string | null {
21
+ return this._string;
22
+ }
23
+
24
+ /**
25
+ * Widget type
26
+ */
27
+ _type: string = "tree";
28
+ get type(): string {
29
+ return this._type;
30
+ }
31
+
32
+ /**
33
+ * Color expression value
34
+ */
35
+ _colors: string | null = null;
36
+ get colors(): string | null {
37
+ return this._colors;
38
+ }
39
+
40
+ constructor(fields: Object) {
41
+ this._fields = fields;
42
+ }
43
+
44
+ parse(xml: string) {
45
+ const parser = new DOMParser();
46
+ const view: Document = parser.parseFromString(xml, "text/xml");
47
+ this.parseNode(view.documentElement);
48
+ this._string = view.documentElement.getAttribute("string");
49
+ this._colors = view.documentElement.getAttribute("colors");
50
+ }
51
+
52
+ parseNode(node: Element) {
53
+ const widgetFactory = new WidgetFactory();
54
+
55
+ const nodesParsed = parseNodes(node.childNodes, this._fields);
56
+
57
+ nodesParsed.forEach((nodeParsed) => {
58
+ const { tag, tagAttributes } = nodeParsed;
59
+ let invisible =
60
+ tagAttributes.invisible || this._fields[tagAttributes.name]?.invisible;
61
+
62
+ if (
63
+ invisible === 1 ||
64
+ invisible === "1" ||
65
+ invisible === true ||
66
+ invisible === "True"
67
+ ) {
68
+ invisible = true;
69
+ } else {
70
+ invisible = false;
71
+ }
72
+
73
+ if (!invisible) {
74
+ const widget = widgetFactory.createWidget(tag, tagAttributes);
75
+ this._columns.push(widget);
76
+ }
77
+ });
78
+ }
79
+
80
+ /**
81
+ * Find the widgets matching with param id
82
+ * @param {string} id id to find
83
+ */
84
+ findById(id: string): Widget | null {
85
+ return this._columns.find((item) => {
86
+ if (item.findById) {
87
+ return item.findById(id);
88
+ }
89
+ });
90
+ }
91
+ }
92
+
93
+ export default Tree;
package/src/Widget.ts ADDED
@@ -0,0 +1,121 @@
1
+ abstract class Widget {
2
+ /**
3
+ * Default colspan
4
+ */
5
+ static _defaultColspan: number = 1;
6
+ static get defaultColspan() {
7
+ return Widget._defaultColspan;
8
+ }
9
+ static set defaultColspan(value) {
10
+ Widget._defaultColspan = value;
11
+ }
12
+
13
+ /**
14
+ * Determines if widget is read only (default is false)
15
+ */
16
+ _readOnly: boolean;
17
+ get readOnly(): boolean {
18
+ return this._readOnly;
19
+ }
20
+ set readOnly(value: boolean) {
21
+ this._readOnly = value;
22
+ }
23
+
24
+ /**
25
+ * Column span (default is 1)
26
+ */
27
+ _colspan: number;
28
+ get colspan(): number {
29
+ return this._colspan;
30
+ }
31
+ set colspan(value: number) {
32
+ this._colspan = +value;
33
+ }
34
+
35
+ /**
36
+ * Invisible fields (default is false)
37
+ */
38
+ _invisible: boolean;
39
+ get invisible(): boolean {
40
+ return this._invisible;
41
+ }
42
+ set invisible(value: boolean) {
43
+ this._invisible = value;
44
+ }
45
+
46
+ /**
47
+ * Widget type
48
+ */
49
+ _type: string = "";
50
+ get type(): string {
51
+ return this._type;
52
+ }
53
+ set type(value: string) {
54
+ this._type = value;
55
+ }
56
+
57
+ /**
58
+ * Context
59
+ */
60
+ _context: any;
61
+ get context(): any {
62
+ return this._context;
63
+ }
64
+ set context(value: any) {
65
+ this._context = value;
66
+ }
67
+
68
+ /**
69
+ * Domain
70
+ */
71
+ _domain?: string;
72
+ get domain(): string | undefined {
73
+ return this._domain;
74
+ }
75
+ set domain(value: string | undefined) {
76
+ this._domain = value;
77
+ }
78
+
79
+ constructor(props?: any) {
80
+ this._colspan = Widget._defaultColspan;
81
+ this._readOnly = false;
82
+ this._invisible = false;
83
+
84
+ if (props) {
85
+ if (props.colspan) {
86
+ this._colspan = +props.colspan;
87
+ }
88
+ if (props.readonly) {
89
+ if (
90
+ props.readonly === "1" ||
91
+ props.readonly === 1 ||
92
+ props.readonly === true
93
+ ) {
94
+ this._readOnly = true;
95
+ }
96
+ }
97
+ if (props.invisible) {
98
+ if (
99
+ props.invisible === 1 ||
100
+ props.invisible === "1" ||
101
+ props.invisible === true
102
+ ) {
103
+ this._invisible = true;
104
+ }
105
+ }
106
+ if (props.type) {
107
+ this._type = props.type;
108
+ }
109
+ if (props.context) {
110
+ this._context = props.context;
111
+ }
112
+ if (props.domain && typeof props.domain === "string") {
113
+ this._domain = props.domain;
114
+ }
115
+ }
116
+ }
117
+
118
+ abstract findById(id: string): Widget | null;
119
+ }
120
+
121
+ export default Widget;
@@ -0,0 +1,158 @@
1
+ import Notebook from "./Notebook";
2
+ import Page from "./Page";
3
+ import Group from "./Group";
4
+ import Button from "./Button";
5
+ import Label from "./Label";
6
+ import Char from "./Char";
7
+ import Text from "./Text";
8
+ import Selection from "./Selection";
9
+ import Many2one from "./Many2one";
10
+ import Boolean from "./Boolean";
11
+ import Integer from "./Integer";
12
+ import Widget from "./Widget";
13
+ import Float from "./Float";
14
+ import FloatTime from "./FloatTime";
15
+ import ProgressBar from "./ProgressBar";
16
+ import Date from "./Date";
17
+ import DateTime from "./DateTime";
18
+ import Many2many from "./Many2many";
19
+ import One2many from "./One2many";
20
+ import NewLine from "./NewLine";
21
+ import Separator from "./Separator";
22
+ import Reference from "./Reference";
23
+ import Binary from "./Binary";
24
+ import Image from "./Image";
25
+ import FiberGrid from "./FiberGrid";
26
+ import Timeline from "./Timeline";
27
+
28
+ class WidgetFactory {
29
+ /**
30
+ * Widget class
31
+ */
32
+ _widgetClass: any;
33
+
34
+ setWidgetClass(type: string): void {
35
+ switch (type) {
36
+ case "notebook":
37
+ this._widgetClass = Notebook;
38
+ break;
39
+ case "page":
40
+ this._widgetClass = Page;
41
+ break;
42
+ case "group":
43
+ this._widgetClass = Group;
44
+ break;
45
+ case "label":
46
+ this._widgetClass = Label;
47
+ break;
48
+ case "char":
49
+ this._widgetClass = Char;
50
+ break;
51
+ case "text":
52
+ this._widgetClass = Text;
53
+ break;
54
+ case "button":
55
+ this._widgetClass = Button;
56
+ break;
57
+ case "selection":
58
+ this._widgetClass = Selection;
59
+ break;
60
+ case "many2one":
61
+ this._widgetClass = Many2one;
62
+ break;
63
+ case "boolean":
64
+ this._widgetClass = Boolean;
65
+ break;
66
+ case "integer":
67
+ this._widgetClass = Integer;
68
+ break;
69
+ case "float":
70
+ this._widgetClass = Float;
71
+ break;
72
+ case "float_time":
73
+ this._widgetClass = FloatTime;
74
+ break;
75
+ case "date":
76
+ this._widgetClass = Date;
77
+ break;
78
+ case "datetime":
79
+ this._widgetClass = DateTime;
80
+ break;
81
+ case "progressbar":
82
+ this._widgetClass = ProgressBar;
83
+ break;
84
+ case "many2many":
85
+ this._widgetClass = Many2many;
86
+ break;
87
+ case "one2many":
88
+ case "one2many_list":
89
+ this._widgetClass = One2many;
90
+ break;
91
+ case "newline":
92
+ this._widgetClass = NewLine;
93
+ break;
94
+ case "separator":
95
+ this._widgetClass = Separator;
96
+ break;
97
+ case "url":
98
+ this._widgetClass = Char;
99
+ break;
100
+ case "email":
101
+ this._widgetClass = Char;
102
+ break;
103
+ case "reference":
104
+ this._widgetClass = Reference;
105
+ break;
106
+ case "binary":
107
+ this._widgetClass = Binary;
108
+ break;
109
+ case "image":
110
+ this._widgetClass = Image;
111
+ break;
112
+ case "fiber_grid":
113
+ this._widgetClass = FiberGrid;
114
+ break;
115
+ case "timeline":
116
+ this._widgetClass = Timeline;
117
+ break;
118
+ default:
119
+ break;
120
+ }
121
+ }
122
+
123
+ createWidget(type: string, props: any) {
124
+ let finalType = type;
125
+
126
+ this.setWidgetClass(type);
127
+
128
+ // Fallback to default widget, we try to use the fields type widget if it exists
129
+ if (this._widgetClass === undefined) {
130
+ finalType = props.fieldsWidgetType;
131
+ this.setWidgetClass(props.fieldsWidgetType);
132
+ }
133
+
134
+ if (this._widgetClass === undefined) {
135
+ this._widgetClass = Widget;
136
+ }
137
+
138
+ // TODO: Widget Class constructors should use only the props needed, not all props.
139
+ switch (type) {
140
+ // Specific cases (only selected props should be used)
141
+ case "notebook":
142
+ case "page":
143
+ case "group":
144
+ return new this._widgetClass({ ...props, type: finalType });
145
+ case "button":
146
+ return new this._widgetClass({
147
+ ...props,
148
+ type,
149
+ buttonType: props.type,
150
+ });
151
+ // Generic case
152
+ default:
153
+ return new this._widgetClass({ ...props, type: finalType });
154
+ }
155
+ }
156
+ }
157
+
158
+ export default WidgetFactory;
@@ -0,0 +1,108 @@
1
+ const evaluateCondition = ({
2
+ entry,
3
+ values,
4
+ fields,
5
+ }: {
6
+ entry: Array<any>;
7
+ values: any;
8
+ fields: any;
9
+ }) => {
10
+ const [fieldName, operator, expectedValue] = entry;
11
+
12
+ if (fields[fieldName] === undefined) {
13
+ return false;
14
+ }
15
+
16
+ if (values[fieldName] === undefined && fields[fieldName].type !== "boolean") {
17
+ return false;
18
+ }
19
+
20
+ let filteredExpectedValue = expectedValue;
21
+
22
+ if (
23
+ fields[fieldName].type === "boolean" &&
24
+ (expectedValue === 0 || expectedValue === 1)
25
+ ) {
26
+ filteredExpectedValue = expectedValue === 0 ? false : true;
27
+ }
28
+
29
+ const value =
30
+ fields[fieldName].type === "boolean"
31
+ ? !!values[fieldName]
32
+ : values[fieldName];
33
+
34
+ switch (operator.toLowerCase()) {
35
+ case "=":
36
+ case "==":
37
+ return value === filteredExpectedValue;
38
+ case "<>":
39
+ case "!=":
40
+ return value !== filteredExpectedValue;
41
+ case ">":
42
+ return value > filteredExpectedValue;
43
+ case ">=":
44
+ return value >= filteredExpectedValue;
45
+ case "<":
46
+ return value < filteredExpectedValue;
47
+ case "<=":
48
+ return value <= filteredExpectedValue;
49
+ case "in":
50
+ return filteredExpectedValue.includes(value);
51
+ case "not in":
52
+ return !filteredExpectedValue.includes(value);
53
+ default:
54
+ return false;
55
+ }
56
+ };
57
+
58
+ const parseAttributes = ({
59
+ attrs,
60
+ values,
61
+ fields,
62
+ }: {
63
+ attrs: string;
64
+ values: any;
65
+ fields: any;
66
+ }) => {
67
+ const leftP = attrs.replace(/\(/g, "[");
68
+ const rightP = leftP.replace(/\)/g, "]");
69
+ const clearQuotes = rightP.replace(/\'/g, '"');
70
+ const replaceTrue = clearQuotes.replace(/True/g, "true");
71
+ const replaceFalse = replaceTrue.replace(/False/g, "false");
72
+ const parsedObject = JSON.parse(replaceFalse);
73
+ const newAttributes: any = {};
74
+
75
+ for (const attrField of Object.keys(parsedObject)) {
76
+ const entries = parsedObject[attrField];
77
+ const evaluatedEntries: boolean[] = entries.map((entry: any) => {
78
+ return evaluateCondition({ entry, values, fields });
79
+ });
80
+ newAttributes[attrField] = evaluatedEntries.every(
81
+ (i: boolean) => i === true
82
+ );
83
+ }
84
+
85
+ return newAttributes;
86
+ };
87
+
88
+ const evaluateAttributes = ({
89
+ tagAttributes,
90
+ values,
91
+ fields,
92
+ }: {
93
+ tagAttributes: any;
94
+ values: any;
95
+ fields: any;
96
+ }) => {
97
+ const newTagAttributes = tagAttributes.attrs
98
+ ? parseAttributes({
99
+ attrs: tagAttributes.attrs,
100
+ values,
101
+ fields,
102
+ })
103
+ : {};
104
+
105
+ return { ...tagAttributes, ...newTagAttributes, attrs: undefined };
106
+ };
107
+
108
+ export { evaluateAttributes };
@@ -0,0 +1,66 @@
1
+ import { getValueForField } from "./fieldParser";
2
+
3
+ export const parseContext = ({
4
+ context,
5
+ values,
6
+ fields,
7
+ }: {
8
+ context?: string;
9
+ values?: any;
10
+ fields?: any;
11
+ }) => {
12
+ // TODO: remove try/catch when we know for sure that all the incoming contexts formats are expected
13
+ try {
14
+ if (!context) return undefined;
15
+
16
+ if (context.trim().length === 0) {
17
+ return undefined;
18
+ }
19
+
20
+ // TODO: maybe this can be accomplished more performant and elegant with regex
21
+ const strNoWhitespaces = context.replace(/\s/g, "");
22
+ var replaceTrue = strNoWhitespaces.replace(/True/g, "true");
23
+ var replaceFalse = replaceTrue.replace(/False/g, "false");
24
+ const strNoClauLeft = replaceFalse.replace(/\{/g, "");
25
+ const strNoClauRight = strNoClauLeft.replace(/\}/g, "");
26
+
27
+ const entryValues = strNoClauRight.split(",");
28
+ const valuesSplitted = entryValues.map((entry) => {
29
+ return entry.split(":");
30
+ });
31
+
32
+ const parsedContext: any = {};
33
+
34
+ valuesSplitted.forEach((entry) => {
35
+ const fieldName = entry[1];
36
+
37
+ if (
38
+ entry[1].indexOf("'") === -1 &&
39
+ entry[1] !== "true" &&
40
+ entry[1] !== "false"
41
+ ) {
42
+ const valueForField = getValueForField({
43
+ values,
44
+ fields,
45
+ fieldName: fieldName === "active_id" ? "id" : fieldName,
46
+ });
47
+ parsedContext[entry[0].replace(/'/g, "")] = valueForField || undefined;
48
+ } else {
49
+ if (entry[1] === "true") {
50
+ parsedContext[entry[0].replace(/'/g, "")] = true;
51
+ } else if (entry[1] === "false") {
52
+ parsedContext[entry[0].replace(/'/g, "")] = false;
53
+ } else {
54
+ parsedContext[entry[0].replace(/'/g, "")] = entry[1].replace(
55
+ /'/g,
56
+ ""
57
+ );
58
+ }
59
+ }
60
+ });
61
+
62
+ return parsedContext;
63
+ } catch (e) {
64
+ return undefined;
65
+ }
66
+ };