@yuneta/gobj-ui 7.25.18 → 7.25.19

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 CHANGED
@@ -227,6 +227,16 @@ seen*:
227
227
  for its treedb nodes, so the graph tab returns to `<graph>/<topic>` with its
228
228
  focus and the data tab to the topic that was open.
229
229
 
230
+ - **A node hears every event of the navs it projects** (they are its pure
231
+ children). Since `7.25.19` it declares all three, in every state -- a ZONE
232
+ projection outlives the path, so a root that is off it still hears its
233
+ rail: `EV_NAV_CLICKED` (a navigation), `EV_NAV_ITEM_CLOSE` (handed to the
234
+ shell, which re-publishes it to the app, as for the shell's own closable
235
+ items) and `EV_DRAWER_CLOSE_REQUESTED` (the node closes its own drawer
236
+ projection: the shell's `yui_shell_close_drawer()` knows only the shell's
237
+ navs). Before, the last two answered *"Event NOT DEFINED in state"*, and so
238
+ did a click on a zone nav of a root in `ST_OFF`.
239
+
230
240
  - **`nav_mode` — the three shapes as one runtime knob.** The two bullets above
231
241
  describe what a tree *declares*; `nav_mode` is how a user *chooses* between
232
242
  the shapes without the app rewriting anything:
@@ -581,7 +591,15 @@ Two layout facts the browser taught this component, both worth keeping:
581
591
  the two-view toggle did when the list was two long), plus `EV_REFRESH` /
582
592
  `EV_SHOW` / `EV_HIDE` / `EV_LANGUAGE_CHANGED`.
583
593
  - Output event: `EV_EXPAND_PATH {path, size}` (`EVF_OUTPUT_EVENT`) — the parent
584
- must declare it in its own FSM (CHILD subscription model). That is the ONLY
594
+ must declare it in its own FSM (CHILD subscription model), and ANSWER it: the
595
+ stub shows "loading" until `EV_SUBTREE_LOADED` or `EV_SUBTREE_ERROR` arrives.
596
+ A host that cannot read a subtree says so with the error, as
597
+ `C_YUI_TREEDB_TOPIC_WITH_FORM` does for its schema, cell and table viewers
598
+ since `7.25.19` (before, it declared nothing: *"Event NOT DEFINED"*):
599
+ ```js
600
+ gobj_send_event(src, "EV_SUBTREE_ERROR",
601
+ {path: kw.path, error: t("this part cannot be loaded here")}, gobj);
602
+ ``` That is the ONLY
585
603
  one, on purpose: this viewer is a child of its host and subscribes it to
586
604
  everything it publishes, so every output event is a mandatory declaration in
587
605
  every host's FSM. The graph child's `EV_JSON_ITEM_CLICKED` stops here
@@ -1003,7 +1021,7 @@ graph does not report `__graphs__`, its own bookkeeping.
1003
1021
  treedb_name: "treedb_test", // the view's own treedb
1004
1022
  topic_name: "yunos", // the topic written (the CHILD's, for a link)
1005
1023
  record: {id: "1", x: 1, y: 2}, // the node the store answered, as written
1006
- created: false, // true for create-node
1024
+ created: false, // true for a NEW record (see below)
1007
1025
  command: "update-node", // create/update/delete-node, link/unlink-nodes
1008
1026
  parent_ref: "realms^r1^yunos", // graph, link/unlink only
1009
1027
  child_ref: "yunos^1" // graph, link/unlink only
@@ -1018,6 +1036,21 @@ do -- so `treedb_name` and `record` arrived empty, and a link named no topic.
1018
1036
  delete answers the node deleted, a link the child), and a link echoes its topic
1019
1037
  and refs in `__md_command__`.
1020
1038
 
1039
+ Since `7.25.19` the topics view publishes a successful **delete** too (it
1040
+ published nothing: the answer went to an empty `break`), and `created` is
1041
+ TRUE for its **+New**: that goes out as an `update-node` with `create_only`,
1042
+ so comparing the command with `"create-node"` answered `false` for every
1043
+ record the table created. The request now echoes `created: true` in its
1044
+ `__md_command__`. The graph creates with `create-node`, and says so the same
1045
+ way.
1046
+
1047
+ ```js
1048
+ // the table's +New, answered
1049
+ {treedb_name: "treedb_test", topic_name: "users", record: {id: "n1"}, created: true, command: "update-node"}
1050
+ // a row deleted, answered with the node deleted
1051
+ {treedb_name: "treedb_test", topic_name: "roles", record: {id: "x"}, created: false, command: "delete-node"}
1052
+ ```
1053
+
1021
1054
  ### Read-only treedbs: `readonly`
