@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.
- package/README.md +10 -0
- package/dist/Binary.d.ts +14 -0
- package/dist/Binary.js +46 -0
- package/dist/Binary.js.map +1 -0
- package/dist/Boolean.d.ts +8 -0
- package/dist/Boolean.js +26 -0
- package/dist/Boolean.js.map +1 -0
- package/dist/Button.d.ts +29 -0
- package/dist/Button.js +108 -0
- package/dist/Button.js.map +1 -0
- package/dist/Char.d.ts +26 -0
- package/dist/Char.js +89 -0
- package/dist/Char.js.map +1 -0
- package/dist/Container.d.ts +44 -0
- package/dist/Container.js +148 -0
- package/dist/Container.js.map +1 -0
- package/dist/ContainerWidget.d.ts +42 -0
- package/dist/ContainerWidget.js +125 -0
- package/dist/ContainerWidget.js.map +1 -0
- package/dist/Date.d.ts +8 -0
- package/dist/Date.js +26 -0
- package/dist/Date.js.map +1 -0
- package/dist/DateTime.d.ts +8 -0
- package/dist/DateTime.js +26 -0
- package/dist/DateTime.js.map +1 -0
- package/dist/FiberGrid.d.ts +5 -0
- package/dist/FiberGrid.js +23 -0
- package/dist/FiberGrid.js.map +1 -0
- package/dist/Field.d.ts +59 -0
- package/dist/Field.js +162 -0
- package/dist/Field.js.map +1 -0
- package/dist/Float.d.ts +24 -0
- package/dist/Float.js +64 -0
- package/dist/Float.js.map +1 -0
- package/dist/FloatTime.d.ts +7 -0
- package/dist/FloatTime.js +26 -0
- package/dist/FloatTime.js.map +1 -0
- package/dist/Form.d.ts +53 -0
- package/dist/Form.js +199 -0
- package/dist/Form.js.map +1 -0
- package/dist/Group.d.ts +5 -0
- package/dist/Group.js +23 -0
- package/dist/Group.js.map +1 -0
- package/dist/Image.d.ts +7 -0
- package/dist/Image.js +26 -0
- package/dist/Image.js.map +1 -0
- package/dist/Integer.d.ts +8 -0
- package/dist/Integer.js +26 -0
- package/dist/Integer.js.map +1 -0
- package/dist/Label.d.ts +23 -0
- package/dist/Label.js +80 -0
- package/dist/Label.js.map +1 -0
- package/dist/Many2many.d.ts +26 -0
- package/dist/Many2many.js +80 -0
- package/dist/Many2many.js.map +1 -0
- package/dist/Many2one.d.ts +20 -0
- package/dist/Many2one.js +63 -0
- package/dist/Many2one.js.map +1 -0
- package/dist/NewLine.d.ts +5 -0
- package/dist/NewLine.js +26 -0
- package/dist/NewLine.js.map +1 -0
- package/dist/Notebook.d.ts +8 -0
- package/dist/Notebook.js +41 -0
- package/dist/Notebook.js.map +1 -0
- package/dist/One2many.d.ts +44 -0
- package/dist/One2many.js +130 -0
- package/dist/One2many.js.map +1 -0
- package/dist/Page.d.ts +5 -0
- package/dist/Page.js +23 -0
- package/dist/Page.js.map +1 -0
- package/dist/ProgressBar.d.ts +7 -0
- package/dist/ProgressBar.js +26 -0
- package/dist/ProgressBar.js.map +1 -0
- package/dist/Reference.d.ts +7 -0
- package/dist/Reference.js +26 -0
- package/dist/Reference.js.map +1 -0
- package/dist/SearchFilter.d.ts +28 -0
- package/dist/SearchFilter.js +81 -0
- package/dist/SearchFilter.js.map +1 -0
- package/dist/Selection.d.ts +20 -0
- package/dist/Selection.js +63 -0
- package/dist/Selection.js.map +1 -0
- package/dist/Separator.d.ts +12 -0
- package/dist/Separator.js +46 -0
- package/dist/Separator.js.map +1 -0
- package/dist/Text.d.ts +29 -0
- package/dist/Text.js +96 -0
- package/dist/Text.js.map +1 -0
- package/dist/Timeline.d.ts +17 -0
- package/dist/Timeline.js +56 -0
- package/dist/Timeline.js.map +1 -0
- package/dist/Tree.d.ts +31 -0
- package/dist/Tree.js +96 -0
- package/dist/Tree.js.map +1 -0
- package/dist/Widget.d.ts +47 -0
- package/dist/Widget.js +116 -0
- package/dist/Widget.js.map +1 -0
- package/dist/WidgetFactory.d.ts +9 -0
- package/dist/WidgetFactory.js +157 -0
- package/dist/WidgetFactory.js.map +1 -0
- package/dist/helpers/attributeParser.d.ts +6 -0
- package/dist/helpers/attributeParser.js +83 -0
- package/dist/helpers/attributeParser.js.map +1 -0
- package/dist/helpers/contextParser.d.ts +5 -0
- package/dist/helpers/contextParser.js +52 -0
- package/dist/helpers/contextParser.js.map +1 -0
- package/dist/helpers/domainParser.d.ts +5 -0
- package/dist/helpers/domainParser.js +26 -0
- package/dist/helpers/domainParser.js.map +1 -0
- package/dist/helpers/fieldParser.d.ts +5 -0
- package/dist/helpers/fieldParser.js +20 -0
- package/dist/helpers/fieldParser.js.map +1 -0
- package/dist/helpers/nodeParser.d.ts +7 -0
- package/dist/helpers/nodeParser.js +50 -0
- package/dist/helpers/nodeParser.js.map +1 -0
- package/dist/helpers/onChangeParser.d.ts +5 -0
- package/dist/helpers/onChangeParser.js +16 -0
- package/dist/helpers/onChangeParser.js.map +1 -0
- package/dist/helpers/stateParser.d.ts +14 -0
- package/dist/helpers/stateParser.js +46 -0
- package/dist/helpers/stateParser.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/package.json +49 -0
- package/src/Binary.ts +29 -0
- package/src/Boolean.ts +12 -0
- package/src/Button.ts +78 -0
- package/src/Char.ts +65 -0
- package/src/Container.ts +171 -0
- package/src/ContainerWidget.ts +105 -0
- package/src/Date.ts +12 -0
- package/src/DateTime.ts +12 -0
- package/src/FiberGrid.ts +9 -0
- package/src/Field.ts +147 -0
- package/src/Float.ts +45 -0
- package/src/FloatTime.ts +8 -0
- package/src/Form.ts +212 -0
- package/src/Group.ts +9 -0
- package/src/Image.ts +8 -0
- package/src/Integer.ts +13 -0
- package/src/Label.ts +46 -0
- package/src/Many2many.ts +59 -0
- package/src/Many2one.ts +44 -0
- package/src/NewLine.ts +9 -0
- package/src/Notebook.ts +24 -0
- package/src/One2many.ts +106 -0
- package/src/Page.ts +9 -0
- package/src/ProgressBar.ts +8 -0
- package/src/Reference.ts +10 -0
- package/src/SearchFilter.ts +81 -0
- package/src/Selection.ts +44 -0
- package/src/Separator.ts +30 -0
- package/src/Text.ts +76 -0
- package/src/Timeline.ts +44 -0
- package/src/Tree.ts +93 -0
- package/src/Widget.ts +121 -0
- package/src/WidgetFactory.ts +158 -0
- package/src/helpers/attributeParser.ts +108 -0
- package/src/helpers/contextParser.ts +66 -0
- package/src/helpers/domainParser.ts +39 -0
- package/src/helpers/fieldParser.ts +27 -0
- package/src/helpers/nodeParser.ts +57 -0
- package/src/helpers/onChangeParser.ts +18 -0
- package/src/helpers/stateParser.ts +62 -0
- package/src/index.ts +67 -0
- package/src/spec/Boolean.spec.ts +36 -0
- package/src/spec/Button.spec.ts +58 -0
- package/src/spec/Char.spec.ts +80 -0
- package/src/spec/Container.spec.ts +47 -0
- package/src/spec/ContainerWidget.spec.ts +35 -0
- package/src/spec/Date.spec.ts +36 -0
- package/src/spec/DateTime.spec.ts +36 -0
- package/src/spec/Float.spec.ts +29 -0
- package/src/spec/Form.spec.ts +976 -0
- package/src/spec/Group.spec.ts +32 -0
- package/src/spec/Label.spec.ts +46 -0
- package/src/spec/Many2many.spec.ts +36 -0
- package/src/spec/Many2one.spec.ts +36 -0
- package/src/spec/One2many.spec.ts +354 -0
- package/src/spec/SearchFilter.spec.ts +955 -0
- package/src/spec/Selection.spec.ts +52 -0
- package/src/spec/Separator.spec.ts +14 -0
- package/src/spec/Tree.spec.ts +214 -0
- package/src/spec/Widget.spec.ts +45 -0
- package/src/spec/WidgetFactory.spec.ts +40 -0
- package/src/spec/attributeParser.spec.ts +173 -0
- package/src/spec/contextParser.spec.ts +57 -0
- package/src/spec/domainParser.spec.ts +40 -0
- package/src/spec/fixtures/WidgetImpl.ts +10 -0
- package/src/spec/stateParser.spec.ts +161 -0
package/src/Separator.ts
ADDED
|
@@ -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;
|
package/src/Timeline.ts
ADDED
|
@@ -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
|
+
};
|