Skip to content

Commit

Permalink
feat: sync changes from v2 to v2-develop (#156) [skip ci]
Browse files Browse the repository at this point in the history
Co-authored-by: mguellsegarra <[email protected]>
  • Loading branch information
giscegit and mguellsegarra authored Dec 12, 2024
1 parent c553890 commit 50b5e6e
Show file tree
Hide file tree
Showing 12 changed files with 286 additions and 31 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@gisce/ooui",
"version": "2.23.0-rc.1",
"version": "2.24.0",
"engines": {
"node": "20.5.0"
},
Expand Down
33 changes: 33 additions & 0 deletions src/Field.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Widget from "./Widget";
import { replaceEntities, isTrue } from "./helpers/attributeParser";
import { parseBoolAttribute } from "./helpers/nodeParser";

class Field extends Widget {
/**
Expand Down Expand Up @@ -105,6 +106,14 @@ class Field extends Widget {
this._sum = value;
}

get suffix(): string {
return this._parsedWidgetProps.suffix || "";
}

get prefix(): string {
return this._parsedWidgetProps.prefix || "";
}

/**
* Values and keys
*/
Expand All @@ -117,6 +126,27 @@ class Field extends Widget {
this._selectionValues = value;
}

_autoRefresh?: boolean = false;
get autoRefresh(): boolean {
return this._autoRefresh ?? false;
}

set autoRefresh(value: boolean) {
this._autoRefresh = value;
}

get readOnly(): boolean | undefined {
if (this.autoRefresh) {
return true;
} else {
return super.readOnly;
}
}

set readOnly(value: boolean | undefined) {
super.readOnly = value;
}

constructor(props: any) {
super(props);

Expand Down Expand Up @@ -168,6 +198,9 @@ class Field extends Widget {
if (props.help_inline) {
this.tooltipInline = isTrue(props.help_inline);
}
if (props.autorefresh) {
this.autoRefresh = parseBoolAttribute(props.autorefresh);
}
}
}

Expand Down
24 changes: 23 additions & 1 deletion src/Form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import Container from "./Container";
import ContainerWidget from "./ContainerWidget";
import Widget from "./Widget";
import { ParsedNode } from "./helpers/nodeParser";
import { evaluateAttributes, replaceEntities } from "./helpers/attributeParser";
import {
evaluateAttributes,
replaceEntities,
parseWidgetProps,
} from "./helpers/attributeParser";
import { evaluateStates, evaluateButtonStates } from "./helpers/stateParser";
import { parseContext } from "./helpers/contextParser";
import { parseOnChange } from "./helpers/onChangeParser";
Expand Down Expand Up @@ -120,6 +124,14 @@ class Form {
this._invisibleFields = value;
}

/**
* List of autorefreshable fields
*/
_autorefreshableFields: string[] = [];
get autorefreshableFields(): string[] {
return this._autorefreshableFields;
}

/**
* Context for each field in the form
*/
Expand Down Expand Up @@ -166,6 +178,11 @@ class Form {
this._contextForFields[unknownWidget._id] = widget._context;
}
});

// Also we store all the autorefreshables fields in a list
this._autorefreshableFields = allWidgets
.filter((widget) => widget instanceof Field && widget.autoRefresh)
.map((field) => (field as Field)._id);
}

parseNode({
Expand Down Expand Up @@ -195,6 +212,11 @@ class Form {
);
}
widgetType = this._fields[name].type;
// Merge _fields[widget_props] with attributes[widget_props]
attributes.widget_props = {
...parseWidgetProps(attributes.widget_props),
...(this._fields[name].widget_props || {}),
};
}
tagAttributes = {
...this._fields[name],
Expand Down
14 changes: 13 additions & 1 deletion src/Tree.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import WidgetFactory from "./WidgetFactory";
import Widget from "./Widget";
import { replaceEntities } from "./helpers/attributeParser";
import { ParsedNode } from "./helpers/nodeParser";
import { parseBoolAttribute, ParsedNode } from "./helpers/nodeParser";
import * as txml from "txml";
import { parseContext } from "./helpers/contextParser";

Expand Down Expand Up @@ -67,6 +67,14 @@ class Tree {
this._contextForFields = value;
}

/**
* List of autorefreshable fields
*/
_autorefreshableFields: string[] = [];
get autorefreshableFields(): string[] {
return this._autorefreshableFields;
}

/**
* Is infinite
*/
Expand Down Expand Up @@ -145,6 +153,10 @@ class Tree {
const widget = widgetFactory.createWidget(widgetType, mergedAttrs);
this._columns.push(widget);
}

if (parseBoolAttribute(mergedAttrs.autorefresh)) {
this._autorefreshableFields.push(name);
}
}
});
}
Expand Down
29 changes: 4 additions & 25 deletions src/Widget.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { replaceEntities } from "./helpers/attributeParser";
import { replaceEntities, parseWidgetProps } from "./helpers/attributeParser";
import { parseBoolAttribute } from "./helpers/nodeParser";