1022
1055
 
1023
1056
  `C_YUI_TREEDB_TOPICS` and `C_YUI_TREEDB_GRAPH` take a **`readonly`** attr; the
@@ -1844,8 +1877,12 @@ the history buttons -- they decide the Save from `history.canUndo()`, and they
1844
1877
  run on every history change, every change of mode and every redraw of the
1845
1878
  theme -- and a refusal heard in reading was never shown. The engine now keeps
1846
1879
  the topic as owed: the Save stays lit while one is, in edition and on entering
1847
- it; the Save that writes the topic again pays it, and a reload of the data
1848
- forgets it (the view holds what the backend holds).
1880
+ it; the Save that writes the topic again pays it, a reload of the data
1881
+ forgets it (the view holds what the backend holds), and so does an ECHO of the
1882
+ topic's `__graphs__` record (since `7.25.19`): the echo is what the backend
1883
+ holds, taken as shown and as saved, so nothing is owed any more. Before, a
1884
+ refused Save #1 answered after Save #2's echo -- or another browser saving the
1885
+ topic -- left the Save lit with nothing to write until a reload.
1849
1886
 
1850
1887
  ```js
1851
1888
  gobj_send_event(engine, "EV_GRAPHS_WRITE_REFUSED", {topic: "users"}, host); // Save lit
@@ -10901,7 +10901,7 @@ function register_c_yui_map() {
10901
10901
  *
10902
10902
  * Graphics, Charts with uPlot
10903
10903
  *
10904
- * Copyright (c) 2025, ArtGins.
10904
+ * Copyright (c) 2025-2026, ArtGins.
10905
10905
  * All Rights Reserved.
10906
10906
  ***********************************************************************/
10907
10907
  /***************************************************************
@@ -11151,8 +11151,8 @@ function ac_add_serie(gobj, event, kw, src) {
11151
11151
  let colors = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "colors");
11152
11152
  if (!Array.isArray(colors) || !colors.length) colors = CHART_PALETTE;
11153
11153
  let color = colors[Math.max(0, idx - 1) % colors.length];
11154
- (0, _yuneta_gobj_js.kw_get_str)(gobj, kw, "stroke", color.stroke, _yuneta_gobj_js.kw_flag_t.KW_CREATE);
11155
- (0, _yuneta_gobj_js.kw_get_str)(gobj, kw, "fill", color.fill, _yuneta_gobj_js.kw_flag_t.KW_CREATE);
11154
+ if (kw.stroke === void 0) kw.stroke = color.stroke;
11155
+ if (kw.fill === void 0) kw.fill = color.fill;
11156
11156
  uplot$4.addSeries(kw);
11157
11157
  return 0;
11158
11158
  }
@@ -16020,7 +16020,7 @@ function ac_hide_diff(gobj, event, kw, src) {
16020
16020
  * document has no backend to ask for it: the SOURCE truncated
16021
16021
  * it, and that is the answer, to the viewer that asked.
16022
16022
  ***************************************************************/
16023
- function ac_expand_path(gobj, event, kw, src) {
16023
+ function ac_expand_path$1(gobj, event, kw, src) {
16024
16024
  (0, _yuneta_gobj_js.gobj_send_event)(src, "EV_SUBTREE_ERROR", {
16025
16025
  path: kw && kw.path || "",
16026
16026
  error: (0, i18next.t)("collapsed in the source")
@@ -16081,7 +16081,7 @@ function create_gclass$12(gclass_name) {
16081
16081
  ],
16082
16082
  [
16083
16083
  "EV_EXPAND_PATH",
16084
- ac_expand_path,
16084
+ ac_expand_path$1,
16085
16085
  null
16086
16086
  ]
16087
16087
  ]],
@@ -16118,7 +16118,7 @@ function create_gclass$12(gclass_name) {
16118
16118
  ],
16119
16119
  [
16120
16120
  "EV_EXPAND_PATH",
16121
- ac_expand_path,
16121
+ ac_expand_path$1,
16122
16122
  null
16123
16123
  ]
16124
16124
  ]],
@@ -24937,7 +24937,7 @@ function answered_record$1(data) {
24937
24937
  /************************************************************
24938
24938
  * Command to remote service
24939
24939
  ************************************************************/
24940
- function treedb_update_node$1(gobj, treedb_name, topic_name, record, options, form_write) {
24940
+ function treedb_update_node$1(gobj, treedb_name, topic_name, record, options, form_write, created) {
24941
24941
  let command = "update-node";
24942
24942
  let gobj_remote_yuno = (0, _yuneta_gobj_js.gobj_read_pointer_attr)(gobj, "gobj_remote_yuno");
24943
24943
  let kw = {
@@ -24949,6 +24949,7 @@ function treedb_update_node$1(gobj, treedb_name, topic_name, record, options, fo
24949
24949
  };
24950
24950
  kw.__md_command__ = { topic_name };
24951
24951
  if (form_write) kw.__md_command__.form_write = form_write;
24952
+ if (created) kw.__md_command__.created = true;
24952
24953
  let ret = (0, _yuneta_gobj_js.gobj_command)(gobj_remote_yuno, command, kw, gobj);
24953
24954
  if (ret) {
24954
24955
  (0, _yuneta_gobj_js.log_error)(ret);
@@ -24972,7 +24973,11 @@ function treedb_delete_node$1(gobj, treedb_name, topic_name, record, options) {
24972
24973
  };
24973
24974
  kw.__md_command__ = { topic_name };
24974
24975
  let ret = (0, _yuneta_gobj_js.gobj_command)(gobj_remote_yuno, command, kw, gobj);
24975
- if (ret) (0, _yuneta_gobj_js.log_error)(ret);
24976
+ if (ret) {
24977
+ (0, _yuneta_gobj_js.log_error)(ret);
24978
+ return -1;
24979
+ }
24980
+ return 0;
24976
24981
  }
24977
24982
  /************************************************************
24978
24983
  * True on a phone-width viewport (Bulma's mobile breakpoint).
@@ -25255,17 +25260,18 @@ function ac_mt_command_answer$2(gobj, event, kw, src) {
25255
25260
  break;
25256
25261
  case "create-node":
25257
25262
  case "update-node":
25263
+ case "delete-node":
25258
25264
  (0, _yuneta_gobj_js.gobj_publish_event)(gobj, "EV_RECORD_WRITTEN", {
25259
25265
  treedb_name: (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "treedb_name"),
25260
25266
  topic_name: (0, _yuneta_gobj_js.kw_get_str)(gobj, kw_command, "topic_name", "", 0),
25261
25267
  record: answered_record$1(data),
25262
- created: command === "create-node",
25268
+ created: command === "create-node" || kw_command.created === true,
25263
25269
  command
25264
25270
  });
25271
+ if (command === "delete-node") break;
25265
25272
  settle_form_write(gobj.priv.form_writes, (0, _yuneta_gobj_js.kw_get_int)(gobj, kw_command, "form_write", 0, 0), (0, _yuneta_gobj_js.kw_get_str)(gobj, kw_command, "topic_name", "", 0));
25266
25273
  answer_form_write(gobj, get_gobj_formtable(gobj, (0, _yuneta_gobj_js.kw_get_str)(gobj, kw_command, "topic_name", "", 0)), (0, _yuneta_gobj_js.kw_get_int)(gobj, kw_command, "form_write", 0, 0), true);
25267
25274
  break;
25268
- case "delete-node": break;
25269
25275
  default: (0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)} Command unknown: ${command}`);
