@yuneta/gobj-ui 7.26.32 → 7.26.33

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.
@@ -10711,7 +10711,9 @@ function get_form_values(gobj, $form) {
10711
10711
  else value = value_.text;
10712
10712
  }
10713
10713
  break;
10714
- case "fieldset": break;
10714
+ case "fieldset":
10715
+ value = {};
10716
+ break;
10715
10717
  case "table":
10716
10718
  let template = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "template");
10717
10719
  if (!(0, _yuneta_gobj_js.empty_string)(name) && (0, _yuneta_gobj_js.kw_has_key)(template, name)) {
@@ -10733,7 +10735,7 @@ function get_form_values(gobj, $form) {
10733
10735
  break;
10734
10736
  default: (0, _yuneta_gobj_js.log_error)((0, _yuneta_gobj_js.sprintf)("%s: $form type unknown: '%s'", (0, _yuneta_gobj_js.gobj_short_name)(gobj), tag));
10735
10737
  }
10736
- value = form_value_2_treedb_value(gobj, field_desc, value);
10738
+ if (tag !== "fieldset") value = form_value_2_treedb_value(gobj, field_desc, value);
10737
10739
  let path;
10738
10740
  if ((0, _yuneta_gobj_js.empty_string)(prefix)) path = name;
10739
10741
  else path = prefix + "`" + name;
@@ -10706,7 +10706,9 @@ function get_form_values(gobj, $form) {
10706
10706
  else value = value_.text;
10707
10707
  }
10708
10708
  break;
10709
- case "fieldset": break;
10709
+ case "fieldset":
10710
+ value = {};
10711
+ break;
10710
10712
  case "table":
10711
10713
  let template = gobj_read_attr(gobj, "template");
10712
10714
  if (!empty_string(name) && kw_has_key(template, name)) {
@@ -10728,7 +10730,7 @@ function get_form_values(gobj, $form) {
10728
10730
  break;
10729
10731
  default: log_error(sprintf("%s: $form type unknown: '%s'", gobj_short_name(gobj), tag));
10730
10732
  }
10731
- value = form_value_2_treedb_value(gobj, field_desc, value);
10733
+ if (tag !== "fieldset") value = form_value_2_treedb_value(gobj, field_desc, value);
10732
10734
  let path;
10733
10735
  if (empty_string(prefix)) path = name;
10734
10736
  else path = prefix + "`" + name;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuneta/gobj-ui",
3
- "version": "7.26.32",
3
+ "version": "7.26.33",
4
4
  "type": "module",
5
5
  "main": "dist/gobj-ui.cjs.js",
6
6
  "module": "dist/gobj-ui.es.js",
package/src/c_yui_form.js CHANGED
@@ -2767,10 +2767,13 @@ function get_form_values(gobj, $form)
2767
2767
  break;
2768
2768
 
2769
2769
  case "fieldset":
2770
- /*
2771
- * HACK: really this is the path of the value.
2772
- * We are navigating by a tree data structure; this is one node, not a leaf.
2773
- */
2770
+ /* A NODE of the template, not a leaf: its value is the
2771
+ * dict its own fields fill, and they come after it in the
2772
+ * document. No json anybody typed, so it skips the
2773
+ * conversion below, which handed its null on (7.26.8 to
2774
+ * 7.26.32): the fields found no dict to write into and the
2775
+ * save stored the node as null. */
2776
+ value = {};
2774
2777
  break;
2775
2778
 
2776
2779
  case "table":
@@ -2811,7 +2814,9 @@ function get_form_values(gobj, $form)
2811
2814
  break;
2812
2815
  }
2813
2816
 
2814
- value = form_value_2_treedb_value(gobj, field_desc, value);
2817
+ if(tag !== "fieldset") {
2818
+ value = form_value_2_treedb_value(gobj, field_desc, value);
2819
+ }
2815
2820
  let path;
2816
2821
  if(empty_string(prefix)) {
2817
2822
  path = name;
@@ -0,0 +1,160 @@
1
+ /***********************************************************************
2
+ * form_template_field.wiring.test.js
3
+ *
4
+ * A `template` field of a C_YUI_FORM in 'exec' mode is a sub-form
5
+ * (a <fieldset>): a NODE of the record, whose value is the dict its
6
+ * own fields fill. From 7.26.8 to 7.26.32 the node went through the
7
+ * json conversion, which handed its null on: the fields below found
8
+ * no dict to write into (kw_set_dict_value() refuses a null segment)
9
+ * and the save stored the node as null -- the alarm colours of a
10
+ * device in estadodelaire, wiped by every save of its settings.
11
+ * Driven through the real gclass on a document double, with the
12
+ * template of those settings.
13
+ *
14
+ * Copyright (c) 2026, ArtGins.
15
+ * All Rights Reserved.
16
+ ***********************************************************************/
17
+ import {describe, test, expect, beforeAll, beforeEach} from "vitest";
18
+ import {install_dom_double} from "../test/dom_double.js";
19
+
20
+ install_dom_double();
21
+
22
+ if(typeof globalThis.ResizeObserver === "undefined") {
23
+ globalThis.ResizeObserver = class {
24
+ observe() {}
25
+ unobserve() {}
26
+ disconnect() {}
27
+ };
28
+ }
29
+
30
+ const {
31
+ SDATA_END, gclass_create,
32
+ gobj_start_up, gobj_create_yuno, gobj_create_pure_child,
33
+ gobj_start, gobj_send_event, gobj_read_attr,
34
+ set_log_callback,
35
+ } = await import("@yuneta/gobj-js");
36
+ const {register_c_yui_form} = await import("./c_yui_form.js");
37
+
38
+ const saved = [];
39
+ const logged = [];
40
+ let yuno = null;
41
+
42
+ /* The settings template of an estadodelaire device type, cut down to
43
+ * the sub-form and one field beside it. */
44
+ const TEMPLATE = {
45
+ template_version: {
46
+ type: "integer",
47
+ default: 7,
48
+ flag: ["hidden", "persistent"]
49
+ },
50
+ alarm_colors: {
51
+ type: "object",
52
+ flag: ["writable", "persistent", "template"],
53
+ template: {
54
+ active_not_validated: {
55
+ type: "string",
56
+ default: "red",
57
+ flag: ["writable", "persistent", "color"]
58
+ },
59
+ active_validated: {
60
+ type: "string",
61
+ default: "#e5a50a",
62
+ flag: ["writable", "persistent", "color"]
63
+ },
64
+ not_active_not_validated: {
65
+ type: "string",
66
+ default: "Fuchsia",
67
+ flag: ["writable", "persistent", "color"]
68
+ }
69
+ }
70
+ }
71
+ };
72
+
73
+ beforeAll(async () => {
74
+ const i18next = (await import("i18next")).default;
75
+ await i18next.init({lng: "en", resources: {}});
76
+ gobj_start_up(null, null, null, null, null, null, null);
77
+ set_log_callback((level, msg) => {
78
+ logged.push({level: String(level), msg: String(msg)});
79
+ });
80
+ gclass_create("C_TEST_FORM_HOST", [], [["ST_IDLE", []]], {}, 0, [SDATA_END()], {}, 0, 0, 0, 0);
81
+ gclass_create(
82
+ "C_TEST_FORM_APP",
83
+ [["EV_SAVE_RECORD", 0], ["EV_RECORD_CHANGED", 0]],
84
+ [["ST_IDLE", [
85
+ ["EV_SAVE_RECORD", (gobj, event, kw) => {
86
+ saved.push(kw);
87
+ return 0;
88
+ }, null],
89
+ ["EV_RECORD_CHANGED", () => 0, null],
90
+ ]]],
91
+ {}, 0, [SDATA_END()], {}, 0, 0, 0, 0
92
+ );
93
+ register_c_yui_form();
94
+ yuno = gobj_create_yuno("form_template_yuno", "C_TEST_FORM_HOST", {});
95
+ gobj_start(yuno);
96
+ });
97
+
98
+ beforeEach(() => {
99
+ saved.length = 0;
100
+ logged.length = 0;
101
+ });
102
+
103
+ let seq = 0;
104
+
105
+ function build(record)
106
+ {
107
+ const app = gobj_create_pure_child(`tapp${++seq}`, "C_TEST_FORM_APP", {}, yuno);
108
+ gobj_start(app);
109
+ const form = gobj_create_pure_child(`tform${seq}`, "C_YUI_FORM", {
110
+ template: TEMPLATE,
111
+ record: record,
112
+ editable: true,
113
+ }, app);
114
+ gobj_start(form);
115
+ const $c = gobj_read_attr(form, "$container");
116
+ expect($c.querySelector("fieldset")).toBeTruthy(); // exec mode: a sub-form
117
+ return form;
118
+ }
119
+
120
+ function errors()
121
+ {
122
+ return logged.filter(l => /error/i.test(l.level) || /ERROR/.test(l.msg));
123
+ }
124
+
125
+ describe("a template field in exec mode (a sub-form)", () => {
126
+ test("is saved as the dict its fields fill", () => {
127
+ const form = build({
128
+ template_version: 7,
129
+ alarm_colors: {
130
+ active_not_validated: "#ff0000",
131
+ active_validated: "#e5a50a",
132
+ not_active_not_validated: "#ff00ff"
133
+ }
134
+ });
135
+ gobj_send_event(form, "EV_SAVE_RECORD", {}, form);
136
+ expect(saved.length).toBe(1);
137
+ expect(saved[0].alarm_colors).toEqual({
138
+ active_not_validated: "#ff0000",
139
+ active_validated: "#e5a50a",
140
+ not_active_not_validated: "#ff00ff"
141
+ });
142
+ expect(saved[0].template_version).toBe(7);
143
+ expect(errors()).toEqual([]);
144
+ });
145
+
146
+ test("left null by a save before the fix, comes back with its defaults", () => {
147
+ const form = build({
148
+ template_version: 7,
149
+ alarm_colors: null
150
+ });
151
+ gobj_send_event(form, "EV_SAVE_RECORD", {}, form);
152
+ expect(saved.length).toBe(1);
153
+ expect(saved[0].alarm_colors).toEqual({
154
+ active_not_validated: "red",
155
+ active_validated: "#e5a50a",
156
+ not_active_not_validated: "Fuchsia"
157
+ });
158
+ expect(errors()).toEqual([]);
159
+ });
160
+ });