abstract class Widget {
/**
Expand Down Expand Up @@ -132,19 +133,7 @@ abstract class Widget {
this._colspan = +props.colspan;
}
if (props.readonly !== undefined) {
if (
props.readonly === "1" ||
props.readonly === 1 ||
props.readonly === true
) {
this._readOnly = true;
} else if (
props.readonly === "0" ||
props.readonly === 0 ||
props.readonly === false
) {
this._readOnly = false;
}
this._readOnly = parseBoolAttribute(props.readonly);
}
if (props.invisible) {
if (
Expand Down Expand Up @@ -172,17 +161,7 @@ abstract class Widget {
this._fieldType = props.fieldsWidgetType;
}
if (props.widget_props) {
if (typeof props.widget_props === "string") {
try {
this._parsedWidgetProps = JSON.parse(
props.widget_props.replace(/'/g, '"'),
);
} catch (err) {
console.error("Error parsing widget_props");
}
} else {
this._parsedWidgetProps = props.widget_props;
}
this._parsedWidgetProps = parseWidgetProps(props.widget_props);
}
if (props.key) {
this._key = props.key;
Expand Down
16 changes: 16 additions & 0 deletions src/helpers/attributeParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,22 @@ const parseAttributes = ({
return newAttributes;
};

export const parseWidgetProps = (widget_props: string | object): object => {
if (widget_props === undefined) {
return {};
}
if (typeof widget_props === "string") {
try {
return JSON.parse(widget_props.replace(/'/g, '"'));
} catch (err) {
console.error("Error parsing widget_props");
return {};
}
} else {
return widget_props;
}
};

export const parseJsonAttributes = ({
attrs,
values,
Expand Down
8 changes: 7 additions & 1 deletion src/helpers/nodeParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@ type ParsedNode = {
};

const parseBoolAttribute = (attr: any): boolean => {
if (attr === 1 || attr === "1" || attr === true || attr === "True") {
if (
attr === 1 ||
attr === "1" ||
attr === true ||
attr === "True" ||
attr === "true"
) {
return true;
} else {
return false;
Expand Down
35 changes: 35 additions & 0 deletions src/spec/Field.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { describe, it, expect } from "vitest";
import Field from "../Field";

describe("Field", () => {
describe("with the autoRefresh property", () => {
it("should be false as default", () => {
const props = {};
const field = new Field(props);
expect(field.autoRefresh).toBe(false);
});
it("should work with text", () => {
const props = {
autorefresh: "1",
};
const field = new Field(props);
expect(field.autoRefresh).toBe(true);
});
describe("if autorefresh is not a valid boold", () => {
it("should return false", () => {
const props = {
autorefresh: "abc",
};
const field = new Field(props);
expect(field.autoRefresh).toBe(false);
});
});
it("should return true for readOnly if autoRefresh is set", () => {
const props = {
autorefresh: true,
};
const field = new Field(props);
expect(field.readOnly).toBe(true);
});
});
});
80 changes: 80 additions & 0 deletions src/spec/Form.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6015,4 +6015,84 @@ describe("A Form", () => {
expect(field_char?.type).toBe("arrow_steps");
expect(field_char?.id).toBe("field_char");
});
it("a field with autorefresh evaluated in attrs should be present in form autorefreshable fields property", () => {
const fields = {
field_char: {
string: "Etapa",
type: "char",
},
state: {
readonly: true,
required: true,
selection: [
["esborrany", "Borrador"],
["validar", "Validar"],
["pendent", "Pendiente"],
["activa", "Activa"],
["cancelada", "Cancelada"],
["contracte", "Activación Contrato"],
["novapolissa", "Creación nuevo contrato"],
["modcontractual", "Modificación Contractual"],
["impagament", "Impago"],
["tall", "Corte"],
["running", "En ejecución"],
["baixa", "Baja"],
["facturacio", "Facturación"],
],
string: "Estado",
type: "selection",
views: {},
},
};

const xmlViewForm = `<?xml version="1.0"?>
<form string="Form1">
<field name="field_char" widget="arrow_steps" colspan="4" nolabel="1" attrs="{'autorefresh':[('state', '=', 'running')]}" />
</form>`;

const form = new Form(fields);
form.parse(xmlViewForm, {
values: {
field_char: "test",
state: "running",
},
});

const field_char = form.findById("field_char") as Field;
expect(field_char).toBeDefined();
expect(field_char?.autoRefresh).toBeTruthy();
expect(field_char?.readOnly).toBeTruthy();
expect(form.autorefreshableFields.length).toBe(1);
expect(form.autorefreshableFields[0]).toBe("field_char");
});
describe("If the field has widget_props", () => {
it("should merge widget_props from fields definition and xml", () => {
const fields = {
field_integer: {
readonly: 1,
string: "Power",
type: "integer",
widget_props: {
suffix: "kW",
},
},
};

const xmlViewForm = `<?xml version="1.0"?>
<form string="Form1">
<field name="field_integer" widget_props="{'prefix': 'Wow'}" />
</form>`;

const form = new Form(fields);
form.parse(xmlViewForm, {
values: {
field_integer: 10,
},
});
const field = form.findById("field_integer") as Field;
expect(field).toBeDefined();
expect(field.suffix).toBe("kW");
expect(field.prefix).toBe("Wow");
});
});
});
19 changes: 19 additions & 0 deletions src/spec/Tree.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -377,4 +377,23 @@ describe("A Tree", () => {
const nameWidget = tree.findById("name") as Char;
expect(nameWidget.isFunction).toBeTruthy();
});
it("Should parse autorefreshable fields", () => {
const tree = new Tree({
name: {
required: true,
select: true,
size: 128,
string: "Pot&#232;ncia contractada (kW)",
type: "char",
views: {},
},
});
tree.parse(
`<tree string="Partners" colors="red:type=='updated'"><field name="name" sum="Pot&#232;ncia contractada (kW)" autorefresh="1"/></tree>`,
);

const nameWidget = tree.findById("name") as Char;
expect(nameWidget.autoRefresh).toBeTruthy();
expect(tree._autorefreshableFields.length).toBe(1);
});
});
Loading

0 comments on commit 50b5e6e

Please sign in to comment.