@yuneta/gobj-ui 7.25.18 → 7.25.20
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 +87 -8
- package/dist/gobj-ui.cjs.js +151 -43
- package/dist/gobj-ui.es.js +151 -43
- package/package.json +2 -2
- package/src/c_g6_nodes_tree.js +52 -4
- package/src/c_yui_json.js +28 -5
- package/src/c_yui_json_pad.js +3 -2
- package/src/c_yui_node.js +71 -0
- package/src/c_yui_schema_editor.js +34 -11
- package/src/c_yui_treedb_graph.js +24 -10
- package/src/c_yui_treedb_topic_with_form.js +24 -0
- package/src/c_yui_treedb_topics.js +22 -9
- package/src/c_yui_uplot.js +10 -5
- package/src/form_json_expand.wiring.test.js +204 -0
- package/src/g6_graphs_write_owed.wiring.test.js +114 -0
- package/src/node_nav_events.wiring.test.js +150 -0
- package/src/schema_editor_reload.wiring.test.js +37 -0
- package/src/schema_editor_transport.wiring.test.js +89 -5
- package/src/treedb_graph_writes.wiring.test.js +38 -4
- package/src/treedb_topics_transport.wiring.test.js +89 -0
- package/src/uplot_add_serie.test.js +92 -0
package/dist/gobj-ui.es.js
CHANGED
|
@@ -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
|
-
|
|
11150
|
-
|
|
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
|
}
|
|
@@ -14738,10 +14738,18 @@ function push_collapsed_row(ctx, value, segments, depth, key, rows) {
|
|
|
14738
14738
|
},
|
|
14739
14739
|
is_pending ? "loading" : "click to load"
|
|
14740
14740
|
]);
|
|
14741
|
-
if (err) children.push([
|
|
14741
|
+
if (err && err.is_key) children.push([
|
|
14742
|
+
"span",
|
|
14743
|
+
{
|
|
14744
|
+
class: "JSON_STUB_ERR has-text-danger is-size-7 ml-2",
|
|
14745
|
+
"data-i18n": err.error
|
|
14746
|
+
},
|
|
14747
|
+
t(err.error)
|
|
14748
|
+
]);
|
|
14749
|
+
else if (err) children.push([
|
|
14742
14750
|
"span",
|
|
14743
14751
|
{ class: "JSON_STUB_ERR has-text-danger is-size-7 ml-2" },
|
|
14744
|
-
String(err)
|
|
14752
|
+
String(err.error)
|
|
14745
14753
|
]);
|
|
14746
14754
|
let attrs = {
|
|
14747
14755
|
class: "JSON_ROW JSON_COLLAPSED" + (is_pending ? " is-pending" : ""),
|
|
@@ -14958,14 +14966,32 @@ function ac_subtree_loaded(gobj, event, kw, src) {
|
|
|
14958
14966
|
return 0;
|
|
14959
14967
|
}
|
|
14960
14968
|
/************************************************************
|
|
14961
|
-
* EV_SUBTREE_ERROR { path, error
|
|
14969
|
+
* EV_SUBTREE_ERROR { path, error | i18n, by_design }
|
|
14970
|
+
* — mark the branch that was not loaded.
|
|
14971
|
+
*
|
|
14972
|
+
* `error` is text, drawn as it came (a backend's comment).
|
|
14973
|
+
* `i18n` is a KEY, drawn as t(key) with data-i18n so the stub
|
|
14974
|
+
* changes language with the app (a text translated by the host
|
|
14975
|
+
* stays in the language it was sent in). The name is the one a
|
|
14976
|
+
* locale check scans for (`i18n: "<key>"`), so the key of every
|
|
14977
|
+
* host stays visible to it.
|
|
14978
|
+
* `by_design`: the host answers that it CANNOT read a subtree
|
|
14979
|
+
* (a form holds records, a pasted pad has no backend) -- that is
|
|
14980
|
+
* not a failure, and it is logged as a warning. Anything else is
|
|
14981
|
+
* a load that failed, logged as an error.
|
|
14962
14982
|
************************************************************/
|
|
14963
14983
|
function ac_subtree_error(gobj, event, kw, src) {
|
|
14964
14984
|
let priv = gobj.priv;
|
|
14965
14985
|
let path = kw.path || "";
|
|
14986
|
+
let is_key = !!kw.i18n;
|
|
14987
|
+
let error = kw.i18n || kw.error || "error";
|
|
14966
14988
|
priv.pending.delete(path);
|
|
14967
|
-
priv.errors.set(path,
|
|
14968
|
-
|
|
14989
|
+
priv.errors.set(path, {
|
|
14990
|
+
error,
|
|
14991
|
+
is_key
|
|
14992
|
+
});
|
|
14993
|
+
if (kw.by_design) log_warning(`${GCLASS_NAME$13}: subtree not loaded at '${path}': ${error}`);
|
|
14994
|
+
else log_error(`${GCLASS_NAME$13}: subtree load failed at '${path}': ${error}`);
|
|
14969
14995
|
render_view$1(gobj);
|
|
14970
14996
|
return 0;
|
|
14971
14997
|
}
|
|
@@ -16015,10 +16041,11 @@ function ac_hide_diff(gobj, event, kw, src) {
|
|
|
16015
16041
|
* document has no backend to ask for it: the SOURCE truncated
|
|
16016
16042
|
* it, and that is the answer, to the viewer that asked.
|
|
16017
16043
|
***************************************************************/
|
|
16018
|
-
function ac_expand_path(gobj, event, kw, src) {
|
|
16044
|
+
function ac_expand_path$1(gobj, event, kw, src) {
|
|
16019
16045
|
gobj_send_event(src, "EV_SUBTREE_ERROR", {
|
|
16020
16046
|
path: kw && kw.path || "",
|
|
16021
|
-
|
|
16047
|
+
i18n: "collapsed in the source",
|
|
16048
|
+
by_design: true
|
|
16022
16049
|
}, gobj);
|
|
16023
16050
|
return 0;
|
|
16024
16051
|
}
|
|
@@ -16076,7 +16103,7 @@ function create_gclass$12(gclass_name) {
|
|
|
16076
16103
|
],
|
|
16077
16104
|
[
|
|
16078
16105
|
"EV_EXPAND_PATH",
|
|
16079
|
-
ac_expand_path,
|
|
16106
|
+
ac_expand_path$1,
|
|
16080
16107
|
null
|
|
16081
16108
|
]
|
|
16082
16109
|
]],
|
|
@@ -16113,7 +16140,7 @@ function create_gclass$12(gclass_name) {
|
|
|
16113
16140
|
],
|
|
16114
16141
|
[
|
|
16115
16142
|
"EV_EXPAND_PATH",
|
|
16116
|
-
ac_expand_path,
|
|
16143
|
+
ac_expand_path$1,
|
|
16117
16144
|
null
|
|
16118
16145
|
]
|
|
16119
16146
|
]],
|
|
@@ -24932,7 +24959,7 @@ function answered_record$1(data) {
|
|
|
24932
24959
|
/************************************************************
|
|
24933
24960
|
* Command to remote service
|
|
24934
24961
|
************************************************************/
|
|
24935
|
-
function treedb_update_node$1(gobj, treedb_name, topic_name, record, options, form_write) {
|
|
24962
|
+
function treedb_update_node$1(gobj, treedb_name, topic_name, record, options, form_write, created) {
|
|
24936
24963
|
let command = "update-node";
|
|
24937
24964
|
let gobj_remote_yuno = gobj_read_pointer_attr(gobj, "gobj_remote_yuno");
|
|
24938
24965
|
let kw = {
|
|
@@ -24944,6 +24971,7 @@ function treedb_update_node$1(gobj, treedb_name, topic_name, record, options, fo
|
|
|
24944
24971
|
};
|
|
24945
24972
|
kw.__md_command__ = { topic_name };
|
|
24946
24973
|
if (form_write) kw.__md_command__.form_write = form_write;
|
|
24974
|
+
if (created) kw.__md_command__.created = true;
|
|
24947
24975
|
let ret = gobj_command(gobj_remote_yuno, command, kw, gobj);
|
|
24948
24976
|
if (ret) {
|
|
24949
24977
|
log_error(ret);
|
|
@@ -24967,7 +24995,11 @@ function treedb_delete_node$1(gobj, treedb_name, topic_name, record, options) {
|
|
|
24967
24995
|
};
|
|
24968
24996
|
kw.__md_command__ = { topic_name };
|
|
24969
24997
|
let ret = gobj_command(gobj_remote_yuno, command, kw, gobj);
|
|
24970
|
-
if (ret)
|
|
24998
|
+
if (ret) {
|
|
24999
|
+
log_error(ret);
|
|
25000
|
+
return -1;
|
|
25001
|
+
}
|
|
25002
|
+
return 0;
|
|
24971
25003
|
}
|
|
24972
25004
|
/************************************************************
|
|
24973
25005
|
* True on a phone-width viewport (Bulma's mobile breakpoint).
|
|
@@ -25109,7 +25141,7 @@ function request_print_tranger$1(gobj, path) {
|
|
|
25109
25141
|
let jv = priv.json_gobj;
|
|
25110
25142
|
if (path && jv && is_gobj(jv) && !gobj_is_destroying(jv)) gobj_send_event(jv, "EV_SUBTREE_ERROR", {
|
|
25111
25143
|
path,
|
|
25112
|
-
|
|
25144
|
+
i18n: "no session"
|
|
25113
25145
|
}, gobj);
|
|
25114
25146
|
return;
|
|
25115
25147
|
}
|
|
@@ -25250,17 +25282,18 @@ function ac_mt_command_answer$2(gobj, event, kw, src) {
|
|
|
25250
25282
|
break;
|
|
25251
25283
|
case "create-node":
|
|
25252
25284
|
case "update-node":
|
|
25285
|
+
case "delete-node":
|
|
25253
25286
|
gobj_publish_event(gobj, "EV_RECORD_WRITTEN", {
|
|
25254
25287
|
treedb_name: gobj_read_str_attr(gobj, "treedb_name"),
|
|
25255
25288
|
topic_name: kw_get_str(gobj, kw_command, "topic_name", "", 0),
|
|
25256
25289
|
record: answered_record$1(data),
|
|
25257
|
-
created: command === "create-node",
|
|
25290
|
+
created: command === "create-node" || kw_command.created === true,
|
|
25258
25291
|
command
|
|
25259
25292
|
});
|
|
25293
|
+
if (command === "delete-node") break;
|
|
25260
25294
|
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
25295
|
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
25296
|
break;
|
|
25263
|
-
case "delete-node": break;
|
|
25264
25297
|
default: log_error(`${gobj_short_name(gobj)} Command unknown: ${command}`);
|
|
25265
25298
|
}
|
|
25266
25299
|
return 0;
|
|
@@ -25528,7 +25561,7 @@ function ac_create_record(gobj, event, kw, src) {
|
|
|
25528
25561
|
create: true,
|
|
25529
25562
|
create_only: true,
|
|
25530
25563
|
autolink: true
|
|
25531
|
-
}, form_write) < 0) {
|
|
25564
|
+
}, form_write, true) < 0) {
|
|
25532
25565
|
answer_form_write(gobj, src, form_write, false);
|
|
25533
25566
|
return -1;
|
|
25534
25567
|
}
|
|
@@ -29446,6 +29479,25 @@ function refuse_if_readonly$2(gobj, event) {
|
|
|
29446
29479
|
* From external, at the beginning, load all topic data
|
|
29447
29480
|
************************************************************/
|
|
29448
29481
|
/***************************************************************
|
|
29482
|
+
* One of MY json viewers (the schema, a cell, the table's records)
|
|
29483
|
+
* met a `__collapsed__` sentinel and the reader opened it. The
|
|
29484
|
+
* viewer never fetches: it asks its host, and waits on "loading"
|
|
29485
|
+
* until it is answered. This view holds records, not a store it can
|
|
29486
|
+
* read a subtree of -- the lazy drill is `print-tranger`, which the
|
|
29487
|
+
* TOPICS view runs for its own viewer, over a whole tranger -- so the
|
|
29488
|
+
* answer is that it cannot, and the viewer shows that on the stub
|
|
29489
|
+
* instead of loading for ever.
|
|
29490
|
+
***************************************************************/
|
|
29491
|
+
function ac_expand_path(gobj, event, kw, src) {
|
|
29492
|
+
let path = kw && kw.path || "";
|
|
29493
|
+
gobj_send_event(src, "EV_SUBTREE_ERROR", {
|
|
29494
|
+
path,
|
|
29495
|
+
i18n: "this part cannot be loaded here",
|
|
29496
|
+
by_design: true
|
|
29497
|
+
}, gobj);
|
|
29498
|
+
return 0;
|
|
29499
|
+
}
|
|
29500
|
+
/***************************************************************
|
|
29449
29501
|
* The language changed (the shell publishes it after the app switched).
|
|
29450
29502
|
*
|
|
29451
29503
|
* The column headers carry their key (col_label's title formatter emits a
|
|
@@ -30739,6 +30791,11 @@ function create_gclass$5(gclass_name) {
|
|
|
30739
30791
|
ac_show_schema,
|
|
30740
30792
|
null
|
|
30741
30793
|
],
|
|
30794
|
+
[
|
|
30795
|
+
"EV_EXPAND_PATH",
|
|
30796
|
+
ac_expand_path,
|
|
30797
|
+
null
|
|
30798
|
+
],
|
|
30742
30799
|
[
|
|
30743
30800
|
"EV_CELL_EDITED",
|
|
30744
30801
|
ac_cell_edited,
|
|
@@ -30854,6 +30911,7 @@ function create_gclass$5(gclass_name) {
|
|
|
30854
30911
|
["EV_CHANGE_LOCALE", 0],
|
|
30855
30912
|
["EV_REFRESH", 0],
|
|
30856
30913
|
["EV_SHOW_SCHEMA", 0],
|
|
30914
|
+
["EV_EXPAND_PATH", 0],
|
|
30857
30915
|
["EV_CELL_EDITED", 0],
|
|
30858
30916
|
["EV_REPULL_PAGE", 0],
|
|
30859
30917
|
["EV_PAGE_LOADED", 0],
|
|
@@ -59259,6 +59317,7 @@ var PRIVATE_DATA$4 = {
|
|
|
59259
59317
|
_graph_properties: {},
|
|
59260
59318
|
_saved_graph_properties: {},
|
|
59261
59319
|
_graphs_writes_owed: {},
|
|
59320
|
+
_graphs_load: 0,
|
|
59262
59321
|
yet_showed: false,
|
|
59263
59322
|
edit_mode: false,
|
|
59264
59323
|
operation_mode: null,
|
|
@@ -60968,7 +61027,8 @@ function save_topic_graph_properties(gobj, topic_name) {
|
|
|
60968
61027
|
list_dict: true,
|
|
60969
61028
|
autolink: false,
|
|
60970
61029
|
create: true
|
|
60971
|
-
}
|
|
61030
|
+
},
|
|
61031
|
+
graphs_load: priv._graphs_load
|
|
60972
61032
|
};
|
|
60973
61033
|
gobj_publish_event(gobj, "EV_UPDATE_NODE", kw_update);
|
|
60974
61034
|
}
|
|
@@ -65749,6 +65809,7 @@ function ac_clear_data(gobj, event, kw, src) {
|
|
|
65749
65809
|
hide_create_popover(gobj);
|
|
65750
65810
|
gobj_write_attr(gobj, "records", {});
|
|
65751
65811
|
priv._graphs_writes_owed = {};
|
|
65812
|
+
priv._graphs_load++;
|
|
65752
65813
|
priv._nodes_total = 0;
|
|
65753
65814
|
priv._nodes_placed = 0;
|
|
65754
65815
|
priv._fold_model = null;
|
|
@@ -65850,12 +65911,19 @@ function ac_save_graph(gobj, event, kw, src) {
|
|
|
65850
65911
|
/************************************************************
|
|
65851
65912
|
* The host says a write of `__graphs__` did not land: the
|
|
65852
65913
|
* backend refused it, the transport refused it on the way out,
|
|
65853
|
-
* or there was no session to send it on.
|
|
65914
|
+
* or there was no session to send it on.
|
|
65915
|
+
* kw: {topic, graphs_load}
|
|
65854
65916
|
*
|
|
65855
65917
|
* save_topic_graph_properties() recorded it as saved before it
|
|
65856
65918
|
* left. Forgotten now, and the Save is lit again: the next Save
|
|
65857
65919
|
* writes the topic again. Before, the view believed the backend
|
|
65858
65920
|
* held the arrangement, and the next Save had nothing to write.
|
|
65921
|
+
*
|
|
65922
|
+
* `graphs_load` is the load the write was sent from, echoed by the
|
|
65923
|
+
* host. A refusal of an EARLIER load is about an arrangement the
|
|
65924
|
+
* reload replaced with what the backend holds: applied, it lit the
|
|
65925
|
+
* Save over nothing changed (before gobj-ui 7.25.20). A host that
|
|
65926
|
+
* echoes no load is taken at its word, as before.
|
|
65859
65927
|
************************************************************/
|
|
65860
65928
|
function ac_graphs_write_refused(gobj, event, kw, src) {
|
|
65861
65929
|
let priv = gobj.priv;
|
|
@@ -65864,6 +65932,10 @@ function ac_graphs_write_refused(gobj, event, kw, src) {
|
|
|
65864
65932
|
log_error(`${gobj_short_name(gobj)}: ${event} names no topic`);
|
|
65865
65933
|
return -1;
|
|
65866
65934
|
}
|
|
65935
|
+
if (kw.graphs_load !== void 0 && kw.graphs_load !== priv._graphs_load) {
|
|
65936
|
+
log_warning(`${gobj_short_name(gobj)}: a refused write of the arrangement of '${topic_name}' belongs to an earlier load: ignored`);
|
|
65937
|
+
return 0;
|
|
65938
|
+
}
|
|
65867
65939
|
log_warning(`${gobj_short_name(gobj)}: the arrangement of '${topic_name}' was not saved: the next Save writes it again`);
|
|
65868
65940
|
forget_refused_graphs_write(priv._saved_graph_properties, topic_name);
|
|
65869
65941
|
priv._graphs_writes_owed[topic_name] = true;
|
|
@@ -65871,6 +65943,22 @@ function ac_graphs_write_refused(gobj, event, kw, src) {
|
|
|
65871
65943
|
return 0;
|
|
65872
65944
|
}
|
|
65873
65945
|
/************************************************************
|
|
65946
|
+
* An echo of a `__graphs__` record is what the backend holds for
|
|
65947
|
+
* its topic now, and the view has just taken it as shown and as
|
|
65948
|
+
* saved: a write of that topic owed from an earlier refusal is
|
|
65949
|
+
* owed no more. Left owed, the Save stayed lit with nothing to
|
|
65950
|
+
* write -- the plan compares the two, and they are equal -- until
|
|
65951
|
+
* a reload: a refused Save #1 answered after Save #2 landed, or
|
|
65952
|
+
* another browser saving the topic, did exactly that.
|
|
65953
|
+
************************************************************/
|
|
65954
|
+
function settle_owed_graphs_write(gobj, rec) {
|
|
65955
|
+
let priv = gobj.priv;
|
|
65956
|
+
let topic_name = rec && rec.topic;
|
|
65957
|
+
if (!topic_name || !priv._graphs_writes_owed[topic_name]) return;
|
|
65958
|
+
delete priv._graphs_writes_owed[topic_name];
|
|
65959
|
+
update_history_buttons(gobj);
|
|
65960
|
+
}
|
|
65961
|
+
/************************************************************
|
|
65874
65962
|
* Node created, from subscription
|
|
65875
65963
|
************************************************************/
|
|
65876
65964
|
function ac_node_created(gobj, event, kw, src) {
|
|
@@ -65881,7 +65969,8 @@ function ac_node_created(gobj, event, kw, src) {
|
|
|
65881
65969
|
if (!priv.descs || !priv.graph) return 0;
|
|
65882
65970
|
if (topic_name === "__graphs__") {
|
|
65883
65971
|
priv.__graphs__.push(node);
|
|
65884
|
-
|
|
65972
|
+
apply_graphs_echo(priv._graph_properties, priv._saved_graph_properties, priv.__graphs__, node);
|
|
65973
|
+
settle_owed_graphs_write(gobj, node);
|
|
65885
65974
|
return 0;
|
|
65886
65975
|
}
|
|
65887
65976
|
if (!priv.descs[topic_name]) {
|
|
@@ -65917,6 +66006,7 @@ function ac_node_updated(gobj, event, kw, src) {
|
|
|
65917
66006
|
}
|
|
65918
66007
|
if (!found) priv.__graphs__.push(node);
|
|
65919
66008
|
apply_graphs_echo(priv._graph_properties, priv._saved_graph_properties, priv.__graphs__, node);
|
|
66009
|
+
settle_owed_graphs_write(gobj, node);
|
|
65920
66010
|
return 0;
|
|
65921
66011
|
}
|
|
65922
66012
|
let desc = priv.descs[topic_name];
|
|
@@ -68260,7 +68350,7 @@ function request_print_tranger(gobj, path) {
|
|
|
68260
68350
|
let jv = priv.json_gobj;
|
|
68261
68351
|
if (path && jv && is_gobj(jv) && !gobj_is_destroying(jv)) gobj_send_event(jv, "EV_SUBTREE_ERROR", {
|
|
68262
68352
|
path,
|
|
68263
|
-
|
|
68353
|
+
i18n: "no session"
|
|
68264
68354
|
}, gobj);
|
|
68265
68355
|
return;
|
|
68266
68356
|
}
|
|
@@ -68369,7 +68459,7 @@ function treedb_create_node(gobj, treedb_name, topic_name, record, options) {
|
|
|
68369
68459
|
/************************************************************
|
|
68370
68460
|
* Command to remote service
|
|
68371
68461
|
************************************************************/
|
|
68372
|
-
function treedb_update_node(gobj, treedb_name, topic_name, record, options) {
|
|
68462
|
+
function treedb_update_node(gobj, treedb_name, topic_name, record, options, graphs_load) {
|
|
68373
68463
|
let priv = gobj.priv;
|
|
68374
68464
|
if (!priv.gobj_remote_yuno) {
|
|
68375
68465
|
log_error(`${gobj_short_name(gobj)}: No gobj_remote_yuno defined`);
|
|
@@ -68384,7 +68474,10 @@ function treedb_update_node(gobj, treedb_name, topic_name, record, options) {
|
|
|
68384
68474
|
options: options || {}
|
|
68385
68475
|
};
|
|
68386
68476
|
kw.__md_command__ = { topic_name };
|
|
68387
|
-
if (topic_name === "__graphs__")
|
|
68477
|
+
if (topic_name === "__graphs__") {
|
|
68478
|
+
kw.__md_command__.graph_topic = graph_topic_of(record);
|
|
68479
|
+
if (graphs_load !== void 0) kw.__md_command__.graphs_load = graphs_load;
|
|
68480
|
+
}
|
|
68388
68481
|
let ret = gobj_command(priv.gobj_remote_yuno, command, kw, gobj);
|
|
68389
68482
|
if (ret) {
|
|
68390
68483
|
log_error(ret);
|
|
@@ -68688,7 +68781,7 @@ function ac_mt_command_answer$1(gobj, event, kw, src) {
|
|
|
68688
68781
|
case "delete-node":
|
|
68689
68782
|
case "link-nodes":
|
|
68690
68783
|
case "unlink-nodes":
|
|
68691
|
-
if (result < 0 && command === "update-node") graphs_write_refused(gobj, kw_get_str(gobj, kw_command, "topic_name", "", 0), kw_get_str(gobj, kw_command, "graph_topic", "", 0));
|
|
68784
|
+
if (result < 0 && command === "update-node") graphs_write_refused(gobj, kw_get_str(gobj, kw_command, "topic_name", "", 0), kw_get_str(gobj, kw_command, "graph_topic", "", 0), kw_command ? kw_command.graphs_load : void 0);
|
|
68692
68785
|
if (result >= 0 && kw_get_str(gobj, kw_command, "topic_name", "", 0) !== "__graphs__") {
|
|
68693
68786
|
let written = {
|
|
68694
68787
|
treedb_name: priv.treedb_name,
|
|
@@ -68943,17 +69036,18 @@ function ac_update_node(gobj, event, kw, src) {
|
|
|
68943
69036
|
let topic_name = kw.topic_name;
|
|
68944
69037
|
let record = kw.record;
|
|
68945
69038
|
let options = kw.options || {};
|
|
69039
|
+
let graphs_load = kw.graphs_load;
|
|
68946
69040
|
if (refuse_if_readonly$1(gobj, event)) {
|
|
68947
|
-
graphs_write_refused(gobj, topic_name, graph_topic_of(record));
|
|
69041
|
+
graphs_write_refused(gobj, topic_name, graph_topic_of(record), graphs_load);
|
|
68948
69042
|
return -1;
|
|
68949
69043
|
}
|
|
68950
69044
|
if (topic_name === "__graphs__" && !is_connected(gobj)) {
|
|
68951
69045
|
log_warning(`${gobj_short_name(gobj)}: no session, the arrangement was not sent`);
|
|
68952
|
-
graphs_write_refused(gobj, topic_name, graph_topic_of(record));
|
|
69046
|
+
graphs_write_refused(gobj, topic_name, graph_topic_of(record), graphs_load);
|
|
68953
69047
|
return -1;
|
|
68954
69048
|
}
|
|
68955
|
-
let ret = treedb_update_node(gobj, treedb_name, topic_name, record, options);
|
|
68956
|
-
if (ret < 0) graphs_write_refused(gobj, topic_name, graph_topic_of(record));
|
|
69049
|
+
let ret = treedb_update_node(gobj, treedb_name, topic_name, record, options, graphs_load);
|
|
69050
|
+
if (ret < 0) graphs_write_refused(gobj, topic_name, graph_topic_of(record), graphs_load);
|
|
68957
69051
|
return ret;
|
|
68958
69052
|
}
|
|
68959
69053
|
/************************************************************
|
|
@@ -68968,9 +69062,11 @@ function graph_topic_of(record) {
|
|
|
68968
69062
|
* (C_G6_NODES_TREE) took it for granted when it left -- nothing
|
|
68969
69063
|
* answers it when it lands -- so it is told, and its next Save
|
|
68970
69064
|
* writes the topic again. Other topics are the operator's data:
|
|
68971
|
-
* the answer's error says what happened to them.
|
|
69065
|
+
* the answer's error says what happened to them. `graphs_load` is
|
|
69066
|
+
* the engine's load the write was sent from, handed back so it can
|
|
69067
|
+
* tell a refusal of an earlier load from one of the current.
|
|
68972
69068
|
************************************************************/
|
|
68973
|
-
function graphs_write_refused(gobj, topic_name, topic) {
|
|
69069
|
+
function graphs_write_refused(gobj, topic_name, topic, graphs_load) {
|
|
68974
69070
|
let priv = gobj.priv;
|
|
68975
69071
|
if (topic_name !== "__graphs__") return;
|
|
68976
69072
|
if (!topic) {
|
|
@@ -68978,7 +69074,9 @@ function graphs_write_refused(gobj, topic_name, topic) {
|
|
|
68978
69074
|
return;
|
|
68979
69075
|
}
|
|
68980
69076
|
if (!priv.gobj_nodes_tree) return;
|
|
68981
|
-
|
|
69077
|
+
let kw = { topic };
|
|
69078
|
+
if (graphs_load !== void 0) kw.graphs_load = graphs_load;
|
|
69079
|
+
gobj_send_event(priv.gobj_nodes_tree, "EV_GRAPHS_WRITE_REFUSED", kw, gobj);
|
|
68982
69080
|
}
|
|
68983
69081
|
/********************************************
|
|
68984
69082
|
* Message from G6_nodes_tree
|
|
@@ -72951,8 +73049,12 @@ function current_topic(gobj) {
|
|
|
72951
73049
|
* One line for what the whole view has to say: loading, empty,
|
|
72952
73050
|
* or the reason nothing loaded. Carries its i18n key, so it
|
|
72953
73051
|
* follows a language change like any other text.
|
|
73052
|
+
*
|
|
73053
|
+
* `detail` is a NAME (a treedb, a topic) shown as it is, unless
|
|
73054
|
+
* `detail_is_key` says it is a key: a name is not text to
|
|
73055
|
+
* translate, and a topic called `nodes` is not "Nodos".
|
|
72954
73056
|
***************************************************************/
|
|
72955
|
-
function show_notice(gobj, key, detail) {
|
|
73057
|
+
function show_notice(gobj, key, detail, detail_is_key) {
|
|
72956
73058
|
let $notice = $of(gobj, ".SCHEMA_NOTICE");
|
|
72957
73059
|
if (!$notice) return;
|
|
72958
73060
|
clear($notice);
|
|
@@ -72969,14 +73071,15 @@ function show_notice(gobj, key, detail) {
|
|
|
72969
73071
|
},
|
|
72970
73072
|
t(key)
|
|
72971
73073
|
]));
|
|
72972
|
-
if (detail && detail !== key)
|
|
72973
|
-
"
|
|
72974
|
-
{
|
|
72975
|
-
|
|
72976
|
-
|
|
72977
|
-
|
|
72978
|
-
|
|
72979
|
-
|
|
73074
|
+
if (detail && detail !== key) {
|
|
73075
|
+
let attrs = { class: "SCHEMA_NOTICE_DETAIL yui-text-quiet ml-2" };
|
|
73076
|
+
if (detail_is_key) attrs.i18n = `${detail}`;
|
|
73077
|
+
$notice.appendChild(createElement2([
|
|
73078
|
+
"span",
|
|
73079
|
+
attrs,
|
|
73080
|
+
detail_is_key ? t(`${detail}`) : `${detail}`
|
|
73081
|
+
]));
|
|
73082
|
+
}
|
|
72980
73083
|
}
|
|
72981
73084
|
/***************************************************************
|
|
72982
73085
|
* A button of the toolbar. Every one carries an icon and a
|
|
@@ -73163,7 +73266,7 @@ function render(gobj) {
|
|
|
73163
73266
|
return;
|
|
73164
73267
|
}
|
|
73165
73268
|
if (state === "ST_IDLE") {
|
|
73166
|
-
show_notice(gobj, priv.load_error ? "cannot load the schemas" : "not connected", priv.load_error);
|
|
73269
|
+
show_notice(gobj, priv.load_error ? "cannot load the schemas" : "not connected", priv.load_error, true);
|
|
73167
73270
|
destroy_diagram(gobj);
|
|
73168
73271
|
clear($body);
|
|
73169
73272
|
return;
|
|
@@ -75164,13 +75267,18 @@ function run_next_write(gobj) {
|
|
|
75164
75267
|
let write = priv.save_queue[0];
|
|
75165
75268
|
let command = write_command(write.op);
|
|
75166
75269
|
let options = write_options(write.op);
|
|
75270
|
+
if (!transport_in_session(gobj)) {
|
|
75271
|
+
log_warning(`${gobj_short_name(gobj)}: no session, '${command}' of '${write.topic_name}' was not sent`);
|
|
75272
|
+
priv.reload_on_open = true;
|
|
75273
|
+
return end_writes(gobj, "cannot reach the treedb");
|
|
75274
|
+
}
|
|
75167
75275
|
priv.write_tag++;
|
|
75168
75276
|
if (remote_command(gobj, command, {
|
|
75169
75277
|
topic_name: write.topic_name,
|
|
75170
75278
|
record: write.record,
|
|
75171
75279
|
options,
|
|
75172
75280
|
record_id: write.record.id || ""
|
|
75173
|
-
}, { write: priv.write_tag }) < 0) return end_writes(gobj,
|
|
75281
|
+
}, { write: priv.write_tag }) < 0) return end_writes(gobj, "cannot reach the treedb");
|
|
75174
75282
|
return 0;
|
|
75175
75283
|
}
|
|
75176
75284
|
/***************************************************************
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yuneta/gobj-ui",
|
|
3
|
-
"version": "7.25.
|
|
3
|
+
"version": "7.25.20",
|
|
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.
|
|
33
|
+
"@yuneta/gobj-js": "^7.25.6",
|
|
34
34
|
"vite": "^8.2.1",
|
|
35
35
|
"vitest": "^4.1.10"
|
|
36
36
|
},
|
package/src/c_g6_nodes_tree.js
CHANGED
|
@@ -494,6 +494,7 @@ let PRIVATE_DATA = {
|
|
|
494
494
|
_graph_properties: {}, // topic_name → {nodes: {node_id: {x,y,size,...}}}
|
|
495
495
|
_saved_graph_properties: {}, // the same, as the BACKEND has it: what a Save compares against
|
|
496
496
|
_graphs_writes_owed: {}, // topic_name → true: a __graphs__ write the host said did not land
|
|
497
|
+
_graphs_load: 0, // the LOAD a __graphs__ write belongs to: EV_CLEAR_DATA starts another
|
|
497
498
|
yet_showed: false,
|
|
498
499
|
edit_mode: false,
|
|
499
500
|
operation_mode: null,
|
|
@@ -3301,7 +3302,10 @@ function save_topic_graph_properties(gobj, topic_name)
|
|
|
3301
3302
|
list_dict: true,
|
|
3302
3303
|
autolink: false,
|
|
3303
3304
|
create: true
|
|
3304
|
-
}
|
|
3305
|
+
},
|
|
3306
|
+
/* Echoed back with a refusal (EV_GRAPHS_WRITE_REFUSED), so
|
|
3307
|
+
* one answered after a reload is told from one of THIS load. */
|
|
3308
|
+
graphs_load: priv._graphs_load
|
|
3305
3309
|
};
|
|
3306
3310
|
gobj_publish_event(gobj, "EV_UPDATE_NODE", kw_update);
|
|
3307
3311
|
}
|
|
@@ -10372,6 +10376,9 @@ function ac_clear_data(gobj, event, kw, src)
|
|
|
10372
10376
|
* reload brings what the backend holds, and that is what the view
|
|
10373
10377
|
* will hold. */
|
|
10374
10378
|
priv._graphs_writes_owed = {};
|
|
10379
|
+
/* And a write still on its way belongs to it: its refusal, if
|
|
10380
|
+
* one comes, is about an arrangement this view no longer holds. */
|
|
10381
|
+
priv._graphs_load++;
|
|
10375
10382
|
|
|
10376
10383
|
/* The node counters belong to the data that is going away: a refresh
|
|
10377
10384
|
* that kept them would decide the layout on the previous treedb. */
|
|
@@ -10537,12 +10544,19 @@ function ac_save_graph(gobj, event, kw, src)
|
|
|
10537
10544
|
/************************************************************
|
|
10538
10545
|
* The host says a write of `__graphs__` did not land: the
|
|
10539
10546
|
* backend refused it, the transport refused it on the way out,
|
|
10540
|
-
* or there was no session to send it on.
|
|
10547
|
+
* or there was no session to send it on.
|
|
10548
|
+
* kw: {topic, graphs_load}
|
|
10541
10549
|
*
|
|
10542
10550
|
* save_topic_graph_properties() recorded it as saved before it
|
|
10543
10551
|
* left. Forgotten now, and the Save is lit again: the next Save
|
|
10544
10552
|
* writes the topic again. Before, the view believed the backend
|
|
10545
10553
|
* held the arrangement, and the next Save had nothing to write.
|
|
10554
|
+
*
|
|
10555
|
+
* `graphs_load` is the load the write was sent from, echoed by the
|
|
10556
|
+
* host. A refusal of an EARLIER load is about an arrangement the
|
|
10557
|
+
* reload replaced with what the backend holds: applied, it lit the
|
|
10558
|
+
* Save over nothing changed (before gobj-ui 7.25.20). A host that
|
|
10559
|
+
* echoes no load is taken at its word, as before.
|
|
10546
10560
|
************************************************************/
|
|
10547
10561
|
function ac_graphs_write_refused(gobj, event, kw, src)
|
|
10548
10562
|
{
|
|
@@ -10553,6 +10567,11 @@ function ac_graphs_write_refused(gobj, event, kw, src)
|
|
|
10553
10567
|
log_error(`${gobj_short_name(gobj)}: ${event} names no topic`);
|
|
10554
10568
|
return -1;
|
|
10555
10569
|
}
|
|
10570
|
+
if(kw.graphs_load !== undefined && kw.graphs_load !== priv._graphs_load) {
|
|
10571
|
+
log_warning(`${gobj_short_name(gobj)}: a refused write of the arrangement ` +
|
|
10572
|
+
`of '${topic_name}' belongs to an earlier load: ignored`);
|
|
10573
|
+
return 0;
|
|
10574
|
+
}
|
|
10556
10575
|
log_warning(`${gobj_short_name(gobj)}: the arrangement of '${topic_name}' ` +
|
|
10557
10576
|
`was not saved: the next Save writes it again`);
|
|
10558
10577
|
forget_refused_graphs_write(priv._saved_graph_properties, topic_name);
|
|
@@ -10565,6 +10584,27 @@ function ac_graphs_write_refused(gobj, event, kw, src)
|
|
|
10565
10584
|
return 0;
|
|
10566
10585
|
}
|
|
10567
10586
|
|
|
10587
|
+
/************************************************************
|
|
10588
|
+
* An echo of a `__graphs__` record is what the backend holds for
|
|
10589
|
+
* its topic now, and the view has just taken it as shown and as
|
|
10590
|
+
* saved: a write of that topic owed from an earlier refusal is
|
|
10591
|
+
* owed no more. Left owed, the Save stayed lit with nothing to
|
|
10592
|
+
* write -- the plan compares the two, and they are equal -- until
|
|
10593
|
+
* a reload: a refused Save #1 answered after Save #2 landed, or
|
|
10594
|
+
* another browser saving the topic, did exactly that.
|
|
10595
|
+
************************************************************/
|
|
10596
|
+
function settle_owed_graphs_write(gobj, rec)
|
|
10597
|
+
{
|
|
10598
|
+
let priv = gobj.priv;
|
|
10599
|
+
let topic_name = rec && rec.topic;
|
|
10600
|
+
|
|
10601
|
+
if(!topic_name || !priv._graphs_writes_owed[topic_name]) {
|
|
10602
|
+
return;
|
|
10603
|
+
}
|
|
10604
|
+
delete priv._graphs_writes_owed[topic_name];
|
|
10605
|
+
update_history_buttons(gobj);
|
|
10606
|
+
}
|
|
10607
|
+
|
|
10568
10608
|
/************************************************************
|
|
10569
10609
|
* Node created, from subscription
|
|
10570
10610
|
************************************************************/
|
|
@@ -10579,10 +10619,17 @@ function ac_node_created(gobj, event, kw, src)
|
|
|
10579
10619
|
return 0;
|
|
10580
10620
|
}
|
|
10581
10621
|
|
|
10582
|
-
|
|
10622
|
+
/* The first record of a topic's arrangement. Only THAT topic
|
|
10623
|
+
* moves, as for an update echo: build_graph_properties() took
|
|
10624
|
+
* every topic's saved copy from the live objects the view edits
|
|
10625
|
+
* in place, so an unsaved change of another topic counted as
|
|
10626
|
+
* saved and its Save was lost (before gobj-ui 7.25.20). */
|
|
10583
10627
|
if(topic_name === '__graphs__') {
|
|
10584
10628
|
priv.__graphs__.push(node);
|
|
10585
|
-
|
|
10629
|
+
apply_graphs_echo(
|
|
10630
|
+
priv._graph_properties, priv._saved_graph_properties, priv.__graphs__, node
|
|
10631
|
+
);
|
|
10632
|
+
settle_owed_graphs_write(gobj, node);
|
|
10586
10633
|
return 0;
|
|
10587
10634
|
}
|
|
10588
10635
|
|
|
@@ -10649,6 +10696,7 @@ function ac_node_updated(gobj, event, kw, src)
|
|
|
10649
10696
|
apply_graphs_echo(
|
|
10650
10697
|
priv._graph_properties, priv._saved_graph_properties, priv.__graphs__, node
|
|
10651
10698
|
);
|
|
10699
|
+
settle_owed_graphs_write(gobj, node);
|
|
10652
10700
|
return 0;
|
|
10653
10701
|
}
|
|
10654
10702
|
|
package/src/c_yui_json.js
CHANGED
|
@@ -64,6 +64,7 @@ import {
|
|
|
64
64
|
gclass_create,
|
|
65
65
|
gclass_find_by_name,
|
|
66
66
|
log_error,
|
|
67
|
+
log_warning,
|
|
67
68
|
gobj_read_pointer_attr,
|
|
68
69
|
gobj_parent,
|
|
69
70
|
gobj_subscribe_event,
|
|
@@ -898,8 +899,12 @@ function push_collapsed_row(ctx, value, segments, depth, key, rows)
|
|
|
898
899
|
children.push(['span', {class: 'JSON_STUB_HINT is-size-7 ml-2',
|
|
899
900
|
'data-i18n': is_pending ? 'loading' : 'click to load'},
|
|
900
901
|
is_pending ? 'loading' : 'click to load']);
|
|
901
|
-
if(err) {
|
|
902
|
-
children.push(['span', {class: 'JSON_STUB_ERR has-text-danger is-size-7 ml-2'
|
|
902
|
+
if(err && err.is_key) {
|
|
903
|
+
children.push(['span', {class: 'JSON_STUB_ERR has-text-danger is-size-7 ml-2',
|
|
904
|
+
'data-i18n': err.error}, t(err.error)]);
|
|
905
|
+
} else if(err) {
|
|
906
|
+
children.push(['span', {class: 'JSON_STUB_ERR has-text-danger is-size-7 ml-2'},
|
|
907
|
+
String(err.error)]);
|
|
903
908
|
}
|
|
904
909
|
|
|
905
910
|
let attrs = {
|
|
@@ -1117,17 +1122,35 @@ function ac_subtree_loaded(gobj, event, kw, src)
|
|
|
1117
1122
|
}
|
|
1118
1123
|
|
|
1119
1124
|
/************************************************************
|
|
1120
|
-
* EV_SUBTREE_ERROR { path, error
|
|
1125
|
+
* EV_SUBTREE_ERROR { path, error | i18n, by_design }
|
|
1126
|
+
* — mark the branch that was not loaded.
|
|
1127
|
+
*
|
|
1128
|
+
* `error` is text, drawn as it came (a backend's comment).
|
|
1129
|
+
* `i18n` is a KEY, drawn as t(key) with data-i18n so the stub
|
|
1130
|
+
* changes language with the app (a text translated by the host
|
|
1131
|
+
* stays in the language it was sent in). The name is the one a
|
|
1132
|
+
* locale check scans for (`i18n: "<key>"`), so the key of every
|
|
1133
|
+
* host stays visible to it.
|
|
1134
|
+
* `by_design`: the host answers that it CANNOT read a subtree
|
|
1135
|
+
* (a form holds records, a pasted pad has no backend) -- that is
|
|
1136
|
+
* not a failure, and it is logged as a warning. Anything else is
|
|
1137
|
+
* a load that failed, logged as an error.
|
|
1121
1138
|
************************************************************/
|
|
1122
1139
|
function ac_subtree_error(gobj, event, kw, src)
|
|
1123
1140
|
{
|
|
1124
1141
|
let priv = gobj.priv;
|
|
1125
1142
|
|
|
1126
1143
|
let path = kw.path || "";
|
|
1144
|
+
let is_key = !!kw.i18n;
|
|
1145
|
+
let error = kw.i18n || kw.error || "error";
|
|
1127
1146
|
priv.pending.delete(path);
|
|
1128
|
-
priv.errors.set(path,
|
|
1147
|
+
priv.errors.set(path, {error: error, is_key: is_key});
|
|
1129
1148
|
|
|
1130
|
-
|
|
1149
|
+
if(kw.by_design) {
|
|
1150
|
+
log_warning(`${GCLASS_NAME}: subtree not loaded at '${path}': ${error}`);
|
|
1151
|
+
} else {
|
|
1152
|
+
log_error(`${GCLASS_NAME}: subtree load failed at '${path}': ${error}`);
|
|
1153
|
+
}
|
|
1131
1154
|
|
|
1132
1155
|
render_view(gobj);
|
|
1133
1156
|
return 0;
|
package/src/c_yui_json_pad.js
CHANGED
|
@@ -798,8 +798,9 @@ function ac_hide_diff(gobj, event, kw, src)
|
|
|
798
798
|
function ac_expand_path(gobj, event, kw, src)
|
|
799
799
|
{
|
|
800
800
|
gobj_send_event(src, "EV_SUBTREE_ERROR", {
|
|
801
|
-
path:
|
|
802
|
-
|
|
801
|
+
path: (kw && kw.path) || "",
|
|
802
|
+
i18n: "collapsed in the source",
|
|
803
|
+
by_design: true
|
|
803
804
|
}, gobj);
|
|
804
805
|
return 0;
|
|
805
806
|
}
|