@yuneta/gobj-ui 7.25.16 → 7.25.18
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 +76 -0
- package/dist/gobj-ui.cjs.js +104 -34
- package/dist/gobj-ui.es.js +104 -34
- package/package.json +2 -2
- package/src/c_yui_schema_editor.js +41 -18
- package/src/c_yui_treedb_graph.js +71 -12
- package/src/c_yui_treedb_topics.js +23 -2
- package/src/schema_editor_reload.wiring.test.js +161 -0
- package/src/treedb_graph_writes.wiring.test.js +79 -4
- package/src/treedb_topics_transport.wiring.test.js +22 -7
package/README.md
CHANGED
|
@@ -989,6 +989,35 @@ hold the list again; the cell and a delete's question count either shape. The
|
|
|
989
989
|
search box no longer finds a parent row by the id of one of its children: to
|
|
990
990
|
find what hangs from a row, click its hook.
|
|
991
991
|
|
|
992
|
+
### What a write says to the host: `EV_RECORD_WRITTEN`
|
|
993
|
+
|
|
994
|
+
`C_YUI_TREEDB_TOPICS` and `C_YUI_TREEDB_GRAPH` publish `EV_RECORD_WRITTEN`
|
|
995
|
+
when a write of THEIRS is answered with success: a host whose work is not
|
|
996
|
+
finished with the record (a schema editor, a pending Apply) needs that, and the
|
|
997
|
+
`EV_TREEDB_NODE_*` events cannot tell its own writes from anybody else's. The
|
|
998
|
+
graph does not report `__graphs__`, its own bookkeeping.
|
|
999
|
+
|
|
1000
|
+
```js
|
|
1001
|
+
// kw of EV_RECORD_WRITTEN
|
|
1002
|
+
{
|
|
1003
|
+
treedb_name: "treedb_test", // the view's own treedb
|
|
1004
|
+
topic_name: "yunos", // the topic written (the CHILD's, for a link)
|
|
1005
|
+
record: {id: "1", x: 1, y: 2}, // the node the store answered, as written
|
|
1006
|
+
created: false, // true for create-node
|
|
1007
|
+
command: "update-node", // create/update/delete-node, link/unlink-nodes
|
|
1008
|
+
parent_ref: "realms^r1^yunos", // graph, link/unlink only
|
|
1009
|
+
child_ref: "yunos^1" // graph, link/unlink only
|
|
1010
|
+
}
|
|
1011
|
+
```
|
|
1012
|
+
|
|
1013
|
+
Since `7.25.18` every field carries what it says. They were read from the
|
|
1014
|
+
answer's command frame, which carries back only the request's
|
|
1015
|
+
`__md_command__` -- `C_IEVENT_CLI` and gui_agent's `C_AGENT_TREEDB_LINK` both
|
|
1016
|
+
do -- so `treedb_name` and `record` arrived empty, and a link named no topic.
|
|
1017
|
+
`treedb_name` is now the view's, `record` is the node the answer carries (a
|
|
1018
|
+
delete answers the node deleted, a link the child), and a link echoes its topic
|
|
1019
|
+
and refs in `__md_command__`.
|
|
1020
|
+
|
|
992
1021
|
### Read-only treedbs: `readonly`
|
|
993
1022
|
|
|
994
1023
|
`C_YUI_TREEDB_TOPICS` and `C_YUI_TREEDB_GRAPH` take a **`readonly`** attr; the
|
|
@@ -1824,6 +1853,20 @@ gobj_send_event(engine, "EV_GRAPHS_WRITE_REFUSED", {topic: "users"}, host); //
|
|
|
1824
1853
|
gobj_send_event(engine, "EV_SAVE_GRAPH", {}, engine); // writes users; Save dark
|
|
1825
1854
|
```
|
|
1826
1855
|
|
|
1856
|
+
**The refusal reaches the engine through the real transports** (since
|
|
1857
|
+
`7.25.17`). The answer of a command carries back only the request's
|
|
1858
|
+
`__md_command__`, as its `command_stack` frame -- `C_IEVENT_CLI` and gui_agent's
|
|
1859
|
+
`C_AGENT_TREEDB_LINK` both do, and neither echoes the request's `record`. The
|
|
1860
|
+
host read the topic from that `record`, found none, logged *"a refused
|
|
1861
|
+
__graphs__ write names no topic"* and never told the engine: the 7.25.15 fix
|
|
1862
|
+
worked only in a test whose fake transport echoed the whole request. The host
|
|
1863
|
+
now puts the topic in the echo it asks for:
|
|
1864
|
+
|
|
1865
|
+
```js
|
|
1866
|
+
kw.__md_command__ = {topic_name: "__graphs__", graph_topic: "users"};
|
|
1867
|
+
// the answer: __md_iev__.command_stack[0].kw === that echo, and nothing else
|
|
1868
|
+
```
|
|
1869
|
+
|
|
1827
1870
|
**Every saved look has a way back, in the context menu** (since `7.23.134`,
|
|
1828
1871
|
replacing `reset sizes` / `reset topic sizes`). In edition, the node, the port
|
|
1829
1872
|
and the edge menus each offer three resets — this one, its kind (`reset topic
|
|
@@ -2259,6 +2302,39 @@ else.
|
|
|
2259
2302
|
gobj_send_event(editor, "EV_REFRESH", {}, host); // logged, waits
|
|
2260
2303
|
// ... both deletes answered -> ST_LOADING -> the model is read again
|
|
2261
2304
|
```
|
|
2305
|
+
- **A write in flight takes the body out of the keyboard's reach too**
|
|
2306
|
+
(7.25.17). `ST_SAVING` keeps the screen under it and marks the body busy.
|
|
2307
|
+
The busy class only stopped the pointer (`pointer-events: none`); the
|
|
2308
|
+
shell's focus trap put the focus back on the row control that had it, and
|
|
2309
|
+
Enter or Delete there sent `EV_DELETE_COLUMN` or `EV_SELECT_TOPIC`, which
|
|
2310
|
+
`ST_SAVING` does not declare (*"Event NOT DEFINED"*). The busy body is now
|
|
2311
|
+
also `inert`. `ST_LOADING` needs nothing: its body is emptied.
|
|
2312
|
+
|
|
2313
|
+
```js
|
|
2314
|
+
// in ST_SAVING
|
|
2315
|
+
$container.querySelector(".SCHEMA_BODY").hasAttribute("inert"); // true
|
|
2316
|
+
```
|
|
2317
|
+
- **A write marks the topic of its RECORD, not the topic on screen**
|
|
2318
|
+
(7.25.17). What "its version still has to move" is asked about is the set of
|
|
2319
|
+
topics this session wrote (the draft chip, the export warning,
|
|
2320
|
+
`validate_schema()`'s `written_topics`). A column write marked the topic on
|
|
2321
|
+
screen, so an import from the topics screen (no topic on it) marked nothing,
|
|
2322
|
+
and an import that added `roles` from the screen of `users` marked `users`.
|
|
2323
|
+
The mark is read from the record the store answered (a new topic has its id
|
|
2324
|
+
only there), then from the record queued (a column names its topic in its
|
|
2325
|
+
fkey), and only then from the screen.
|
|
2326
|
+
|
|
2327
|
+
```js
|
|
2328
|
+
// import adding topic `roles`, run from db/users, every write answered
|
|
2329
|
+
editor.priv.written; // {"db.roles": true} (was {"db.users": true})
|
|
2330
|
+
```
|
|
2331
|
+
- **The reason a load failed is a key** (7.25.17). The notice's detail was
|
|
2332
|
+
the text of `t()` taken when the load failed (`cannot reach the treedb`,
|
|
2333
|
+
`cannot load the schemas`) or the backend's words, shown as plain text: it
|
|
2334
|
+
did not change language, and with no comment it repeated the notice's own
|
|
2335
|
+
title. It is now kept as a key, written with `data-i18n` (the backend's
|
|
2336
|
+
words translate to themselves when no locale has them), and left out when
|
|
2337
|
+
it is the title.
|
|
2262
2338
|
- **The loading screen is drawn** (7.25.8): the body is cleared, the drawing
|
|
2263
2339
|
destroyed and every toolbar button disabled, as in `ST_SAVING`, because
|
|
2264
2340
|
`ST_LOADING` declares none of a screen's actions. A **dialog** left open is
|
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -24924,6 +24924,17 @@ function treedb_nodes$1(gobj, treedb_name, topic_name, options, page, purpose) {
|
|
|
24924
24924
|
return 0;
|
|
24925
24925
|
}
|
|
24926
24926
|
/************************************************************
|
|
24927
|
+
* The record a write answered: the node the store wrote (an
|
|
24928
|
+
* update or a create), deleted, or the child of a link. The
|
|
24929
|
+
* answer's frame carries back only `__md_command__`, never the
|
|
24930
|
+
* request's own record.
|
|
24931
|
+
************************************************************/
|
|
24932
|
+
function answered_record$1(data) {
|
|
24933
|
+
if (data && typeof data === "object" && !Array.isArray(data)) return data;
|
|
24934
|
+
if (Array.isArray(data) && data[0] && typeof data[0] === "object") return data[0];
|
|
24935
|
+
return {};
|
|
24936
|
+
}
|
|
24937
|
+
/************************************************************
|
|
24927
24938
|
* Command to remote service
|
|
24928
24939
|
************************************************************/
|
|
24929
24940
|
function treedb_update_node$1(gobj, treedb_name, topic_name, record, options, form_write) {
|
|
@@ -25245,9 +25256,9 @@ function ac_mt_command_answer$2(gobj, event, kw, src) {
|
|
|
25245
25256
|
case "create-node":
|
|
25246
25257
|
case "update-node":
|
|
25247
25258
|
(0, _yuneta_gobj_js.gobj_publish_event)(gobj, "EV_RECORD_WRITTEN", {
|
|
25248
|
-
treedb_name: (0, _yuneta_gobj_js.
|
|
25259
|
+
treedb_name: (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "treedb_name"),
|
|
25249
25260
|
topic_name: (0, _yuneta_gobj_js.kw_get_str)(gobj, kw_command, "topic_name", "", 0),
|
|
25250
|
-
record: (
|
|
25261
|
+
record: answered_record$1(data),
|
|
25251
25262
|
created: command === "create-node",
|
|
25252
25263
|
command
|
|
25253
25264
|
});
|
|
@@ -68378,6 +68389,7 @@ function treedb_update_node(gobj, treedb_name, topic_name, record, options) {
|
|
|
68378
68389
|
options: options || {}
|
|
68379
68390
|
};
|
|
68380
68391
|
kw.__md_command__ = { topic_name };
|
|
68392
|
+
if (topic_name === "__graphs__") kw.__md_command__.graph_topic = graph_topic_of(record);
|
|
68381
68393
|
let ret = (0, _yuneta_gobj_js.gobj_command)(priv.gobj_remote_yuno, command, kw, gobj);
|
|
68382
68394
|
if (ret) {
|
|
68383
68395
|
(0, _yuneta_gobj_js.log_error)(ret);
|
|
@@ -68407,6 +68419,29 @@ function treedb_delete_node(gobj, treedb_name, topic_name, record, options) {
|
|
|
68407
68419
|
if (ret) (0, _yuneta_gobj_js.log_error)(ret);
|
|
68408
68420
|
}
|
|
68409
68421
|
/************************************************************
|
|
68422
|
+
* What a link or an unlink asks back with its answer: the
|
|
68423
|
+
* topic of the CHILD (the node a link saves) and both refs.
|
|
68424
|
+
* `child_ref` is "topic^id", `parent_ref` "topic^id^hook".
|
|
68425
|
+
************************************************************/
|
|
68426
|
+
function link_echo(parent_ref, child_ref) {
|
|
68427
|
+
return {
|
|
68428
|
+
topic_name: typeof child_ref === "string" ? child_ref.split("^")[0] : "",
|
|
68429
|
+
parent_ref,
|
|
68430
|
+
child_ref
|
|
68431
|
+
};
|
|
68432
|
+
}
|
|
68433
|
+
/************************************************************
|
|
68434
|
+
* The record a write answered: the node the store wrote (an
|
|
68435
|
+
* update or a create), deleted, or the child of a link. The
|
|
68436
|
+
* answer's frame carries back only `__md_command__`, never the
|
|
68437
|
+
* request's own record.
|
|
68438
|
+
************************************************************/
|
|
68439
|
+
function answered_record(data) {
|
|
68440
|
+
if (data && typeof data === "object" && !Array.isArray(data)) return data;
|
|
68441
|
+
if (Array.isArray(data) && data[0] && typeof data[0] === "object") return data[0];
|
|
68442
|
+
return {};
|
|
68443
|
+
}
|
|
68444
|
+
/************************************************************
|
|
68410
68445
|
* Command to remote service
|
|
68411
68446
|
************************************************************/
|
|
68412
68447
|
function treedb_link_nodes(gobj, treedb_name, parent_ref, child_ref, options) {
|
|
@@ -68423,6 +68458,7 @@ function treedb_link_nodes(gobj, treedb_name, parent_ref, child_ref, options) {
|
|
|
68423
68458
|
child_ref,
|
|
68424
68459
|
options: options || {}
|
|
68425
68460
|
};
|
|
68461
|
+
kw.__md_command__ = link_echo(parent_ref, child_ref);
|
|
68426
68462
|
let ret = (0, _yuneta_gobj_js.gobj_command)(priv.gobj_remote_yuno, command, kw, gobj);
|
|
68427
68463
|
if (ret) (0, _yuneta_gobj_js.log_error)(ret);
|
|
68428
68464
|
}
|
|
@@ -68443,6 +68479,7 @@ function treedb_unlink_nodes(gobj, treedb_name, parent_ref, child_ref, options)
|
|
|
68443
68479
|
child_ref,
|
|
68444
68480
|
options: options || {}
|
|
68445
68481
|
};
|
|
68482
|
+
kw.__md_command__ = link_echo(parent_ref, child_ref);
|
|
68446
68483
|
let ret = (0, _yuneta_gobj_js.gobj_command)(priv.gobj_remote_yuno, command, kw, gobj);
|
|
68447
68484
|
if (ret) (0, _yuneta_gobj_js.log_error)(ret);
|
|
68448
68485
|
}
|
|
@@ -68656,14 +68693,21 @@ function ac_mt_command_answer$1(gobj, event, kw, src) {
|
|
|
68656
68693
|
case "delete-node":
|
|
68657
68694
|
case "link-nodes":
|
|
68658
68695
|
case "unlink-nodes":
|
|
68659
|
-
if (result < 0 && command === "update-node") graphs_write_refused(gobj, (0, _yuneta_gobj_js.kw_get_str)(gobj, kw_command, "topic_name", "", 0), (0, _yuneta_gobj_js.
|
|
68660
|
-
if (result >= 0 && (0, _yuneta_gobj_js.kw_get_str)(gobj, kw_command, "topic_name", "", 0) !== "__graphs__")
|
|
68661
|
-
|
|
68662
|
-
|
|
68663
|
-
|
|
68664
|
-
|
|
68665
|
-
|
|
68666
|
-
|
|
68696
|
+
if (result < 0 && command === "update-node") graphs_write_refused(gobj, (0, _yuneta_gobj_js.kw_get_str)(gobj, kw_command, "topic_name", "", 0), (0, _yuneta_gobj_js.kw_get_str)(gobj, kw_command, "graph_topic", "", 0));
|
|
68697
|
+
if (result >= 0 && (0, _yuneta_gobj_js.kw_get_str)(gobj, kw_command, "topic_name", "", 0) !== "__graphs__") {
|
|
68698
|
+
let written = {
|
|
68699
|
+
treedb_name: priv.treedb_name,
|
|
68700
|
+
topic_name: (0, _yuneta_gobj_js.kw_get_str)(gobj, kw_command, "topic_name", "", 0),
|
|
68701
|
+
record: answered_record(data),
|
|
68702
|
+
created: command === "create-node",
|
|
68703
|
+
command
|
|
68704
|
+
};
|
|
68705
|
+
if (command === "link-nodes" || command === "unlink-nodes") {
|
|
68706
|
+
written.parent_ref = (0, _yuneta_gobj_js.kw_get_str)(gobj, kw_command, "parent_ref", "", 0);
|
|
68707
|
+
written.child_ref = (0, _yuneta_gobj_js.kw_get_str)(gobj, kw_command, "child_ref", "", 0);
|
|
68708
|
+
}
|
|
68709
|
+
(0, _yuneta_gobj_js.gobj_publish_event)(gobj, "EV_RECORD_WRITTEN", written);
|
|
68710
|
+
}
|
|
68667
68711
|
break;
|
|
68668
68712
|
default: (0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)} Command unknown: ${command}`);
|
|
68669
68713
|
}
|
|
@@ -68905,29 +68949,35 @@ function ac_update_node(gobj, event, kw, src) {
|
|
|
68905
68949
|
let record = kw.record;
|
|
68906
68950
|
let options = kw.options || {};
|
|
68907
68951
|
if (refuse_if_readonly$1(gobj, event)) {
|
|
68908
|
-
graphs_write_refused(gobj, topic_name, record);
|
|
68952
|
+
graphs_write_refused(gobj, topic_name, graph_topic_of(record));
|
|
68909
68953
|
return -1;
|
|
68910
68954
|
}
|
|
68911
68955
|
if (topic_name === "__graphs__" && !is_connected(gobj)) {
|
|
68912
68956
|
(0, _yuneta_gobj_js.log_warning)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: no session, the arrangement was not sent`);
|
|
68913
|
-
graphs_write_refused(gobj, topic_name, record);
|
|
68957
|
+
graphs_write_refused(gobj, topic_name, graph_topic_of(record));
|
|
68914
68958
|
return -1;
|
|
68915
68959
|
}
|
|
68916
68960
|
let ret = treedb_update_node(gobj, treedb_name, topic_name, record, options);
|
|
68917
|
-
if (ret < 0) graphs_write_refused(gobj, topic_name, record);
|
|
68961
|
+
if (ret < 0) graphs_write_refused(gobj, topic_name, graph_topic_of(record));
|
|
68918
68962
|
return ret;
|
|
68919
68963
|
}
|
|
68920
68964
|
/************************************************************
|
|
68965
|
+
* The topic a `__graphs__` record arranges.
|
|
68966
|
+
************************************************************/
|
|
68967
|
+
function graph_topic_of(record) {
|
|
68968
|
+
if (!record || typeof record !== "object") return "";
|
|
68969
|
+
return record.topic || record.id || "";
|
|
68970
|
+
}
|
|
68971
|
+
/************************************************************
|
|
68921
68972
|
* A write of `__graphs__` did not land. The engine
|
|
68922
68973
|
* (C_G6_NODES_TREE) took it for granted when it left -- nothing
|
|
68923
68974
|
* answers it when it lands -- so it is told, and its next Save
|
|
68924
68975
|
* writes the topic again. Other topics are the operator's data:
|
|
68925
68976
|
* the answer's error says what happened to them.
|
|
68926
68977
|
************************************************************/
|
|
68927
|
-
function graphs_write_refused(gobj, topic_name,
|
|
68978
|
+
function graphs_write_refused(gobj, topic_name, topic) {
|
|
68928
68979
|
let priv = gobj.priv;
|
|
68929
68980
|
if (topic_name !== "__graphs__") return;
|
|
68930
|
-
let topic = record && typeof record === "object" ? record.topic || record.id : "";
|
|
68931
68981
|
if (!topic) {
|
|
68932
68982
|
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: a refused __graphs__ write names no topic`);
|
|
68933
68983
|
return;
|
|
@@ -72486,11 +72536,18 @@ function el_attrs(attrs) {
|
|
|
72486
72536
|
return attrs;
|
|
72487
72537
|
}
|
|
72488
72538
|
/***************************************************************
|
|
72489
|
-
* The body stops answering while a write is in flight.
|
|
72539
|
+
* The body stops answering while a write is in flight. For the
|
|
72540
|
+
* keyboard too: `pointer-events` stops the mouse alone, and the
|
|
72541
|
+
* shell's focus trap puts the focus back on the row control that
|
|
72542
|
+
* had it, where Enter or Delete sent an action ST_SAVING does
|
|
72543
|
+
* not declare. `inert` takes the whole body out of reach.
|
|
72490
72544
|
***************************************************************/
|
|
72491
72545
|
function set_busy(gobj, busy) {
|
|
72492
72546
|
let $body = $of(gobj, ".SCHEMA_BODY");
|
|
72493
|
-
if ($body)
|
|
72547
|
+
if ($body) {
|
|
72548
|
+
$body.classList.toggle("SCHEMA_BUSY", !!busy);
|
|
72549
|
+
$body.toggleAttribute("inert", !!busy);
|
|
72550
|
+
}
|
|
72494
72551
|
}
|
|
72495
72552
|
/***************************************************************
|
|
72496
72553
|
* Shorthands for the three panes of the frame.
|
|
@@ -72706,7 +72763,7 @@ function request_model(gobj, keep_written) {
|
|
|
72706
72763
|
priv.records_before = null;
|
|
72707
72764
|
priv.load_round++;
|
|
72708
72765
|
priv.reload_on_open = true;
|
|
72709
|
-
priv.load_error =
|
|
72766
|
+
priv.load_error = "cannot reach the treedb";
|
|
72710
72767
|
if (priv.model) yui_shell_show_error(yui_shell_of(gobj), "cannot reach the treedb", { t: i18next.t });
|
|
72711
72768
|
end_load(gobj);
|
|
72712
72769
|
return -1;
|
|
@@ -72917,10 +72974,13 @@ function show_notice(gobj, key, detail) {
|
|
|
72917
72974
|
},
|
|
72918
72975
|
(0, i18next.t)(key)
|
|
72919
72976
|
]));
|
|
72920
|
-
if (detail) $notice.appendChild((0, _yuneta_gobj_js.createElement2)([
|
|
72977
|
+
if (detail && detail !== key) $notice.appendChild((0, _yuneta_gobj_js.createElement2)([
|
|
72921
72978
|
"span",
|
|
72922
|
-
{
|
|
72923
|
-
|
|
72979
|
+
{
|
|
72980
|
+
class: "SCHEMA_NOTICE_DETAIL yui-text-quiet ml-2",
|
|
72981
|
+
i18n: `${detail}`
|
|
72982
|
+
},
|
|
72983
|
+
(0, i18next.t)(`${detail}`)
|
|
72924
72984
|
]));
|
|
72925
72985
|
}
|
|
72926
72986
|
/***************************************************************
|
|
@@ -75475,7 +75535,7 @@ function ac_mt_command_answer(gobj, event, kw, src) {
|
|
|
75475
75535
|
return 0;
|
|
75476
75536
|
}
|
|
75477
75537
|
priv.pending--;
|
|
75478
|
-
if (result < 0) priv.load_error = comment ||
|
|
75538
|
+
if (result < 0) priv.load_error = comment || "cannot load the schemas";
|
|
75479
75539
|
else if (priv.records && Array.isArray(priv.records[topic_name])) priv.records[topic_name] = Array.isArray(data) ? data : [];
|
|
75480
75540
|
if (priv.pending > 0) return 0;
|
|
75481
75541
|
if (priv.load_error) {
|
|
@@ -75511,9 +75571,10 @@ function ac_mt_command_answer(gobj, event, kw, src) {
|
|
|
75511
75571
|
}
|
|
75512
75572
|
if (result < 0) return end_writes(gobj, comment || (0, i18next.t)("the treedb refused the write"));
|
|
75513
75573
|
priv.save_wrote = true;
|
|
75574
|
+
let record = null;
|
|
75514
75575
|
if (command === "delete-node") forget_record(gobj, topic_name, (0, _yuneta_gobj_js.kw_get_str)(gobj, md, "record_id", "", 0));
|
|
75515
75576
|
else {
|
|
75516
|
-
|
|
75577
|
+
record = (0, _yuneta_gobj_js.is_object)(data) ? data : Array.isArray(data) && (0, _yuneta_gobj_js.is_object)(data[0]) ? data[0] : null;
|
|
75517
75578
|
if (record) patch_record(gobj, topic_name, record);
|
|
75518
75579
|
else {
|
|
75519
75580
|
let not_sent = priv.save_queue.length - 1;
|
|
@@ -75521,7 +75582,7 @@ function ac_mt_command_answer(gobj, event, kw, src) {
|
|
|
75521
75582
|
if (not_sent > 0) yui_shell_show_error(yui_shell_of(gobj), "the treedb did not describe a write back: the writes after it were not sent", { t: i18next.t });
|
|
75522
75583
|
if (topic_name === T_TOPICS || topic_name === T_COLS) {
|
|
75523
75584
|
let write = priv.save_queue[0];
|
|
75524
|
-
mark_written(gobj, topic_name, write ? write.record : null);
|
|
75585
|
+
mark_written(gobj, topic_name, null, write ? write.record : null);
|
|
75525
75586
|
}
|
|
75526
75587
|
priv.reload_after_write = false;
|
|
75527
75588
|
priv.save_queue = [];
|
|
@@ -75536,7 +75597,7 @@ function ac_mt_command_answer(gobj, event, kw, src) {
|
|
|
75536
75597
|
}
|
|
75537
75598
|
if (topic_name === T_TOPICS || topic_name === T_COLS) {
|
|
75538
75599
|
let write = priv.save_queue[0];
|
|
75539
|
-
mark_written(gobj, topic_name, write ? write.record : null);
|
|
75600
|
+
mark_written(gobj, topic_name, record, write ? write.record : null);
|
|
75540
75601
|
}
|
|
75541
75602
|
priv.save_queue.shift();
|
|
75542
75603
|
return run_next_write(gobj);
|
|
@@ -75593,25 +75654,34 @@ function late_write_done(gobj, command, topic_name, data) {
|
|
|
75593
75654
|
***************************************************************/
|
|
75594
75655
|
function mark_written_record(gobj, topic_name, record) {
|
|
75595
75656
|
let priv = gobj.priv;
|
|
75596
|
-
|
|
75657
|
+
let marked = 0;
|
|
75658
|
+
if (!record) return 0;
|
|
75597
75659
|
if (topic_name === T_TOPICS && typeof record.id === "string" && record.id) {
|
|
75598
75660
|
priv.written[record.id] = true;
|
|
75599
|
-
return;
|
|
75661
|
+
return 1;
|
|
75600
75662
|
}
|
|
75601
|
-
if (topic_name !== T_COLS) return;
|
|
75602
|
-
for (let ref of parse_fkey_ref(record.topics))
|
|
75663
|
+
if (topic_name !== T_COLS) return 0;
|
|
75664
|
+
for (let ref of parse_fkey_ref(record.topics)) {
|
|
75665
|
+
priv.written[ref.id] = true;
|
|
75666
|
+
marked++;
|
|
75667
|
+
}
|
|
75668
|
+
return marked;
|
|
75603
75669
|
}
|
|
75604
75670
|
/***************************************************************
|
|
75605
75671
|
* Remember which topic this write belongs to, which is what
|
|
75606
75672
|
* "its version still has to move" is asked about.
|
|
75673
|
+
*
|
|
75674
|
+
* Asked of the RECORD first: the one the store answered (a new
|
|
75675
|
+
* topic has its id only there), then the one queued (a column
|
|
75676
|
+
* names its topic in its fkey). The screen is the last resort,
|
|
75677
|
+
* and a poor one: an import writes topics the operator is not
|
|
75678
|
+
* on, and from the topics screen there is no topic on it at all.
|
|
75607
75679
|
***************************************************************/
|
|
75608
|
-
function mark_written(gobj, topic_name,
|
|
75680
|
+
function mark_written(gobj, topic_name, answered, queued) {
|
|
75609
75681
|
let priv = gobj.priv;
|
|
75682
|
+
if (mark_written_record(gobj, topic_name, answered) > 0) return;
|
|
75683
|
+
if (mark_written_record(gobj, topic_name, queued) > 0) return;
|
|
75610
75684
|
let topic = current_topic(gobj);
|
|
75611
|
-
if (topic_name === T_TOPICS && record && record.id) {
|
|
75612
|
-
priv.written[record.id] = true;
|
|
75613
|
-
return;
|
|
75614
|
-
}
|
|
75615
75685
|
if (topic) priv.written[topic.id] = true;
|
|
75616
75686
|
}
|
|
75617
75687
|
/***************************************************************
|
package/dist/gobj-ui.es.js
CHANGED
|
@@ -24919,6 +24919,17 @@ function treedb_nodes$1(gobj, treedb_name, topic_name, options, page, purpose) {
|
|
|
24919
24919
|
return 0;
|
|
24920
24920
|
}
|
|
24921
24921
|
/************************************************************
|
|
24922
|
+
* The record a write answered: the node the store wrote (an
|
|
24923
|
+
* update or a create), deleted, or the child of a link. The
|
|
24924
|
+
* answer's frame carries back only `__md_command__`, never the
|
|
24925
|
+
* request's own record.
|
|
24926
|
+
************************************************************/
|
|
24927
|
+
function answered_record$1(data) {
|
|
24928
|
+
if (data && typeof data === "object" && !Array.isArray(data)) return data;
|
|
24929
|
+
if (Array.isArray(data) && data[0] && typeof data[0] === "object") return data[0];
|
|
24930
|
+
return {};
|
|
24931
|
+
}
|
|
24932
|
+
/************************************************************
|
|
24922
24933
|
* Command to remote service
|
|
24923
24934
|
************************************************************/
|
|
24924
24935
|
function treedb_update_node$1(gobj, treedb_name, topic_name, record, options, form_write) {
|
|
@@ -25240,9 +25251,9 @@ function ac_mt_command_answer$2(gobj, event, kw, src) {
|
|
|
25240
25251
|
case "create-node":
|
|
25241
25252
|
case "update-node":
|
|
25242
25253
|
gobj_publish_event(gobj, "EV_RECORD_WRITTEN", {
|
|
25243
|
-
treedb_name:
|
|
25254
|
+
treedb_name: gobj_read_str_attr(gobj, "treedb_name"),
|
|
25244
25255
|
topic_name: kw_get_str(gobj, kw_command, "topic_name", "", 0),
|
|
25245
|
-
record:
|
|
25256
|
+
record: answered_record$1(data),
|
|
25246
25257
|
created: command === "create-node",
|
|
25247
25258
|
command
|
|
25248
25259
|
});
|
|
@@ -68373,6 +68384,7 @@ function treedb_update_node(gobj, treedb_name, topic_name, record, options) {
|
|
|
68373
68384
|
options: options || {}
|
|
68374
68385
|
};
|
|
68375
68386
|
kw.__md_command__ = { topic_name };
|
|
68387
|
+
if (topic_name === "__graphs__") kw.__md_command__.graph_topic = graph_topic_of(record);
|
|
68376
68388
|
let ret = gobj_command(priv.gobj_remote_yuno, command, kw, gobj);
|
|
68377
68389
|
if (ret) {
|
|
68378
68390
|
log_error(ret);
|
|
@@ -68402,6 +68414,29 @@ function treedb_delete_node(gobj, treedb_name, topic_name, record, options) {
|
|
|
68402
68414
|
if (ret) log_error(ret);
|
|
68403
68415
|
}
|
|
68404
68416
|
/************************************************************
|
|
68417
|
+
* What a link or an unlink asks back with its answer: the
|
|
68418
|
+
* topic of the CHILD (the node a link saves) and both refs.
|
|
68419
|
+
* `child_ref` is "topic^id", `parent_ref` "topic^id^hook".
|
|
68420
|
+
************************************************************/
|
|
68421
|
+
function link_echo(parent_ref, child_ref) {
|
|
68422
|
+
return {
|
|
68423
|
+
topic_name: typeof child_ref === "string" ? child_ref.split("^")[0] : "",
|
|
68424
|
+
parent_ref,
|
|
68425
|
+
child_ref
|
|
68426
|
+
};
|
|
68427
|
+
}
|
|
68428
|
+
/************************************************************
|
|
68429
|
+
* The record a write answered: the node the store wrote (an
|
|
68430
|
+
* update or a create), deleted, or the child of a link. The
|
|
68431
|
+
* answer's frame carries back only `__md_command__`, never the
|
|
68432
|
+
* request's own record.
|
|
68433
|
+
************************************************************/
|
|
68434
|
+
function answered_record(data) {
|
|
68435
|
+
if (data && typeof data === "object" && !Array.isArray(data)) return data;
|
|
68436
|
+
if (Array.isArray(data) && data[0] && typeof data[0] === "object") return data[0];
|
|
68437
|
+
return {};
|
|
68438
|
+
}
|
|
68439
|
+
/************************************************************
|
|
68405
68440
|
* Command to remote service
|
|
68406
68441
|
************************************************************/
|
|
68407
68442
|
function treedb_link_nodes(gobj, treedb_name, parent_ref, child_ref, options) {
|
|
@@ -68418,6 +68453,7 @@ function treedb_link_nodes(gobj, treedb_name, parent_ref, child_ref, options) {
|
|
|
68418
68453
|
child_ref,
|
|
68419
68454
|
options: options || {}
|
|
68420
68455
|
};
|
|
68456
|
+
kw.__md_command__ = link_echo(parent_ref, child_ref);
|
|
68421
68457
|
let ret = gobj_command(priv.gobj_remote_yuno, command, kw, gobj);
|
|
68422
68458
|
if (ret) log_error(ret);
|
|
68423
68459
|
}
|
|
@@ -68438,6 +68474,7 @@ function treedb_unlink_nodes(gobj, treedb_name, parent_ref, child_ref, options)
|
|
|
68438
68474
|
child_ref,
|
|
68439
68475
|
options: options || {}
|
|
68440
68476
|
};
|
|
68477
|
+
kw.__md_command__ = link_echo(parent_ref, child_ref);
|
|
68441
68478
|
let ret = gobj_command(priv.gobj_remote_yuno, command, kw, gobj);
|
|
68442
68479
|
if (ret) log_error(ret);
|
|
68443
68480
|
}
|
|
@@ -68651,14 +68688,21 @@ function ac_mt_command_answer$1(gobj, event, kw, src) {
|
|
|
68651
68688
|
case "delete-node":
|
|
68652
68689
|
case "link-nodes":
|
|
68653
68690
|
case "unlink-nodes":
|
|
68654
|
-
if (result < 0 && command === "update-node") graphs_write_refused(gobj, kw_get_str(gobj, kw_command, "topic_name", "", 0),
|
|
68655
|
-
if (result >= 0 && kw_get_str(gobj, kw_command, "topic_name", "", 0) !== "__graphs__")
|
|
68656
|
-
|
|
68657
|
-
|
|
68658
|
-
|
|
68659
|
-
|
|
68660
|
-
|
|
68661
|
-
|
|
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));
|
|
68692
|
+
if (result >= 0 && kw_get_str(gobj, kw_command, "topic_name", "", 0) !== "__graphs__") {
|
|
68693
|
+
let written = {
|
|
68694
|
+
treedb_name: priv.treedb_name,
|
|
68695
|
+
topic_name: kw_get_str(gobj, kw_command, "topic_name", "", 0),
|
|
68696
|
+
record: answered_record(data),
|
|
68697
|
+
created: command === "create-node",
|
|
68698
|
+
command
|
|
68699
|
+
};
|
|
68700
|
+
if (command === "link-nodes" || command === "unlink-nodes") {
|
|
68701
|
+
written.parent_ref = kw_get_str(gobj, kw_command, "parent_ref", "", 0);
|
|
68702
|
+
written.child_ref = kw_get_str(gobj, kw_command, "child_ref", "", 0);
|
|
68703
|
+
}
|
|
68704
|
+
gobj_publish_event(gobj, "EV_RECORD_WRITTEN", written);
|
|
68705
|
+
}
|
|
68662
68706
|
break;
|
|
68663
68707
|
default: log_error(`${gobj_short_name(gobj)} Command unknown: ${command}`);
|
|
68664
68708
|
}
|
|
@@ -68900,29 +68944,35 @@ function ac_update_node(gobj, event, kw, src) {
|
|
|
68900
68944
|
let record = kw.record;
|
|
68901
68945
|
let options = kw.options || {};
|
|
68902
68946
|
if (refuse_if_readonly$1(gobj, event)) {
|
|
68903
|
-
graphs_write_refused(gobj, topic_name, record);
|
|
68947
|
+
graphs_write_refused(gobj, topic_name, graph_topic_of(record));
|
|
68904
68948
|
return -1;
|
|
68905
68949
|
}
|
|
68906
68950
|
if (topic_name === "__graphs__" && !is_connected(gobj)) {
|
|
68907
68951
|
log_warning(`${gobj_short_name(gobj)}: no session, the arrangement was not sent`);
|
|
68908
|
-
graphs_write_refused(gobj, topic_name, record);
|
|
68952
|
+
graphs_write_refused(gobj, topic_name, graph_topic_of(record));
|
|
68909
68953
|
return -1;
|
|
68910
68954
|
}
|
|
68911
68955
|
let ret = treedb_update_node(gobj, treedb_name, topic_name, record, options);
|
|
68912
|
-
if (ret < 0) graphs_write_refused(gobj, topic_name, record);
|
|
68956
|
+
if (ret < 0) graphs_write_refused(gobj, topic_name, graph_topic_of(record));
|
|
68913
68957
|
return ret;
|
|
68914
68958
|
}
|
|
68915
68959
|
/************************************************************
|
|
68960
|
+
* The topic a `__graphs__` record arranges.
|
|
68961
|
+
************************************************************/
|
|
68962
|
+
function graph_topic_of(record) {
|
|
68963
|
+
if (!record || typeof record !== "object") return "";
|
|
68964
|
+
return record.topic || record.id || "";
|
|
68965
|
+
}
|
|
68966
|
+
/************************************************************
|
|
68916
68967
|
* A write of `__graphs__` did not land. The engine
|
|
68917
68968
|
* (C_G6_NODES_TREE) took it for granted when it left -- nothing
|
|
68918
68969
|
* answers it when it lands -- so it is told, and its next Save
|
|
68919
68970
|
* writes the topic again. Other topics are the operator's data:
|
|
68920
68971
|
* the answer's error says what happened to them.
|
|
68921
68972
|
************************************************************/
|
|
68922
|
-
function graphs_write_refused(gobj, topic_name,
|
|
68973
|
+
function graphs_write_refused(gobj, topic_name, topic) {
|
|
68923
68974
|
let priv = gobj.priv;
|
|
68924
68975
|
if (topic_name !== "__graphs__") return;
|
|
68925
|
-
let topic = record && typeof record === "object" ? record.topic || record.id : "";
|
|
68926
68976
|
if (!topic) {
|
|
68927
68977
|
log_error(`${gobj_short_name(gobj)}: a refused __graphs__ write names no topic`);
|
|
68928
68978
|
return;
|
|
@@ -72481,11 +72531,18 @@ function el_attrs(attrs) {
|
|
|
72481
72531
|
return attrs;
|
|
72482
72532
|
}
|
|
72483
72533
|
/***************************************************************
|
|
72484
|
-
* The body stops answering while a write is in flight.
|
|
72534
|
+
* The body stops answering while a write is in flight. For the
|
|
72535
|
+
* keyboard too: `pointer-events` stops the mouse alone, and the
|
|
72536
|
+
* shell's focus trap puts the focus back on the row control that
|
|
72537
|
+
* had it, where Enter or Delete sent an action ST_SAVING does
|
|
72538
|
+
* not declare. `inert` takes the whole body out of reach.
|
|
72485
72539
|
***************************************************************/
|
|
72486
72540
|
function set_busy(gobj, busy) {
|
|
72487
72541
|
let $body = $of(gobj, ".SCHEMA_BODY");
|
|
72488
|
-
if ($body)
|
|
72542
|
+
if ($body) {
|
|
72543
|
+
$body.classList.toggle("SCHEMA_BUSY", !!busy);
|
|
72544
|
+
$body.toggleAttribute("inert", !!busy);
|
|
72545
|
+
}
|
|
72489
72546
|
}
|
|
72490
72547
|
/***************************************************************
|
|
72491
72548
|
* Shorthands for the three panes of the frame.
|
|
@@ -72701,7 +72758,7 @@ function request_model(gobj, keep_written) {
|
|
|
72701
72758
|
priv.records_before = null;
|
|
72702
72759
|
priv.load_round++;
|
|
72703
72760
|
priv.reload_on_open = true;
|
|
72704
|
-
priv.load_error =
|
|
72761
|
+
priv.load_error = "cannot reach the treedb";
|
|
72705
72762
|
if (priv.model) yui_shell_show_error(yui_shell_of(gobj), "cannot reach the treedb", { t });
|
|
72706
72763
|
end_load(gobj);
|
|
72707
72764
|
return -1;
|
|
@@ -72912,10 +72969,13 @@ function show_notice(gobj, key, detail) {
|
|
|
72912
72969
|
},
|
|
72913
72970
|
t(key)
|
|
72914
72971
|
]));
|
|
72915
|
-
if (detail) $notice.appendChild(createElement2([
|
|
72972
|
+
if (detail && detail !== key) $notice.appendChild(createElement2([
|
|
72916
72973
|
"span",
|
|
72917
|
-
{
|
|
72918
|
-
|
|
72974
|
+
{
|
|
72975
|
+
class: "SCHEMA_NOTICE_DETAIL yui-text-quiet ml-2",
|
|
72976
|
+
i18n: `${detail}`
|
|
72977
|
+
},
|
|
72978
|
+
t(`${detail}`)
|
|
72919
72979
|
]));
|
|
72920
72980
|
}
|
|
72921
72981
|
/***************************************************************
|
|
@@ -75470,7 +75530,7 @@ function ac_mt_command_answer(gobj, event, kw, src) {
|
|
|
75470
75530
|
return 0;
|
|
75471
75531
|
}
|
|
75472
75532
|
priv.pending--;
|
|
75473
|
-
if (result < 0) priv.load_error = comment ||
|
|
75533
|
+
if (result < 0) priv.load_error = comment || "cannot load the schemas";
|
|
75474
75534
|
else if (priv.records && Array.isArray(priv.records[topic_name])) priv.records[topic_name] = Array.isArray(data) ? data : [];
|
|
75475
75535
|
if (priv.pending > 0) return 0;
|
|
75476
75536
|
if (priv.load_error) {
|
|
@@ -75506,9 +75566,10 @@ function ac_mt_command_answer(gobj, event, kw, src) {
|
|
|
75506
75566
|
}
|
|
75507
75567
|
if (result < 0) return end_writes(gobj, comment || t("the treedb refused the write"));
|
|
75508
75568
|
priv.save_wrote = true;
|
|
75569
|
+
let record = null;
|
|
75509
75570
|
if (command === "delete-node") forget_record(gobj, topic_name, kw_get_str(gobj, md, "record_id", "", 0));
|
|
75510
75571
|
else {
|
|
75511
|
-
|
|
75572
|
+
record = is_object(data) ? data : Array.isArray(data) && is_object(data[0]) ? data[0] : null;
|
|
75512
75573
|
if (record) patch_record(gobj, topic_name, record);
|
|
75513
75574
|
else {
|
|
75514
75575
|
let not_sent = priv.save_queue.length - 1;
|
|
@@ -75516,7 +75577,7 @@ function ac_mt_command_answer(gobj, event, kw, src) {
|
|
|
75516
75577
|
if (not_sent > 0) yui_shell_show_error(yui_shell_of(gobj), "the treedb did not describe a write back: the writes after it were not sent", { t });
|
|
75517
75578
|
if (topic_name === T_TOPICS || topic_name === T_COLS) {
|
|
75518
75579
|
let write = priv.save_queue[0];
|
|
75519
|
-
mark_written(gobj, topic_name, write ? write.record : null);
|
|
75580
|
+
mark_written(gobj, topic_name, null, write ? write.record : null);
|
|
75520
75581
|
}
|
|
75521
75582
|
priv.reload_after_write = false;
|
|
75522
75583
|
priv.save_queue = [];
|
|
@@ -75531,7 +75592,7 @@ function ac_mt_command_answer(gobj, event, kw, src) {
|
|
|
75531
75592
|
}
|
|
75532
75593
|
if (topic_name === T_TOPICS || topic_name === T_COLS) {
|
|
75533
75594
|
let write = priv.save_queue[0];
|
|
75534
|
-
mark_written(gobj, topic_name, write ? write.record : null);
|
|
75595
|
+
mark_written(gobj, topic_name, record, write ? write.record : null);
|
|
75535
75596
|
}
|
|
75536
75597
|
priv.save_queue.shift();
|
|
75537
75598
|
return run_next_write(gobj);
|
|
@@ -75588,25 +75649,34 @@ function late_write_done(gobj, command, topic_name, data) {
|
|
|
75588
75649
|
***************************************************************/
|
|
75589
75650
|
function mark_written_record(gobj, topic_name, record) {
|
|
75590
75651
|
let priv = gobj.priv;
|
|
75591
|
-
|
|
75652
|
+
let marked = 0;
|
|
75653
|
+
if (!record) return 0;
|
|
75592
75654
|
if (topic_name === T_TOPICS && typeof record.id === "string" && record.id) {
|
|
75593
75655
|
priv.written[record.id] = true;
|
|
75594
|
-
return;
|
|
75656
|
+
return 1;
|
|
75595
75657
|
}
|
|
75596
|
-
if (topic_name !== T_COLS) return;
|
|
75597
|
-
for (let ref of parse_fkey_ref(record.topics))
|
|
75658
|
+
if (topic_name !== T_COLS) return 0;
|
|
75659
|
+
for (let ref of parse_fkey_ref(record.topics)) {
|
|
75660
|
+
priv.written[ref.id] = true;
|
|
75661
|
+
marked++;
|
|
75662
|
+
}
|
|
75663
|
+
return marked;
|
|
75598
75664
|
}
|
|
75599
75665
|
/***************************************************************
|
|
75600
75666
|
* Remember which topic this write belongs to, which is what
|
|
75601
75667
|
* "its version still has to move" is asked about.
|
|
75668
|
+
*
|
|
75669
|
+
* Asked of the RECORD first: the one the store answered (a new
|
|
75670
|
+
* topic has its id only there), then the one queued (a column
|
|
75671
|
+
* names its topic in its fkey). The screen is the last resort,
|
|
75672
|
+
* and a poor one: an import writes topics the operator is not
|
|
75673
|
+
* on, and from the topics screen there is no topic on it at all.
|
|
75602
75674
|
***************************************************************/
|
|
75603
|
-
function mark_written(gobj, topic_name,
|
|
75675
|
+
function mark_written(gobj, topic_name, answered, queued) {
|
|
75604
75676
|
let priv = gobj.priv;
|
|
75677
|
+
if (mark_written_record(gobj, topic_name, answered) > 0) return;
|
|
75678
|
+
if (mark_written_record(gobj, topic_name, queued) > 0) return;
|
|
75605
75679
|
let topic = current_topic(gobj);
|
|
75606
|
-
if (topic_name === T_TOPICS && record && record.id) {
|
|
75607
|
-
priv.written[record.id] = true;
|
|
75608
|
-
return;
|
|
75609
|
-
}
|
|
75610
75680
|
if (topic) priv.written[topic.id] = true;
|
|
75611
75681
|
}
|
|
75612
75682
|
/***************************************************************
|