@gisce/ooui 2.19.0 → 2.21.0-alpha.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.
- package/dist/Field.d.ts +5 -0
- package/dist/Field.d.ts.map +1 -1
- package/dist/Form.d.ts +5 -0
- package/dist/Form.d.ts.map +1 -1
- package/dist/Spinner.d.ts +9 -0
- package/dist/Spinner.d.ts.map +1 -0
- package/dist/Widget.d.ts.map +1 -1
- package/dist/WidgetFactory.d.ts.map +1 -1
- package/dist/helpers/nodeParser.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/ooui.es.js +381 -343
- package/dist/ooui.es.js.map +1 -1
- package/package.json +1 -1
- package/src/Field.ts +25 -0
- package/src/Form.ts +13 -0
- package/src/Spinner.ts +23 -0
- package/src/Widget.ts +2 -13
- package/src/WidgetFactory.ts +4 -0
- package/src/helpers/nodeParser.ts +7 -1
- package/src/index.ts +2 -0
- package/src/spec/Field.spec.ts +35 -0
- package/src/spec/Form.spec.ts +50 -0
- package/src/spec/Spinner.spec.ts +35 -0
- package/src/spec/nodeParser.spec.ts +53 -0
package/package.json
CHANGED
package/src/Field.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Widget from "./Widget";
|
|
2
2
|
import { replaceEntities, isTrue } from "./helpers/attributeParser";
|
|
3
|
+
import { parseBoolAttribute } from "./helpers/nodeParser";
|
|
3
4
|
|
|
4
5
|
class Field extends Widget {
|
|
5
6
|
/**
|
|
@@ -125,6 +126,27 @@ class Field extends Widget {
|
|
|
125
126
|
return this._fieldType;
|
|
126
127
|
}
|
|
127
128
|
|
|
129
|
+
_autoRefresh?: boolean = false;
|
|
130
|
+
get autoRefresh(): boolean {
|
|
131
|
+
return this._autoRefresh ?? false;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
set autoRefresh(value: boolean) {
|
|
135
|
+
this._autoRefresh = value;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
get readOnly(): boolean | undefined {
|
|
139
|
+
if (this.autoRefresh) {
|
|
140
|
+
return true;
|
|
141
|
+
} else {
|
|
142
|
+
return super.readOnly;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
set readOnly(value: boolean | undefined) {
|
|
147
|
+
super.readOnly = value;
|
|
148
|
+
}
|
|
149
|
+
|
|
128
150
|
constructor(props: any) {
|
|
129
151
|
super(props);
|
|
130
152
|
|
|
@@ -180,6 +202,9 @@ class Field extends Widget {
|
|
|
180
202
|
if (props.help_inline) {
|
|
181
203
|
this.tooltipInline = isTrue(props.help_inline);
|
|
182
204
|
}
|
|
205
|
+
if (props.autorefresh) {
|
|
206
|
+
this.autoRefresh = parseBoolAttribute(props.autorefresh);
|
|
207
|
+
}
|
|
183
208
|
}
|
|
184
209
|
}
|
|
185
210
|
|
package/src/Form.ts
CHANGED
|
@@ -120,6 +120,14 @@ class Form {
|
|
|
120
120
|
this._invisibleFields = value;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
/**
|
|
124
|
+
* List of autorefreshable fields
|
|
125
|
+
*/
|
|
126
|
+
_autorefreshableFields: string[] = [];
|
|
127
|
+
get autorefreshableFields(): string[] {
|
|
128
|
+
return this._autorefreshableFields;
|
|
129
|
+
}
|
|
130
|
+
|
|
123
131
|
/**
|
|
124
132
|
* Context for each field in the form
|
|
125
133
|
*/
|
|
@@ -166,6 +174,11 @@ class Form {
|
|
|
166
174
|
this._contextForFields[unknownWidget._id] = widget._context;
|
|
167
175
|
}
|
|
168
176
|
});
|
|
177
|
+
|
|
178
|
+
// Also we store all the autorefreshables fields in a list
|
|
179
|
+
this._autorefreshableFields = allWidgets
|
|
180
|
+
.filter((widget) => widget instanceof Field && widget.autoRefresh)
|
|
181
|
+
.map((field) => (field as Field)._id);
|
|
169
182
|
}
|
|
170
183
|
|
|
171
184
|
parseNode({
|
package/src/Spinner.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import ContainerWidget from "./ContainerWidget";
|
|
2
|
+
|
|
3
|
+
class Spinner extends ContainerWidget {
|
|
4
|
+
_loading = false;
|
|
5
|
+
get loading(): boolean {
|
|
6
|
+
return this._loading;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
set loading(value: boolean) {
|
|
10
|
+
this._loading = value;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
constructor(props?: any) {
|
|
14
|
+
super(props);
|
|
15
|
+
if (props) {
|
|
16
|
+
if (props.loading) {
|
|
17
|
+
this._loading = props.loading;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default Spinner;
|
package/src/Widget.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { replaceEntities } from "./helpers/attributeParser";
|
|
2
|
+
import { parseBoolAttribute } from "./helpers/nodeParser";
|
|
2
3
|
|
|
3
4
|
abstract class Widget {
|
|
4
5
|
/**
|
|
@@ -124,19 +125,7 @@ abstract class Widget {
|
|
|
124
125
|
this._colspan = +props.colspan;
|
|
125
126
|
}
|
|
126
127
|
if (props.readonly !== undefined) {
|
|
127
|
-
|
|
128
|
-
props.readonly === "1" ||
|
|
129
|
-
props.readonly === 1 ||
|
|
130
|
-
props.readonly === true
|
|
131
|
-
) {
|
|
132
|
-
this._readOnly = true;
|
|
133
|
-
} else if (
|
|
134
|
-
props.readonly === "0" ||
|
|
135
|
-
props.readonly === 0 ||
|
|
136
|
-
props.readonly === false
|
|
137
|
-
) {
|
|
138
|
-
this._readOnly = false;
|
|
139
|
-
}
|
|
128
|
+
this._readOnly = parseBoolAttribute(props.readonly);
|
|
140
129
|
}
|
|
141
130
|
if (props.invisible) {
|
|
142
131
|
if (
|
package/src/WidgetFactory.ts
CHANGED
|
@@ -40,6 +40,7 @@ import Alert from "./Alert";
|
|
|
40
40
|
import Comments from "./Comments";
|
|
41
41
|
import JSONField from "./JSONField";
|
|
42
42
|
import Email from "./Email";
|
|
43
|
+
import Spinner from "./Spinner";
|
|
43
44
|
|
|
44
45
|
class WidgetFactory {
|
|
45
46
|
/**
|
|
@@ -180,6 +181,9 @@ class WidgetFactory {
|
|
|
180
181
|
case "arrow_steps":
|
|
181
182
|
this._widgetClass = JSONField;
|
|
182
183
|
break;
|
|
184
|
+
case "spinner":
|
|
185
|
+
this._widgetClass = Spinner;
|
|
186
|
+
break;
|
|
183
187
|
default:
|
|
184
188
|
break;
|
|
185
189
|
}
|
|
@@ -5,7 +5,13 @@ type ParsedNode = {
|
|
|
5
5
|
};
|
|
6
6
|
|
|
7
7
|
const parseBoolAttribute = (attr: any): boolean => {
|
|
8
|
-
if (
|
|
8
|
+
if (
|
|
9
|
+
attr === 1 ||
|
|
10
|
+
attr === "1" ||
|
|
11
|
+
attr === true ||
|
|
12
|
+
attr === "True" ||
|
|
13
|
+
attr === "true"
|
|
14
|
+
) {
|
|
9
15
|
return true;
|
|
10
16
|
} else {
|
|
11
17
|
return false;
|
package/src/index.ts
CHANGED
|
@@ -52,6 +52,7 @@ import Alert from "./Alert";
|
|
|
52
52
|
import JSONField from "./JSONField";
|
|
53
53
|
import Comments from "./Comments";
|
|
54
54
|
import Email from "./Email";
|
|
55
|
+
import Spinner from "./Spinner";
|
|
55
56
|
|
|
56
57
|
import {
|
|
57
58
|
Graph,
|
|
@@ -140,4 +141,5 @@ export {
|
|
|
140
141
|
Comments,
|
|
141
142
|
JSONField,
|
|
142
143
|
Email,
|
|
144
|
+
Spinner,
|
|
143
145
|
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import Field from "../Field";
|
|
3
|
+
|
|
4
|
+
describe("Field", () => {
|
|
5
|
+
describe("with the autoRefresh property", () => {
|
|
6
|
+
it("should be false as default", () => {
|
|
7
|
+
const props = {};
|
|
8
|
+
const field = new Field(props);
|
|
9
|
+
expect(field.autoRefresh).toBe(false);
|
|
10
|
+
});
|
|
11
|
+
it("should work with text", () => {
|
|
12
|
+
const props = {
|
|
13
|
+
autorefresh: "1",
|
|
14
|
+
};
|
|
15
|
+
const field = new Field(props);
|
|
16
|
+
expect(field.autoRefresh).toBe(true);
|
|
17
|
+
});
|
|
18
|
+
describe("if autorefresh is not a valid boold", () => {
|
|
19
|
+
it("should return false", () => {
|
|
20
|
+
const props = {
|
|
21
|
+
autorefresh: "abc",
|
|
22
|
+
};
|
|
23
|
+
const field = new Field(props);
|
|
24
|
+
expect(field.autoRefresh).toBe(false);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
it("should return true for readOnly if autoRefresh is set", () => {
|
|
28
|
+
const props = {
|
|
29
|
+
autorefresh: true,
|
|
30
|
+
};
|
|
31
|
+
const field = new Field(props);
|
|
32
|
+
expect(field.readOnly).toBe(true);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
});
|
package/src/spec/Form.spec.ts
CHANGED
|
@@ -6015,4 +6015,54 @@ describe("A Form", () => {
|
|
|
6015
6015
|
expect(field_char?.type).toBe("arrow_steps");
|
|
6016
6016
|
expect(field_char?.id).toBe("field_char");
|
|
6017
6017
|
});
|
|
6018
|
+
it("a field with autorefresh evaluated in attrs should be present in form autorefreshable fields property", () => {
|
|
6019
|
+
const fields = {
|
|
6020
|
+
field_char: {
|
|
6021
|
+
string: "Etapa",
|
|
6022
|
+
type: "char",
|
|
6023
|
+
},
|
|
6024
|
+
state: {
|
|
6025
|
+
readonly: true,
|
|
6026
|
+
required: true,
|
|
6027
|
+
selection: [
|
|
6028
|
+
["esborrany", "Borrador"],
|
|
6029
|
+
["validar", "Validar"],
|
|
6030
|
+
["pendent", "Pendiente"],
|
|
6031
|
+
["activa", "Activa"],
|
|
6032
|
+
["cancelada", "Cancelada"],
|
|
6033
|
+
["contracte", "Activación Contrato"],
|
|
6034
|
+
["novapolissa", "Creación nuevo contrato"],
|
|
6035
|
+
["modcontractual", "Modificación Contractual"],
|
|
6036
|
+
["impagament", "Impago"],
|
|
6037
|
+
["tall", "Corte"],
|
|
6038
|
+
["running", "En ejecución"],
|
|
6039
|
+
["baixa", "Baja"],
|
|
6040
|
+
["facturacio", "Facturación"],
|
|
6041
|
+
],
|
|
6042
|
+
string: "Estado",
|
|
6043
|
+
type: "selection",
|
|
6044
|
+
views: {},
|
|
6045
|
+
},
|
|
6046
|
+
};
|
|
6047
|
+
|
|
6048
|
+
const xmlViewForm = `<?xml version="1.0"?>
|
|
6049
|
+
<form string="Form1">
|
|
6050
|
+
<field name="field_char" widget="arrow_steps" colspan="4" nolabel="1" attrs="{'autorefresh':[('state', '=', 'running')]}" />
|
|
6051
|
+
</form>`;
|
|
6052
|
+
|
|
6053
|
+
const form = new Form(fields);
|
|
6054
|
+
form.parse(xmlViewForm, {
|
|
6055
|
+
values: {
|
|
6056
|
+
field_char: "test",
|
|
6057
|
+
state: "running",
|
|
6058
|
+
},
|
|
6059
|
+
});
|
|
6060
|
+
|
|
6061
|
+
const field_char = form.findById("field_char") as Field;
|
|
6062
|
+
expect(field_char).toBeDefined();
|
|
6063
|
+
expect(field_char?.autoRefresh).toBeTruthy();
|
|
6064
|
+
expect(field_char?.readOnly).toBeTruthy();
|
|
6065
|
+
expect(form.autorefreshableFields.length).toBe(1);
|
|
6066
|
+
expect(form.autorefreshableFields[0]).toBe("field_char");
|
|
6067
|
+
});
|
|
6018
6068
|
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import WidgetFactory from "../WidgetFactory";
|
|
2
|
+
import Spinner from "../Spinner";
|
|
3
|
+
import { it, expect, describe } from "vitest";
|
|
4
|
+
|
|
5
|
+
describe("A Spinner", () => {
|
|
6
|
+
it("should have an id corresponding to field name", () => {
|
|
7
|
+
const widgetFactory = new WidgetFactory();
|
|
8
|
+
const props = {
|
|
9
|
+
name: "spinner",
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const widget = widgetFactory.createWidget("spinner", props);
|
|
13
|
+
expect(widget).toBeInstanceOf(Spinner);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("should properly set label", () => {
|
|
17
|
+
const widgetFactory = new WidgetFactory();
|
|
18
|
+
const props = {
|
|
19
|
+
name: "spinner",
|
|
20
|
+
string: "spinner caption",
|
|
21
|
+
};
|
|
22
|
+
const widget = widgetFactory.createWidget("spinner", props);
|
|
23
|
+
|
|
24
|
+
expect(widget.label).toBe("spinner caption");
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("should have loading as false by default", () => {
|
|
28
|
+
const widgetFactory = new WidgetFactory();
|
|
29
|
+
const props = {
|
|
30
|
+
name: "spinner",
|
|
31
|
+
};
|
|
32
|
+
const widget = widgetFactory.createWidget("spinner", props);
|
|
33
|
+
expect(widget.loading).toBe(false);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { parseBoolAttribute } from "../helpers/nodeParser";
|
|
3
|
+
|
|
4
|
+
describe("parseBoolAttribute", () => {
|
|
5
|
+
it("returns true for numeric 1", () => {
|
|
6
|
+
expect(parseBoolAttribute(1)).toBe(true);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('returns true for string "1"', () => {
|
|
10
|
+
expect(parseBoolAttribute("1")).toBe(true);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it("returns true for boolean true", () => {
|
|
14
|
+
expect(parseBoolAttribute(true)).toBe(true);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('returns true for string "True"', () => {
|
|
18
|
+
expect(parseBoolAttribute("True")).toBe(true);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('returns true for string "true"', () => {
|
|
22
|
+
expect(parseBoolAttribute("true")).toBe(true);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("returns false for numeric 0", () => {
|
|
26
|
+
expect(parseBoolAttribute(0)).toBe(false);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('returns false for string "0"', () => {
|
|
30
|
+
expect(parseBoolAttribute("0")).toBe(false);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("returns false for boolean false", () => {
|
|
34
|
+
expect(parseBoolAttribute(false)).toBe(false);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('returns false for string "False"', () => {
|
|
38
|
+
expect(parseBoolAttribute("False")).toBe(false);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("returns false for null", () => {
|
|
42
|
+
expect(parseBoolAttribute(null)).toBe(false);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("returns false for undefined", () => {
|
|
46
|
+
expect(parseBoolAttribute(undefined)).toBe(false);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("returns false for non-boolean strings", () => {
|
|
50
|
+
expect(parseBoolAttribute("yes")).toBe(false);
|
|
51
|
+
expect(parseBoolAttribute("no")).toBe(false);
|
|
52
|
+
});
|
|
53
|
+
});
|