25270
25276
  }
25271
25277
  return 0;
@@ -25533,7 +25539,7 @@ function ac_create_record(gobj, event, kw, src) {
25533
25539
  create: true,
25534
25540
  create_only: true,
25535
25541
  autolink: true
25536
- }, form_write) < 0) {
25542
+ }, form_write, true) < 0) {
25537
25543
  answer_form_write(gobj, src, form_write, false);
25538
25544
  return -1;
25539
25545
  }
@@ -29451,6 +29457,24 @@ function refuse_if_readonly$2(gobj, event) {
29451
29457
  * From external, at the beginning, load all topic data
29452
29458
  ************************************************************/
29453
29459
  /***************************************************************
29460
+ * One of MY json viewers (the schema, a cell, the table's records)
29461
+ * met a `__collapsed__` sentinel and the reader opened it. The
29462
+ * viewer never fetches: it asks its host, and waits on "loading"
29463
+ * until it is answered. This view holds records, not a store it can
29464
+ * read a subtree of -- the lazy drill is `print-tranger`, which the
29465
+ * TOPICS view runs for its own viewer, over a whole tranger -- so the
29466
+ * answer is that it cannot, and the viewer shows that on the stub
29467
+ * instead of loading for ever.
29468
+ ***************************************************************/
29469
+ function ac_expand_path(gobj, event, kw, src) {
29470
+ let path = kw && kw.path || "";
29471
+ (0, _yuneta_gobj_js.gobj_send_event)(src, "EV_SUBTREE_ERROR", {
29472
+ path,
29473
+ error: (0, i18next.t)("this part cannot be loaded here")
29474
+ }, gobj);
29475
+ return 0;
29476
+ }
29477
+ /***************************************************************
29454
29478
  * The language changed (the shell publishes it after the app switched).
29455
29479
  *
29456
29480
  * The column headers carry their key (col_label's title formatter emits a
@@ -30744,6 +30768,11 @@ function create_gclass$5(gclass_name) {
30744
30768
  ac_show_schema,
30745
30769
  null
30746
30770
  ],
30771
+ [
30772
+ "EV_EXPAND_PATH",
30773
+ ac_expand_path,
30774
+ null
30775
+ ],
30747
30776
  [
30748
30777
  "EV_CELL_EDITED",
30749
30778
  ac_cell_edited,
@@ -30859,6 +30888,7 @@ function create_gclass$5(gclass_name) {
30859
30888
  ["EV_CHANGE_LOCALE", 0],
30860
30889
  ["EV_REFRESH", 0],
30861
30890
  ["EV_SHOW_SCHEMA", 0],
30891
+ ["EV_EXPAND_PATH", 0],
30862
30892
  ["EV_CELL_EDITED", 0],
30863
30893
  ["EV_REPULL_PAGE", 0],
30864
30894
  ["EV_PAGE_LOADED", 0],
@@ -65876,6 +65906,22 @@ function ac_graphs_write_refused(gobj, event, kw, src) {
65876
65906
  return 0;
65877
65907
  }
65878
65908
  /************************************************************
65909
+ * An echo of a `__graphs__` record is what the backend holds for
65910
+ * its topic now, and the view has just taken it as shown and as
65911
+ * saved: a write of that topic owed from an earlier refusal is
65912
+ * owed no more. Left owed, the Save stayed lit with nothing to
65913
+ * write -- the plan compares the two, and they are equal -- until
65914
+ * a reload: a refused Save #1 answered after Save #2 landed, or
65915
+ * another browser saving the topic, did exactly that.
65916
+ ************************************************************/
65917
+ function settle_owed_graphs_write(gobj, rec) {
65918
+ let priv = gobj.priv;
65919
+ let topic_name = rec && rec.topic;
65920
+ if (!topic_name || !priv._graphs_writes_owed[topic_name]) return;
65921
+ delete priv._graphs_writes_owed[topic_name];
65922
+ update_history_buttons(gobj);
65923
+ }
65924
+ /************************************************************
65879
65925
  * Node created, from subscription
65880
65926
  ************************************************************/
65881
65927
  function ac_node_created(gobj, event, kw, src) {
@@ -65887,6 +65933,7 @@ function ac_node_created(gobj, event, kw, src) {
65887
65933
  if (topic_name === "__graphs__") {
65888
65934
  priv.__graphs__.push(node);
65889
65935
  build_graph_properties(gobj);
65936
+ settle_owed_graphs_write(gobj, node);
65890
65937
  return 0;
65891
65938
  }
65892
65939
  if (!priv.descs[topic_name]) {
@@ -65922,6 +65969,7 @@ function ac_node_updated(gobj, event, kw, src) {
65922
65969
  }
65923
65970
  if (!found) priv.__graphs__.push(node);
65924
65971
  apply_graphs_echo(priv._graph_properties, priv._saved_graph_properties, priv.__graphs__, node);
65972
+ settle_owed_graphs_write(gobj, node);
65925
65973
  return 0;
65926
65974
  }
65927
65975
  let desc = priv.descs[topic_name];
@@ -72956,8 +73004,12 @@ function current_topic(gobj) {
72956
73004
  * One line for what the whole view has to say: loading, empty,
72957
73005
  * or the reason nothing loaded. Carries its i18n key, so it
72958
73006
  * follows a language change like any other text.
73007
+ *
73008
+ * `detail` is a NAME (a treedb, a topic) shown as it is, unless
73009
+ * `detail_is_key` says it is a key: a name is not text to
73010
+ * translate, and a topic called `nodes` is not "Nodos".
72959
73011
  ***************************************************************/
72960
- function show_notice(gobj, key, detail) {
73012
+ function show_notice(gobj, key, detail, detail_is_key) {
72961
73013
  let $notice = $of(gobj, ".SCHEMA_NOTICE");
72962
73014
  if (!$notice) return;
72963
73015
  clear($notice);
@@ -72974,14 +73026,15 @@ function show_notice(gobj, key, detail) {
72974
73026
  },
72975
73027
  (0, i18next.t)(key)
72976
73028
  ]));
72977
- if (detail && detail !== key) $notice.appendChild((0, _yuneta_gobj_js.createElement2)([
72978
- "span",
72979
- {
72980
- class: "SCHEMA_NOTICE_DETAIL yui-text-quiet ml-2",
72981
- i18n: `${detail}`
72982
- },
72983
- (0, i18next.t)(`${detail}`)
72984
- ]));
73029
+ if (detail && detail !== key) {
73030
+ let attrs = { class: "SCHEMA_NOTICE_DETAIL yui-text-quiet ml-2" };
73031
+ if (detail_is_key) attrs.i18n = `${detail}`;
73032
+ $notice.appendChild((0, _yuneta_gobj_js.createElement2)([
73033
+ "span",
73034
+ attrs,
73035
+ detail_is_key ? (0, i18next.t)(`${detail}`) : `${detail}`
73036
+ ]));
73037
+ }
72985
73038
  }
72986
73039
  /***************************************************************
72987
73040
  * A button of the toolbar. Every one carries an icon and a
@@ -73168,7 +73221,7 @@ function render(gobj) {
73168
73221
  return;
73169
73222
  }
73170
73223
  if (state === "ST_IDLE") {
73171
- show_notice(gobj, priv.load_error ? "cannot load the schemas" : "not connected", priv.load_error);
73224
+ show_notice(gobj, priv.load_error ? "cannot load the schemas" : "not connected", priv.load_error, true);
73172
73225
  destroy_diagram(gobj);
73173
73226
  clear($body);
73174
73227
  return;
@@ -10896,7 +10896,7 @@ function register_c_yui_map() {
10896
10896
  *
10897
10897
  * Graphics, Charts with uPlot
10898
10898
  *
10899
- * Copyright (c) 2025, ArtGins.
10899
+ * Copyright (c) 2025-2026, ArtGins.
10900
10900
  * All Rights Reserved.
10901
10901
  ***********************************************************************/
10902
10902
  /***************************************************************
@@ -11146,8 +11146,8 @@ function ac_add_serie(gobj, event, kw, src) {
11146
11146
  let colors = gobj_read_attr(gobj, "colors");
11147
11147
  if (!Array.isArray(colors) || !colors.length) colors = CHART_PALETTE;
11148
11148
  let color = colors[Math.max(0, idx - 1) % colors.length];
11149
- kw_get_str(gobj, kw, "stroke", color.stroke, kw_flag_t.KW_CREATE);
11150
- kw_get_str(gobj, kw, "fill", color.fill, kw_flag_t.KW_CREATE);
11149
+ if (kw.stroke === void 0) kw.stroke = color.stroke;
11150
+ if (kw.fill === void 0) kw.fill = color.fill;
11151
11151
  uplot.addSeries(kw);
11152
11152
  return 0;
11153
11153
  }
@@ -16015,7 +16015,7 @@ function ac_hide_diff(gobj, event, kw, src) {
16015
16015
  * document has no backend to ask for it: the SOURCE truncated
16016
16016
  * it, and that is the answer, to the viewer that asked.
16017
16017
  ***************************************************************/
16018
- function ac_expand_path(gobj, event, kw, src) {
16018
+ function ac_expand_path$1(gobj, event, kw, src) {
16019
16019
  gobj_send_event(src, "EV_SUBTREE_ERROR", {
16020
16020
  path: kw && kw.path || "",
16021
16021
  error: t("collapsed in the source")
@@ -16076,7 +16076,7 @@ function create_gclass$12(gclass_name) {
16076
16076
  ],
16077
16077
  [
16078
16078
  "EV_EXPAND_PATH",
16079
- ac_expand_path,
16079
+ ac_expand_path$1,
16080
16080
  null
16081
16081
  ]
16082
16082
  ]],
@@ -16113,7 +16113,7 @@ function create_gclass$12(gclass_name) {
16113
16113
  ],
16114
16114
  [
16115
16115
  "EV_EXPAND_PATH",
16116
- ac_expand_path,
16116
+ ac_expand_path$1,
16117
16117
  null
16118
16118
  ]
16119
16119
  ]],
@@ -24932,7 +24932,7 @@ function answered_record$1(data) {
24932
24932
  /************************************************************
24933
24933
  * Command to remote service
24934
24934
  ************************************************************/
24935
- function treedb_update_node$1(gobj, treedb_name, topic_name, record, options, form_write) {
24935
+ function treedb_update_node$1(gobj, treedb_name, topic_name, record, options, form_write, created) {
24936
24936
  let command = "update-node";
24937
24937
  let gobj_remote_yuno = gobj_read_pointer_attr(gobj, "gobj_remote_yuno");
24938
24938
  let kw = {
@@ -24944,6 +24944,7 @@ function treedb_update_node$1(gobj, treedb_name, topic_name, record, options, fo
24944
24944
  };
24945
24945
  kw.__md_command__ = { topic_name };
24946
24946
  if (form_write) kw.__md_command__.form_write = form_write;
24947
+ if (created) kw.__md_command__.created = true;
24947
24948
  let ret = gobj_command(gobj_remote_yuno, command, kw, gobj);
24948
24949
  if (ret) {
24949
24950
  log_error(ret);
@@ -24967,7 +24968,11 @@ function treedb_delete_node$1(gobj, treedb_name, topic_name, record, options) {
24967
24968
  };
24968
24969
  kw.__md_command__ = { topic_name };
24969
24970
  let ret = gobj_command(gobj_remote_yuno, command, kw, gobj);
24970
- if (ret) log_error(ret);
24971
+ if (ret) {
24972
+ log_error(ret);
24973
+ return -1;
24974
+ }
24975
+ return 0;
24971
24976
  }
24972
24977
  /************************************************************
24973
24978
  * True on a phone-width viewport (Bulma's mobile breakpoint).
@@ -25250,17 +25255,18 @@ function ac_mt_command_answer$2(gobj, event, kw, src) {
25250
25255
  break;
25251
25256
  case "create-node":
25252
25257
  case "update-node":
25258
+ case "delete-node":
25253
25259
  gobj_publish_event(gobj, "EV_RECORD_WRITTEN", {
25254
25260
  treedb_name: gobj_read_str_attr(gobj, "treedb_name"),
25255
25261
  topic_name: kw_get_str(gobj, kw_command, "topic_name", "", 0),
25256
25262
  record: answered_record$1(data),
25257
- created: command === "create-node",
25263
+ created: command === "create-node" || kw_command.created === true,
25258
25264
  command
25259
25265
  });
25266
+ if (command === "delete-node") break;
25260
25267
  settle_form_write(gobj.priv.form_writes, kw_get_int(gobj, kw_command, "form_write", 0, 0), kw_get_str(gobj, kw_command, "topic_name", "", 0));
25261
25268
  answer_form_write(gobj, get_gobj_formtable(gobj, kw_get_str(gobj, kw_command, "topic_name", "", 0)), kw_get_int(gobj, kw_command, "form_write", 0, 0), true);
25262
25269
  break;
25263
- case "delete-node": break;
25264
25270
  default: log_error(`${gobj_short_name(gobj)} Command unknown: ${command}`);
25265
25271
  }
25266
25272
  return 0;
@@ -25528,7 +25534,7 @@ function ac_create_record(gobj, event, kw, src) {
25528
25534
  create: true,
25529
25535
  create_only: true,
25530
25536
  autolink: true
25531
- }, form_write) < 0) {
25537
+ }, form_write, true) < 0) {
25532
25538
  answer_form_write(gobj, src, form_write, false);
25533
25539
  return -1;
25534
25540
  }
@@ -29446,6 +29452,24 @@ function refuse_if_readonly$2(gobj, event) {
29446
29452
  * From external, at the beginning, load all topic data
29447
29453
  ************************************************************/
29448
29454
  /***************************************************************
29455
+ * One of MY json viewers (the schema, a cell, the table's records)
29456
+ * met a `__collapsed__` sentinel and the reader opened it. The
29457
+ * viewer never fetches: it asks its host, and waits on "loading"
29458
+ * until it is answered. This view holds records, not a store it can
29459
+ * read a subtree of -- the lazy drill is `print-tranger`, which the
29460
+ * TOPICS view runs for its own viewer, over a whole tranger -- so the
29461
+ * answer is that it cannot, and the viewer shows that on the stub
29462
+ * instead of loading for ever.
29463
+ ***************************************************************/
29464
+ function ac_expand_path(gobj, event, kw, src) {
29465
+ let path = kw && kw.path || "";
29466
+ gobj_send_event(src, "EV_SUBTREE_ERROR", {
29467
+ path,
29468
+ error: t("this part cannot be loaded here")
29469
+ }, gobj);
29470
+ return 0;
29471
+ }
29472
+ /***************************************************************
29449
29473
  * The language changed (the shell publishes it after the app switched).
29450
29474
  *
29451
29475
  * The column headers carry their key (col_label's title formatter emits a
@@ -30739,6 +30763,11 @@ function create_gclass$5(gclass_name) {
30739
30763
  ac_show_schema,
30740
30764
  null
30741
30765
  ],
30766
+ [
30767
+ "EV_EXPAND_PATH",
30768
+ ac_expand_path,
30769
+ null
30770
+ ],
30742
30771
  [
30743
30772
  "EV_CELL_EDITED",
30744
30773
  ac_cell_edited,
@@ -30854,6 +30883,7 @@ function create_gclass$5(gclass_name) {
30854
30883
  ["EV_CHANGE_LOCALE", 0],
30855
30884
  ["EV_REFRESH", 0],
30856
30885
  ["EV_SHOW_SCHEMA", 0],
30886
+ ["EV_EXPAND_PATH", 0],
30857
30887
  ["EV_CELL_EDITED", 0],
30858
30888
  ["EV_REPULL_PAGE", 0],
30859
30889
  ["EV_PAGE_LOADED", 0],
@@ -65871,6 +65901,22 @@ function ac_graphs_write_refused(gobj, event, kw, src) {
65871
65901
  return 0;
65872
65902
  }
65873
65903
  /************************************************************
65904
+ * An echo of a `__graphs__` record is what the backend holds for
65905
+ * its topic now, and the view has just taken it as shown and as
65906
+ * saved: a write of that topic owed from an earlier refusal is
65907
+ * owed no more. Left owed, the Save stayed lit with nothing to
65908
+ * write -- the plan compares the two, and they are equal -- until
65909
+ * a reload: a refused Save #1 answered after Save #2 landed, or
65910
+ * another browser saving the topic, did exactly that.
65911
+ ************************************************************/
65912
+ function settle_owed_graphs_write(gobj, rec) {
65913
+ let priv = gobj.priv;
65914
+ let topic_name = rec && rec.topic;
65915
+ if (!topic_name || !priv._graphs_writes_owed[topic_name]) return;
65916
+ delete priv._graphs_writes_owed[topic_name];
65917
+ update_history_buttons(gobj);
65918
+ }
65919
+ /************************************************************
65874
65920
  * Node created, from subscription
65875
65921
  ************************************************************/
65876
65922
  function ac_node_created(gobj, event, kw, src) {
@@ -65882,6 +65928,7 @@ function ac_node_created(gobj, event, kw, src) {
65882
65928
  if (topic_name === "__graphs__") {
65883
65929
  priv.__graphs__.push(node);
65884
65930
  build_graph_properties(gobj);
65931
+ settle_owed_graphs_write(gobj, node);
65885
65932
  return 0;
65886
65933
  }
65887
65934
  if (!priv.descs[topic_name]) {
@@ -65917,6 +65964,7 @@ function ac_node_updated(gobj, event, kw, src) {
65917
65964
  }
65918
65965
  if (!found) priv.__graphs__.push(node);
65919
65966
  apply_graphs_echo(priv._graph_properties, priv._saved_graph_properties, priv.__graphs__, node);
65967
+ settle_owed_graphs_write(gobj, node);
65920
65968
  return 0;
65921
65969
  }
65922
65970
  let desc = priv.descs[topic_name];
@@ -72951,8 +72999,12 @@ function current_topic(gobj) {
72951
72999
  * One line for what the whole view has to say: loading, empty,
72952
73000
  * or the reason nothing loaded. Carries its i18n key, so it
72953
73001
  * follows a language change like any other text.
73002
+ *
73003
+ * `detail` is a NAME (a treedb, a topic) shown as it is, unless
73004
+ * `detail_is_key` says it is a key: a name is not text to
73005
+ * translate, and a topic called `nodes` is not "Nodos".
72954
73006
  ***************************************************************/
72955
- function show_notice(gobj, key, detail) {
73007
+ function show_notice(gobj, key, detail, detail_is_key) {
72956
73008
  let $notice = $of(gobj, ".SCHEMA_NOTICE");
72957
73009
  if (!$notice) return;
72958
73010
  clear($notice);
@@ -72969,14 +73021,15 @@ function show_notice(gobj, key, detail) {
72969
73021
  },
72970
73022
  t(key)
72971
73023
  ]));
72972
- if (detail && detail !== key) $notice.appendChild(createElement2([
72973
- "span",
72974
- {
72975
- class: "SCHEMA_NOTICE_DETAIL yui-text-quiet ml-2",
72976
- i18n: `${detail}`
72977
- },
72978
- t(`${detail}`)
72979
- ]));
73024
+ if (detail && detail !== key) {
73025
+ let attrs = { class: "SCHEMA_NOTICE_DETAIL yui-text-quiet ml-2" };
73026
+ if (detail_is_key) attrs.i18n = `${detail}`;
73027
+ $notice.appendChild(createElement2([
73028
+ "span",
73029
+ attrs,
73030
+ detail_is_key ? t(`${detail}`) : `${detail}`
73031
+ ]));
73032
+ }
72980
73033
  }
72981
73034
  /***************************************************************
72982
73035
  * A button of the toolbar. Every one carries an icon and a
@@ -73163,7 +73216,7 @@ function render(gobj) {
73163
73216
  return;
73164
73217
  }
73165
73218
  if (state === "ST_IDLE") {
73166
- show_notice(gobj, priv.load_error ? "cannot load the schemas" : "not connected", priv.load_error);
73219
+ show_notice(gobj, priv.load_error ? "cannot load the schemas" : "not connected", priv.load_error, true);
73167
73220
  destroy_diagram(gobj);
73168
73221
  clear($body);
73169
73222
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuneta/gobj-ui",
3
- "version": "7.25.18",
3
+ "version": "7.25.19",
4
4
  "type": "module",
5
5
  "main": "dist/gobj-ui.cjs.js",
6
6
  "module": "dist/gobj-ui.es.js",
@@ -30,7 +30,7 @@
30
30
  "devDependencies": {
31
31
  "@rollup/plugin-terser": "^1.0.0",
32
32
  "@vitest/coverage-v8": "^4.1.10",
33
- "@yuneta/gobj-js": "^7.25.3",
33
+ "@yuneta/gobj-js": "^7.25.5",
34
34
  "vite": "^8.2.1",
35
35
  "vitest": "^4.1.10"
36
36
  },
@@ -10565,6 +10565,27 @@ function ac_graphs_write_refused(gobj, event, kw, src)
10565
10565
  return 0;
10566
10566
  }
10567
10567
 
10568
+ /************************************************************
10569
+ * An echo of a `__graphs__` record is what the backend holds for
10570
+ * its topic now, and the view has just taken it as shown and as
10571
+ * saved: a write of that topic owed from an earlier refusal is
10572
+ * owed no more. Left owed, the Save stayed lit with nothing to
10573
+ * write -- the plan compares the two, and they are equal -- until
10574
+ * a reload: a refused Save #1 answered after Save #2 landed, or
10575
+ * another browser saving the topic, did exactly that.
10576
+ ************************************************************/
10577
+ function settle_owed_graphs_write(gobj, rec)
10578
+ {
10579
+ let priv = gobj.priv;
10580
+ let topic_name = rec && rec.topic;
10581
+
10582
+ if(!topic_name || !priv._graphs_writes_owed[topic_name]) {
10583
+ return;
10584
+ }
10585
+ delete priv._graphs_writes_owed[topic_name];
10586
+ update_history_buttons(gobj);
10587
+ }
10588
+
10568
10589
  /************************************************************
10569
10590
  * Node created, from subscription
10570
10591
  ************************************************************/
@@ -10583,6 +10604,7 @@ function ac_node_created(gobj, event, kw, src)
10583
10604
  if(topic_name === '__graphs__') {
10584
10605
  priv.__graphs__.push(node);
10585
10606
  build_graph_properties(gobj);
10607
+ settle_owed_graphs_write(gobj, node);
10586
10608
  return 0;
10587
10609
  }
10588
10610
 
@@ -10649,6 +10671,7 @@ function ac_node_updated(gobj, event, kw, src)
10649
10671
  apply_graphs_echo(
10650
10672
  priv._graph_properties, priv._saved_graph_properties, priv.__graphs__, node
10651
10673
  );
10674
+ settle_owed_graphs_write(gobj, node);
10652
10675
  return 0;
10653
10676
  }
10654
10677