@yuneta/gobj-ui 7.25.15 → 7.25.17
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 +106 -4
- package/dist/gobj-ui.cjs.js +274 -66
- package/dist/gobj-ui.es.js +274 -66
- package/package.json +2 -2
- package/src/c_g6_nodes_tree.js +37 -4
- package/src/c_yui_schema_editor.js +280 -47
- package/src/c_yui_treedb_graph.js +22 -6
- package/src/form_busy.test.js +1 -1
- package/src/form_writes_in_flight.test.js +1 -1
- package/src/g6_graphs_write_owed.wiring.test.js +200 -0
- package/src/host_drafts.test.js +2 -2
- package/src/schema_editor_drafts.wiring.test.js +1 -1
- package/src/schema_editor_reload.wiring.test.js +313 -4
- package/src/shell_modals.js +29 -8
- package/src/shell_toast_once.test.js +63 -0
- package/src/table_cell_text.test.js +1 -1
- package/src/treedb_graph_writes.wiring.test.js +8 -1
- package/src/treedb_topics_transport.wiring.test.js +1 -1
- package/src/yui_install.js +14 -3
- package/src/yui_install.test.js +23 -0
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -3437,8 +3437,28 @@ function build_dialog(shell, message, buttons, opts) {
|
|
|
3437
3437
|
if ($primary) $primary.focus();
|
|
3438
3438
|
});
|
|
3439
3439
|
}
|
|
3440
|
+
/***************************************************************
|
|
3441
|
+
* The labels a confirmation shows when the caller names none.
|
|
3442
|
+
*
|
|
3443
|
+
* They are i18n KEYS, lower-case like every key: a button
|
|
3444
|
+
* translates its label with the app's t() -- its text, its title
|
|
3445
|
+
* and its aria-label. Until 7.25.16 they were "OK", "Yes", "No",
|
|
3446
|
+
* "Delete" and "Cancel", keys that no locale carries, so a dialog
|
|
3447
|
+
* that took the defaults read in English in every language.
|
|
3448
|
+
*
|
|
3449
|
+
* Written as `i18n:` entries so the validate-locales script of a
|
|
3450
|
+
* consumer finds them when it scans this module: an app that
|
|
3451
|
+
* mounts these dialogs must define the five keys.
|
|
3452
|
+
***************************************************************/
|
|
3453
|
+
var DEFAULT_LABEL = Object.freeze({
|
|
3454
|
+
ok: Object.freeze({ i18n: "ok" }),
|
|
3455
|
+
yes: Object.freeze({ i18n: "yes" }),
|
|
3456
|
+
no: Object.freeze({ i18n: "no" }),
|
|
3457
|
+
delete: Object.freeze({ i18n: "delete" }),
|
|
3458
|
+
cancel: Object.freeze({ i18n: "cancel" })
|
|
3459
|
+
});
|
|
3440
3460
|
function yui_shell_confirm_ok(shell, message, opts) {
|
|
3441
|
-
let label = opts && opts.ok_label ||
|
|
3461
|
+
let label = opts && opts.ok_label || DEFAULT_LABEL.ok.i18n;
|
|
3442
3462
|
if (!opts || !opts.type) opts = Object.assign({}, opts, { type: "success" });
|
|
3443
3463
|
return build_dialog(shell, message, [{
|
|
3444
3464
|
label,
|
|
@@ -3447,8 +3467,8 @@ function yui_shell_confirm_ok(shell, message, opts) {
|
|
|
3447
3467
|
}], opts).then(() => void 0);
|
|
3448
3468
|
}
|
|
3449
3469
|
function yui_shell_confirm_yesno(shell, message, opts) {
|
|
3450
|
-
let yes_label = opts && opts.yes_label ||
|
|
3451
|
-
let no_label = opts && opts.no_label ||
|
|
3470
|
+
let yes_label = opts && opts.yes_label || DEFAULT_LABEL.yes.i18n;
|
|
3471
|
+
let no_label = opts && opts.no_label || DEFAULT_LABEL.no.i18n;
|
|
3452
3472
|
return build_dialog(shell, message, [{
|
|
3453
3473
|
label: yes_label,
|
|
3454
3474
|
value: "yes",
|
|
@@ -3473,8 +3493,8 @@ function yui_shell_confirm_yesno(shell, message, opts) {
|
|
|
3473
3493
|
* pressed.
|
|
3474
3494
|
***************************************************************/
|
|
3475
3495
|
function yui_shell_confirm_danger(shell, message, opts) {
|
|
3476
|
-
let confirm_label = opts && opts.confirm_label ||
|
|
3477
|
-
let cancel_label = opts && opts.cancel_label ||
|
|
3496
|
+
let confirm_label = opts && opts.confirm_label || DEFAULT_LABEL.delete.i18n;
|
|
3497
|
+
let cancel_label = opts && opts.cancel_label || DEFAULT_LABEL.cancel.i18n;
|
|
3478
3498
|
if (!opts || !opts.type) opts = Object.assign({}, opts, { type: "danger" });
|
|
3479
3499
|
return build_dialog(shell, message, [{
|
|
3480
3500
|
label: confirm_label,
|
|
@@ -3486,9 +3506,9 @@ function yui_shell_confirm_danger(shell, message, opts) {
|
|
|
3486
3506
|
}], opts).then((v) => v === "confirm");
|
|
3487
3507
|
}
|
|
3488
3508
|
function yui_shell_confirm_yesnocancel(shell, message, opts) {
|
|
3489
|
-
let yes_label = opts && opts.yes_label ||
|
|
3490
|
-
let no_label = opts && opts.no_label ||
|
|
3491
|
-
let cancel_label = opts && opts.cancel_label ||
|
|
3509
|
+
let yes_label = opts && opts.yes_label || DEFAULT_LABEL.yes.i18n;
|
|
3510
|
+
let no_label = opts && opts.no_label || DEFAULT_LABEL.no.i18n;
|
|
3511
|
+
let cancel_label = opts && opts.cancel_label || DEFAULT_LABEL.cancel.i18n;
|
|
3492
3512
|
return build_dialog(shell, message, [
|
|
3493
3513
|
{
|
|
3494
3514
|
label: yes_label,
|
|
@@ -59232,6 +59252,7 @@ var PRIVATE_DATA$4 = {
|
|
|
59232
59252
|
__graphs__: [],
|
|
59233
59253
|
_graph_properties: {},
|
|
59234
59254
|
_saved_graph_properties: {},
|
|
59255
|
+
_graphs_writes_owed: {},
|
|
59235
59256
|
yet_showed: false,
|
|
59236
59257
|
edit_mode: false,
|
|
59237
59258
|
operation_mode: null,
|
|
@@ -60927,6 +60948,7 @@ function save_topic_graph_properties(gobj, topic_name) {
|
|
|
60927
60948
|
if (!topic_arrangement_changed(properties, priv._saved_graph_properties[topic_name])) return;
|
|
60928
60949
|
properties.__origin__ = (0, _yuneta_gobj_js.gobj_read_str_attr)((0, _yuneta_gobj_js.gobj_yuno)(), "node_uuid");
|
|
60929
60950
|
priv._saved_graph_properties[topic_name] = (0, _yuneta_gobj_js.json_deep_copy)(properties);
|
|
60951
|
+
delete priv._graphs_writes_owed[topic_name];
|
|
60930
60952
|
let kw_update = {
|
|
60931
60953
|
treedb_name: priv.treedb_name,
|
|
60932
60954
|
topic_name: "__graphs__",
|
|
@@ -61008,8 +61030,13 @@ function update_history_buttons(gobj) {
|
|
|
61008
61030
|
} else {
|
|
61009
61031
|
disableElements($container, ".EV_HISTORY_UNDO");
|
|
61010
61032
|
set_active_state($container, ".EV_HISTORY_UNDO", false);
|
|
61011
|
-
|
|
61012
|
-
|
|
61033
|
+
if (graphs_write_is_owed(gobj)) {
|
|
61034
|
+
enableElements($container, ".EV_SAVE_GRAPH");
|
|
61035
|
+
set_submit_state($container, ".EV_SAVE_GRAPH", true);
|
|
61036
|
+
} else {
|
|
61037
|
+
disableElements($container, ".EV_SAVE_GRAPH");
|
|
61038
|
+
set_submit_state($container, ".EV_SAVE_GRAPH", false);
|
|
61039
|
+
}
|
|
61013
61040
|
}
|
|
61014
61041
|
} else {
|
|
61015
61042
|
disableElements($container, ".EV_HISTORY_REDO");
|
|
@@ -61966,6 +61993,15 @@ function run_preview_undo(gobj, key) {
|
|
|
61966
61993
|
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: cannot undo the preview: ${e}`);
|
|
61967
61994
|
}
|
|
61968
61995
|
}
|
|
61996
|
+
/************************************************************
|
|
61997
|
+
* Is a `__graphs__` write owed? The host said one did not land
|
|
61998
|
+
* (EV_GRAPHS_WRITE_REFUSED), and no Save has written that topic
|
|
61999
|
+
* since. The Save button stays lit while it is: the history
|
|
62000
|
+
* knows nothing of it, so `canUndo()` alone would put it out.
|
|
62001
|
+
************************************************************/
|
|
62002
|
+
function graphs_write_is_owed(gobj) {
|
|
62003
|
+
return Object.keys(gobj.priv._graphs_writes_owed).length > 0;
|
|
62004
|
+
}
|
|
61969
62005
|
function mark_graph_dirty(gobj) {
|
|
61970
62006
|
let $container = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container");
|
|
61971
62007
|
enableElements($container, ".EV_SAVE_GRAPH");
|
|
@@ -65706,6 +65742,7 @@ function ac_clear_data(gobj, event, kw, src) {
|
|
|
65706
65742
|
deselect_node(gobj);
|
|
65707
65743
|
hide_create_popover(gobj);
|
|
65708
65744
|
(0, _yuneta_gobj_js.gobj_write_attr)(gobj, "records", {});
|
|
65745
|
+
priv._graphs_writes_owed = {};
|
|
65709
65746
|
priv._nodes_total = 0;
|
|
65710
65747
|
priv._nodes_placed = 0;
|
|
65711
65748
|
priv._fold_model = null;
|
|
@@ -65798,11 +65835,9 @@ function ac_save_graph(gobj, event, kw, src) {
|
|
|
65798
65835
|
disableElements($container, ".EV_SAVE_GRAPH");
|
|
65799
65836
|
set_submit_state($container, ".EV_SAVE_GRAPH", false);
|
|
65800
65837
|
let history = graph_get_plugin(gobj, "history");
|
|
65801
|
-
if (history)
|
|
65802
|
-
history.clear();
|
|
65803
|
-
update_history_buttons(gobj);
|
|
65804
|
-
}
|
|
65838
|
+
if (history) history.clear();
|
|
65805
65839
|
save_geometry(gobj);
|
|
65840
|
+
update_history_buttons(gobj);
|
|
65806
65841
|
}
|
|
65807
65842
|
return 0;
|
|
65808
65843
|
}
|
|
@@ -65825,6 +65860,7 @@ function ac_graphs_write_refused(gobj, event, kw, src) {
|
|
|
65825
65860
|
}
|
|
65826
65861
|
(0, _yuneta_gobj_js.log_warning)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: the arrangement of '${topic_name}' was not saved: the next Save writes it again`);
|
|
65827
65862
|
forget_refused_graphs_write(priv._saved_graph_properties, topic_name);
|
|
65863
|
+
priv._graphs_writes_owed[topic_name] = true;
|
|
65828
65864
|
if (priv.edit_mode) mark_graph_dirty(gobj);
|
|
65829
65865
|
return 0;
|
|
65830
65866
|
}
|
|
@@ -68342,6 +68378,7 @@ function treedb_update_node(gobj, treedb_name, topic_name, record, options) {
|
|
|
68342
68378
|
options: options || {}
|
|
68343
68379
|
};
|
|
68344
68380
|
kw.__md_command__ = { topic_name };
|
|
68381
|
+
if (topic_name === "__graphs__") kw.__md_command__.graph_topic = graph_topic_of(record);
|
|
68345
68382
|
let ret = (0, _yuneta_gobj_js.gobj_command)(priv.gobj_remote_yuno, command, kw, gobj);
|
|
68346
68383
|
if (ret) {
|
|
68347
68384
|
(0, _yuneta_gobj_js.log_error)(ret);
|
|
@@ -68620,7 +68657,7 @@ function ac_mt_command_answer$1(gobj, event, kw, src) {
|
|
|
68620
68657
|
case "delete-node":
|
|
68621
68658
|
case "link-nodes":
|
|
68622
68659
|
case "unlink-nodes":
|
|
68623
|
-
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 && 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));
|
|
68624
68661
|
if (result >= 0 && (0, _yuneta_gobj_js.kw_get_str)(gobj, kw_command, "topic_name", "", 0) !== "__graphs__") (0, _yuneta_gobj_js.gobj_publish_event)(gobj, "EV_RECORD_WRITTEN", {
|
|
68625
68662
|
treedb_name: (0, _yuneta_gobj_js.kw_get_str)(gobj, kw_command, "treedb_name", "", 0),
|
|
68626
68663
|
topic_name: (0, _yuneta_gobj_js.kw_get_str)(gobj, kw_command, "topic_name", "", 0),
|
|
@@ -68869,29 +68906,35 @@ function ac_update_node(gobj, event, kw, src) {
|
|
|
68869
68906
|
let record = kw.record;
|
|
68870
68907
|
let options = kw.options || {};
|
|
68871
68908
|
if (refuse_if_readonly$1(gobj, event)) {
|
|
68872
|
-
graphs_write_refused(gobj, topic_name, record);
|
|
68909
|
+
graphs_write_refused(gobj, topic_name, graph_topic_of(record));
|
|
68873
68910
|
return -1;
|
|
68874
68911
|
}
|
|
68875
68912
|
if (topic_name === "__graphs__" && !is_connected(gobj)) {
|
|
68876
68913
|
(0, _yuneta_gobj_js.log_warning)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: no session, the arrangement was not sent`);
|
|
68877
|
-
graphs_write_refused(gobj, topic_name, record);
|
|
68914
|
+
graphs_write_refused(gobj, topic_name, graph_topic_of(record));
|
|
68878
68915
|
return -1;
|
|
68879
68916
|
}
|
|
68880
68917
|
let ret = treedb_update_node(gobj, treedb_name, topic_name, record, options);
|
|
68881
|
-
if (ret < 0) graphs_write_refused(gobj, topic_name, record);
|
|
68918
|
+
if (ret < 0) graphs_write_refused(gobj, topic_name, graph_topic_of(record));
|
|
68882
68919
|
return ret;
|
|
68883
68920
|
}
|
|
68884
68921
|
/************************************************************
|
|
68922
|
+
* The topic a `__graphs__` record arranges.
|
|
68923
|
+
************************************************************/
|
|
68924
|
+
function graph_topic_of(record) {
|
|
68925
|
+
if (!record || typeof record !== "object") return "";
|
|
68926
|
+
return record.topic || record.id || "";
|
|
68927
|
+
}
|
|
68928
|
+
/************************************************************
|
|
68885
68929
|
* A write of `__graphs__` did not land. The engine
|
|
68886
68930
|
* (C_G6_NODES_TREE) took it for granted when it left -- nothing
|
|
68887
68931
|
* answers it when it lands -- so it is told, and its next Save
|
|
68888
68932
|
* writes the topic again. Other topics are the operator's data:
|
|
68889
68933
|
* the answer's error says what happened to them.
|
|
68890
68934
|
************************************************************/
|
|
68891
|
-
function graphs_write_refused(gobj, topic_name,
|
|
68935
|
+
function graphs_write_refused(gobj, topic_name, topic) {
|
|
68892
68936
|
let priv = gobj.priv;
|
|
68893
68937
|
if (topic_name !== "__graphs__") return;
|
|
68894
|
-
let topic = record && typeof record === "object" ? record.topic || record.id : "";
|
|
68895
68938
|
if (!topic) {
|
|
68896
68939
|
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: a refused __graphs__ write names no topic`);
|
|
68897
68940
|
return;
|
|
@@ -72334,6 +72377,8 @@ var PRIVATE_DATA$1 = {
|
|
|
72334
72377
|
dropped_round: 0,
|
|
72335
72378
|
dropped_write: 0,
|
|
72336
72379
|
reload_after_write: false,
|
|
72380
|
+
refresh_after_write: false,
|
|
72381
|
+
reopen_form: null,
|
|
72337
72382
|
pending_seg: null,
|
|
72338
72383
|
import_plan: null,
|
|
72339
72384
|
import_pane: null,
|
|
@@ -72448,11 +72493,18 @@ function el_attrs(attrs) {
|
|
|
72448
72493
|
return attrs;
|
|
72449
72494
|
}
|
|
72450
72495
|
/***************************************************************
|
|
72451
|
-
* The body stops answering while a write is in flight.
|
|
72496
|
+
* The body stops answering while a write is in flight. For the
|
|
72497
|
+
* keyboard too: `pointer-events` stops the mouse alone, and the
|
|
72498
|
+
* shell's focus trap puts the focus back on the row control that
|
|
72499
|
+
* had it, where Enter or Delete sent an action ST_SAVING does
|
|
72500
|
+
* not declare. `inert` takes the whole body out of reach.
|
|
72452
72501
|
***************************************************************/
|
|
72453
72502
|
function set_busy(gobj, busy) {
|
|
72454
72503
|
let $body = $of(gobj, ".SCHEMA_BODY");
|
|
72455
|
-
if ($body)
|
|
72504
|
+
if ($body) {
|
|
72505
|
+
$body.classList.toggle("SCHEMA_BUSY", !!busy);
|
|
72506
|
+
$body.toggleAttribute("inert", !!busy);
|
|
72507
|
+
}
|
|
72456
72508
|
}
|
|
72457
72509
|
/***************************************************************
|
|
72458
72510
|
* Shorthands for the three panes of the frame.
|
|
@@ -72539,14 +72591,61 @@ function owes_reload(gobj) {
|
|
|
72539
72591
|
let state = (0, _yuneta_gobj_js.gobj_current_state)(gobj);
|
|
72540
72592
|
return gobj.priv.reload_on_open && transport_in_session(gobj) && state !== "ST_LOADING" && state !== "ST_SAVING";
|
|
72541
72593
|
}
|
|
72542
|
-
function reload_first(gobj, event) {
|
|
72594
|
+
function reload_first(gobj, event, reopen) {
|
|
72595
|
+
let priv = gobj.priv;
|
|
72543
72596
|
if (!owes_reload(gobj)) return false;
|
|
72544
|
-
|
|
72597
|
+
priv.reload_on_open = false;
|
|
72598
|
+
if (reopen && priv.dialog) {
|
|
72599
|
+
priv.reopen_form = Object.assign((0, _yuneta_gobj_js.json_deep_copy)(reopen), {
|
|
72600
|
+
dialog: priv.dialog,
|
|
72601
|
+
treedb_id: priv.treedb_id
|
|
72602
|
+
});
|
|
72603
|
+
(0, _yuneta_gobj_js.log_warning)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: ${event} refused, the schemas shown may be out of date: they are read again first, and the form opens again on them with its changes`);
|
|
72604
|
+
yui_shell_show_error(yui_shell_of(gobj), "the schemas shown may be out of date: they are read again, and the form opens again on them with your changes", { t: i18next.t });
|
|
72605
|
+
request_model(gobj, true);
|
|
72606
|
+
return true;
|
|
72607
|
+
}
|
|
72545
72608
|
(0, _yuneta_gobj_js.log_warning)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: ${event} refused, the schemas shown may be out of date: they are read again first`);
|
|
72546
72609
|
yui_shell_show_error(yui_shell_of(gobj), "the schemas shown may be out of date: they are read again, try again when they are in", { t: i18next.t });
|
|
72547
72610
|
request_model(gobj, true);
|
|
72548
72611
|
return true;
|
|
72549
72612
|
}
|
|
72613
|
+
/***************************************************************
|
|
72614
|
+
* The form reload_first() took down, opened again on the model
|
|
72615
|
+
* the load just made, with the operator's changes on top.
|
|
72616
|
+
*
|
|
72617
|
+
* Only where it can mean the same thing: on the treedb it was
|
|
72618
|
+
* opened on, on the screen whose Save it has, and on a record
|
|
72619
|
+
* that is still there. Otherwise it is not opened, and that is
|
|
72620
|
+
* said -- a form opened on another treedb, or on nothing, would
|
|
72621
|
+
* save somewhere the operator never meant.
|
|
72622
|
+
***************************************************************/
|
|
72623
|
+
function reopen_form(gobj, r) {
|
|
72624
|
+
let priv = gobj.priv;
|
|
72625
|
+
let state = (0, _yuneta_gobj_js.gobj_current_state)(gobj);
|
|
72626
|
+
let treedb = current_treedb(gobj);
|
|
72627
|
+
let topic = null;
|
|
72628
|
+
let col = null;
|
|
72629
|
+
let fits = false;
|
|
72630
|
+
if (treedb && r.treedb_id === priv.treedb_id) {
|
|
72631
|
+
if (r.form === "column" && state === "ST_COLUMNS") {
|
|
72632
|
+
topic = find_topic(priv.model, priv.treedb_id, r.topic);
|
|
72633
|
+
col = topic && !r.creating ? find_col(priv.model, priv.treedb_id, r.topic, r.col) : null;
|
|
72634
|
+
fits = !!topic && (r.creating || !!col);
|
|
72635
|
+
} else if (r.form === "topic" && state === "ST_TOPICS") {
|
|
72636
|
+
topic = r.creating ? null : find_topic(priv.model, priv.treedb_id, r.topic);
|
|
72637
|
+
fits = r.creating || !!topic;
|
|
72638
|
+
}
|
|
72639
|
+
}
|
|
72640
|
+
if (!fits) {
|
|
72641
|
+
(0, _yuneta_gobj_js.log_warning)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: the ${r.form} form was not opened again: what it edited is not on the schemas the reload read (${r.treedb_id} ${r.topic}${r.col ? "." + r.col : ""}, now ${state})`);
|
|
72642
|
+
yui_shell_show_error(yui_shell_of(gobj), "the schemas were read again and what the form was editing is not there any more", { t: i18next.t });
|
|
72643
|
+
return -1;
|
|
72644
|
+
}
|
|
72645
|
+
if (r.form === "column") open_column_form(gobj, topic, col, null, r.changed);
|
|
72646
|
+
else open_topic_form(gobj, treedb, topic, r.changed);
|
|
72647
|
+
return 0;
|
|
72648
|
+
}
|
|
72550
72649
|
function reload_after_move(gobj) {
|
|
72551
72650
|
if (!owes_reload(gobj)) return 0;
|
|
72552
72651
|
gobj.priv.reload_on_open = false;
|
|
@@ -72621,7 +72720,7 @@ function request_model(gobj, keep_written) {
|
|
|
72621
72720
|
priv.records_before = null;
|
|
72622
72721
|
priv.load_round++;
|
|
72623
72722
|
priv.reload_on_open = true;
|
|
72624
|
-
priv.load_error =
|
|
72723
|
+
priv.load_error = "cannot reach the treedb";
|
|
72625
72724
|
if (priv.model) yui_shell_show_error(yui_shell_of(gobj), "cannot reach the treedb", { t: i18next.t });
|
|
72626
72725
|
end_load(gobj);
|
|
72627
72726
|
return -1;
|
|
@@ -72692,7 +72791,7 @@ function build_model(gobj) {
|
|
|
72692
72791
|
* measurement of "changed since" can be measured against.
|
|
72693
72792
|
*
|
|
72694
72793
|
* `written` is forgotten only by an EV_REFRESH (the view's own
|
|
72695
|
-
* Refresh button, or a host that sends one). Since
|
|
72794
|
+
* Refresh button, or a host that sends one). Since 7.23.196 a write moves no
|
|
72696
72795
|
* version, so `written` is the draft chip of what this session
|
|
72697
72796
|
* wrote and no longer half of a version measurement: a reload of
|
|
72698
72797
|
* the reconnect, or of a write that turned out done, forgot the
|
|
@@ -72832,10 +72931,13 @@ function show_notice(gobj, key, detail) {
|
|
|
72832
72931
|
},
|
|
72833
72932
|
(0, i18next.t)(key)
|
|
72834
72933
|
]));
|
|
72835
|
-
if (detail) $notice.appendChild((0, _yuneta_gobj_js.createElement2)([
|
|
72934
|
+
if (detail && detail !== key) $notice.appendChild((0, _yuneta_gobj_js.createElement2)([
|
|
72836
72935
|
"span",
|
|
72837
|
-
{
|
|
72838
|
-
|
|
72936
|
+
{
|
|
72937
|
+
class: "SCHEMA_NOTICE_DETAIL yui-text-quiet ml-2",
|
|
72938
|
+
i18n: `${detail}`
|
|
72939
|
+
},
|
|
72940
|
+
(0, i18next.t)(`${detail}`)
|
|
72839
72941
|
]));
|
|
72840
72942
|
}
|
|
72841
72943
|
/***************************************************************
|
|
@@ -73970,6 +74072,55 @@ function read_form($root) {
|
|
|
73970
74072
|
return out;
|
|
73971
74073
|
}
|
|
73972
74074
|
/***************************************************************
|
|
74075
|
+
* A column form as its Save sends it: the fields and the flags.
|
|
74076
|
+
***************************************************************/
|
|
74077
|
+
function column_form_state($form) {
|
|
74078
|
+
let values = read_form($form);
|
|
74079
|
+
values.flag = read_flags($form);
|
|
74080
|
+
return values;
|
|
74081
|
+
}
|
|
74082
|
+
/***************************************************************
|
|
74083
|
+
* The fields the operator CHANGED: those whose value is not the
|
|
74084
|
+
* one the form was opened with.
|
|
74085
|
+
***************************************************************/
|
|
74086
|
+
function form_changes(initial, values) {
|
|
74087
|
+
let changed = {};
|
|
74088
|
+
for (let name of Object.keys(values)) if (JSON.stringify(values[name]) !== JSON.stringify(initial[name])) changed[name] = values[name];
|
|
74089
|
+
return changed;
|
|
74090
|
+
}
|
|
74091
|
+
/***************************************************************
|
|
74092
|
+
* Put changes back into a form just built (reopen_form()). The
|
|
74093
|
+
* flags are drawn again for the type the changes leave, holding
|
|
74094
|
+
* the flags they name, so none of them is hidden by the type.
|
|
74095
|
+
***************************************************************/
|
|
74096
|
+
function apply_form_changes(gobj, $form, changes) {
|
|
74097
|
+
for (let name of Object.keys(changes)) {
|
|
74098
|
+
if (name === "flag") continue;
|
|
74099
|
+
let $control = $form.querySelector(`[data-name="${name}"]`);
|
|
74100
|
+
if (!$control) {
|
|
74101
|
+
(0, _yuneta_gobj_js.log_warning)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: a change of '${name}' has no field in the form opened again: not put back`);
|
|
74102
|
+
continue;
|
|
74103
|
+
}
|
|
74104
|
+
if ($control.type === "checkbox") $control.checked = !!changes[name];
|
|
74105
|
+
else $control.value = changes[name];
|
|
74106
|
+
}
|
|
74107
|
+
let $type = $form.querySelector("[data-name=\"type\"]");
|
|
74108
|
+
if ($type && $form.querySelector(".SCHEMA_FLAGS")) {
|
|
74109
|
+
let flags = Array.isArray(changes.flag) ? changes.flag : read_flags($form);
|
|
74110
|
+
redraw_flags(gobj, $form, $type.value, flags);
|
|
74111
|
+
}
|
|
74112
|
+
}
|
|
74113
|
+
/***************************************************************
|
|
74114
|
+
* Draw the flags of a column form again, for `type`, with
|
|
74115
|
+
* `current` checked.
|
|
74116
|
+
***************************************************************/
|
|
74117
|
+
function redraw_flags(gobj, $form, type, current) {
|
|
74118
|
+
let $holder = $form.querySelector(".SCHEMA_FLAGS");
|
|
74119
|
+
let $new = (0, _yuneta_gobj_js.createElement2)(flags_field(gobj, type, current));
|
|
74120
|
+
$holder.parentNode.replaceChild($new, $holder);
|
|
74121
|
+
(0, _yuneta_gobj_js.refresh_language)($new, i18next.t);
|
|
74122
|
+
}
|
|
74123
|
+
/***************************************************************
|
|
73973
74124
|
* The flags of a column, as checkboxes that say what they do.
|
|
73974
74125
|
*
|
|
73975
74126
|
* Grouped the way they act, greyed when they are meaningless on
|
|
@@ -74043,7 +74194,7 @@ function read_flags($root) {
|
|
|
74043
74194
|
* Offering a field that silently does something else is worse
|
|
74044
74195
|
* than not offering it.
|
|
74045
74196
|
***************************************************************/
|
|
74046
|
-
function open_column_form(gobj, topic, col, prefill) {
|
|
74197
|
+
function open_column_form(gobj, topic, col, prefill, changes) {
|
|
74047
74198
|
let priv = gobj.priv;
|
|
74048
74199
|
let record = prefill || col && col.record || {};
|
|
74049
74200
|
let creating = !col;
|
|
@@ -74147,11 +74298,7 @@ function open_column_form(gobj, topic, col, prefill) {
|
|
|
74147
74298
|
]);
|
|
74148
74299
|
let $type = $form.querySelector("[data-name=\"type\"]");
|
|
74149
74300
|
$type.addEventListener("change", () => {
|
|
74150
|
-
|
|
74151
|
-
let current = read_flags($form);
|
|
74152
|
-
let $new = (0, _yuneta_gobj_js.createElement2)(flags_field(gobj, $type.value, current));
|
|
74153
|
-
$holder.parentNode.replaceChild($new, $holder);
|
|
74154
|
-
(0, _yuneta_gobj_js.refresh_language)($new, i18next.t);
|
|
74301
|
+
redraw_flags(gobj, $form, $type.value, read_flags($form));
|
|
74155
74302
|
});
|
|
74156
74303
|
$form.addEventListener("change", (evt) => {
|
|
74157
74304
|
let $box = evt.target.closest(".SCHEMA_FLAG_BOX");
|
|
@@ -74163,15 +74310,17 @@ function open_column_form(gobj, topic, col, prefill) {
|
|
|
74163
74310
|
evt.stopPropagation();
|
|
74164
74311
|
close_dialog(gobj);
|
|
74165
74312
|
});
|
|
74313
|
+
let initial = column_form_state($form);
|
|
74314
|
+
if (changes) apply_form_changes(gobj, $form, changes);
|
|
74166
74315
|
$form.querySelector(".SCHEMA_COL_FORM_SAVE").addEventListener("click", (evt) => {
|
|
74167
74316
|
evt.stopPropagation();
|
|
74168
|
-
let values =
|
|
74169
|
-
values.flag = read_flags($form);
|
|
74317
|
+
let values = column_form_state($form);
|
|
74170
74318
|
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_SAVE_COLUMN", {
|
|
74171
74319
|
topic: topic.name,
|
|
74172
74320
|
col: creating ? "" : col.name,
|
|
74173
74321
|
creating,
|
|
74174
74322
|
values,
|
|
74323
|
+
changed: creating ? values : form_changes(initial, values),
|
|
74175
74324
|
model_gen
|
|
74176
74325
|
}, gobj);
|
|
74177
74326
|
});
|
|
@@ -74191,7 +74340,7 @@ function stringify_field(value) {
|
|
|
74191
74340
|
* actually has: a pkey naming no column is a topic that does
|
|
74192
74341
|
* not open, and it is the first thing the validator looks for.
|
|
74193
74342
|
***************************************************************/
|
|
74194
|
-
function open_topic_form(gobj, treedb, topic) {
|
|
74343
|
+
function open_topic_form(gobj, treedb, topic, changes) {
|
|
74195
74344
|
let record = topic && topic.record || {};
|
|
74196
74345
|
let creating = !topic;
|
|
74197
74346
|
let col_names = topic ? topic.cols.map((c) => c.name) : [];
|
|
@@ -74286,12 +74435,16 @@ function open_topic_form(gobj, treedb, topic) {
|
|
|
74286
74435
|
evt.stopPropagation();
|
|
74287
74436
|
close_dialog(gobj);
|
|
74288
74437
|
});
|
|
74438
|
+
let initial = read_form($form);
|
|
74439
|
+
if (changes) apply_form_changes(gobj, $form, changes);
|
|
74289
74440
|
$form.querySelector(".SCHEMA_TOPIC_FORM_SAVE").addEventListener("click", (evt) => {
|
|
74290
74441
|
evt.stopPropagation();
|
|
74442
|
+
let values = read_form($form);
|
|
74291
74443
|
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_SAVE_TOPIC", {
|
|
74292
74444
|
topic: creating ? "" : topic.name,
|
|
74293
74445
|
creating,
|
|
74294
|
-
values
|
|
74446
|
+
values,
|
|
74447
|
+
changed: creating ? values : form_changes(initial, values),
|
|
74295
74448
|
model_gen
|
|
74296
74449
|
}, gobj);
|
|
74297
74450
|
});
|
|
@@ -75061,20 +75214,28 @@ function transport_dropped(gobj) {
|
|
|
75061
75214
|
function end_load(gobj) {
|
|
75062
75215
|
let priv = gobj.priv;
|
|
75063
75216
|
let seg = priv.pending_seg;
|
|
75217
|
+
let reopen = priv.reopen_form;
|
|
75064
75218
|
priv.pending_seg = null;
|
|
75219
|
+
priv.reopen_form = null;
|
|
75065
75220
|
if (priv.dialog && priv.dialog_gen !== priv.model_gen) {
|
|
75066
|
-
|
|
75221
|
+
if (!reopen || reopen.dialog !== priv.dialog) {
|
|
75222
|
+
reopen = null;
|
|
75223
|
+
(0, _yuneta_gobj_js.log_warning)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: a dialog was open on the schemas the load replaced: closed`);
|
|
75224
|
+
yui_shell_show_error(yui_shell_of(gobj), "the schemas were read again: open the dialog again", { t: i18next.t });
|
|
75225
|
+
}
|
|
75067
75226
|
close_dialog(gobj);
|
|
75068
|
-
|
|
75069
|
-
|
|
75227
|
+
} else reopen = null;
|
|
75228
|
+
let ret = 0;
|
|
75070
75229
|
if (priv.model) {
|
|
75071
|
-
if (seg !== null)
|
|
75072
|
-
|
|
75230
|
+
if (seg !== null) ret = apply_seg(gobj, seg);
|
|
75231
|
+
else ret = go(gobj, priv.treedb_id, priv.topic_name, priv.diagram, false);
|
|
75232
|
+
} else {
|
|
75233
|
+
if (seg !== null) adopt_seg(gobj, seg);
|
|
75234
|
+
(0, _yuneta_gobj_js.gobj_change_state)(gobj, "ST_IDLE");
|
|
75235
|
+
render(gobj);
|
|
75073
75236
|
}
|
|
75074
|
-
if (
|
|
75075
|
-
|
|
75076
|
-
render(gobj);
|
|
75077
|
-
return 0;
|
|
75237
|
+
if (reopen) reopen_form(gobj, reopen);
|
|
75238
|
+
return ret;
|
|
75078
75239
|
}
|
|
75079
75240
|
/***************************************************************
|
|
75080
75241
|
* The queue is done, or gave up. Either way the model is what
|
|
@@ -75099,7 +75260,11 @@ function end_writes(gobj, error) {
|
|
|
75099
75260
|
render(gobj);
|
|
75100
75261
|
publish_check(gobj);
|
|
75101
75262
|
}
|
|
75102
|
-
|
|
75263
|
+
if (priv.refresh_after_write) {
|
|
75264
|
+
priv.refresh_after_write = false;
|
|
75265
|
+
priv.reload_after_write = false;
|
|
75266
|
+
request_model(gobj, false);
|
|
75267
|
+
} else reload_if_owed(gobj);
|
|
75103
75268
|
return error ? -1 : 0;
|
|
75104
75269
|
}
|
|
75105
75270
|
/***************************************************************
|
|
@@ -75327,7 +75492,7 @@ function ac_mt_command_answer(gobj, event, kw, src) {
|
|
|
75327
75492
|
return 0;
|
|
75328
75493
|
}
|
|
75329
75494
|
priv.pending--;
|
|
75330
|
-
if (result < 0) priv.load_error = comment ||
|
|
75495
|
+
if (result < 0) priv.load_error = comment || "cannot load the schemas";
|
|
75331
75496
|
else if (priv.records && Array.isArray(priv.records[topic_name])) priv.records[topic_name] = Array.isArray(data) ? data : [];
|
|
75332
75497
|
if (priv.pending > 0) return 0;
|
|
75333
75498
|
if (priv.load_error) {
|
|
@@ -75363,9 +75528,10 @@ function ac_mt_command_answer(gobj, event, kw, src) {
|
|
|
75363
75528
|
}
|
|
75364
75529
|
if (result < 0) return end_writes(gobj, comment || (0, i18next.t)("the treedb refused the write"));
|
|
75365
75530
|
priv.save_wrote = true;
|
|
75531
|
+
let record = null;
|
|
75366
75532
|
if (command === "delete-node") forget_record(gobj, topic_name, (0, _yuneta_gobj_js.kw_get_str)(gobj, md, "record_id", "", 0));
|
|
75367
75533
|
else {
|
|
75368
|
-
|
|
75534
|
+
record = (0, _yuneta_gobj_js.is_object)(data) ? data : Array.isArray(data) && (0, _yuneta_gobj_js.is_object)(data[0]) ? data[0] : null;
|
|
75369
75535
|
if (record) patch_record(gobj, topic_name, record);
|
|
75370
75536
|
else {
|
|
75371
75537
|
let not_sent = priv.save_queue.length - 1;
|
|
@@ -75373,20 +75539,22 @@ function ac_mt_command_answer(gobj, event, kw, src) {
|
|
|
75373
75539
|
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 });
|
|
75374
75540
|
if (topic_name === T_TOPICS || topic_name === T_COLS) {
|
|
75375
75541
|
let write = priv.save_queue[0];
|
|
75376
|
-
mark_written(gobj, topic_name, write ? write.record : null);
|
|
75542
|
+
mark_written(gobj, topic_name, null, write ? write.record : null);
|
|
75377
75543
|
}
|
|
75378
75544
|
priv.reload_after_write = false;
|
|
75379
75545
|
priv.save_queue = [];
|
|
75380
75546
|
priv.save_return = "";
|
|
75381
75547
|
priv.save_wrote = false;
|
|
75382
75548
|
(0, _yuneta_gobj_js.gobj_publish_event)(gobj, "EV_RECORD_WRITTEN", { treedb_name: (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "treedb_name") });
|
|
75383
|
-
|
|
75549
|
+
let refresh = priv.refresh_after_write;
|
|
75550
|
+
priv.refresh_after_write = false;
|
|
75551
|
+
request_model(gobj, !refresh);
|
|
75384
75552
|
return 0;
|
|
75385
75553
|
}
|
|
75386
75554
|
}
|
|
75387
75555
|
if (topic_name === T_TOPICS || topic_name === T_COLS) {
|
|
75388
75556
|
let write = priv.save_queue[0];
|
|
75389
|
-
mark_written(gobj, topic_name, write ? write.record : null);
|
|
75557
|
+
mark_written(gobj, topic_name, record, write ? write.record : null);
|
|
75390
75558
|
}
|
|
75391
75559
|
priv.save_queue.shift();
|
|
75392
75560
|
return run_next_write(gobj);
|
|
@@ -75443,25 +75611,34 @@ function late_write_done(gobj, command, topic_name, data) {
|
|
|
75443
75611
|
***************************************************************/
|
|
75444
75612
|
function mark_written_record(gobj, topic_name, record) {
|
|
75445
75613
|
let priv = gobj.priv;
|
|
75446
|
-
|
|
75614
|
+
let marked = 0;
|
|
75615
|
+
if (!record) return 0;
|
|
75447
75616
|
if (topic_name === T_TOPICS && typeof record.id === "string" && record.id) {
|
|
75448
75617
|
priv.written[record.id] = true;
|
|
75449
|
-
return;
|
|
75618
|
+
return 1;
|
|
75450
75619
|
}
|
|
75451
|
-
if (topic_name !== T_COLS) return;
|
|
75452
|
-
for (let ref of parse_fkey_ref(record.topics))
|
|
75620
|
+
if (topic_name !== T_COLS) return 0;
|
|
75621
|
+
for (let ref of parse_fkey_ref(record.topics)) {
|
|
75622
|
+
priv.written[ref.id] = true;
|
|
75623
|
+
marked++;
|
|
75624
|
+
}
|
|
75625
|
+
return marked;
|
|
75453
75626
|
}
|
|
75454
75627
|
/***************************************************************
|
|
75455
75628
|
* Remember which topic this write belongs to, which is what
|
|
75456
75629
|
* "its version still has to move" is asked about.
|
|
75630
|
+
*
|
|
75631
|
+
* Asked of the RECORD first: the one the store answered (a new
|
|
75632
|
+
* topic has its id only there), then the one queued (a column
|
|
75633
|
+
* names its topic in its fkey). The screen is the last resort,
|
|
75634
|
+
* and a poor one: an import writes topics the operator is not
|
|
75635
|
+
* on, and from the topics screen there is no topic on it at all.
|
|
75457
75636
|
***************************************************************/
|
|
75458
|
-
function mark_written(gobj, topic_name,
|
|
75637
|
+
function mark_written(gobj, topic_name, answered, queued) {
|
|
75459
75638
|
let priv = gobj.priv;
|
|
75639
|
+
if (mark_written_record(gobj, topic_name, answered) > 0) return;
|
|
75640
|
+
if (mark_written_record(gobj, topic_name, queued) > 0) return;
|
|
75460
75641
|
let topic = current_topic(gobj);
|
|
75461
|
-
if (topic_name === T_TOPICS && record && record.id) {
|
|
75462
|
-
priv.written[record.id] = true;
|
|
75463
|
-
return;
|
|
75464
|
-
}
|
|
75465
75642
|
if (topic) priv.written[topic.id] = true;
|
|
75466
75643
|
}
|
|
75467
75644
|
/***************************************************************
|
|
@@ -75527,6 +75704,21 @@ function ac_refresh$1(gobj, event, kw, src) {
|
|
|
75527
75704
|
return request_model(gobj, false);
|
|
75528
75705
|
}
|
|
75529
75706
|
/***************************************************************
|
|
75707
|
+
* EV_REFRESH while writes are in flight: the view's own Refresh
|
|
75708
|
+
* is busy then, so it is a host's (after a Save, say).
|
|
75709
|
+
*
|
|
75710
|
+
* Run when the writes END (end_writes()), not now. Run now, the
|
|
75711
|
+
* load replaced ST_SAVING and what was still queued was never
|
|
75712
|
+
* sent, with no word: nothing but the end of what is in flight
|
|
75713
|
+
* moves this view out of ST_LOADING or ST_SAVING.
|
|
75714
|
+
***************************************************************/
|
|
75715
|
+
function ac_refresh_after_the_writes(gobj, event, kw, src) {
|
|
75716
|
+
let priv = gobj.priv;
|
|
75717
|
+
(0, _yuneta_gobj_js.log_warning)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: ${event} while writes are in flight: the schemas are read again when the writes end`);
|
|
75718
|
+
priv.refresh_after_write = true;
|
|
75719
|
+
return 0;
|
|
75720
|
+
}
|
|
75721
|
+
/***************************************************************
|
|
75530
75722
|
* What a DIALOG sends while the model is being read again: the
|
|
75531
75723
|
* Save of a form left open when the reload started, a
|
|
75532
75724
|
* confirmation, an import. The loading screen took the rest of
|
|
@@ -75701,7 +75893,13 @@ function ac_save_column(gobj, event, kw, src) {
|
|
|
75701
75893
|
let topic = find_topic(priv.model, priv.treedb_id, kw.topic);
|
|
75702
75894
|
let col = kw.creating ? null : find_col(priv.model, priv.treedb_id, kw.topic, kw.col);
|
|
75703
75895
|
if (refuse_if_readonly(gobj, event)) return -1;
|
|
75704
|
-
if (reload_first(gobj, event
|
|
75896
|
+
if (reload_first(gobj, event, {
|
|
75897
|
+
form: "column",
|
|
75898
|
+
topic: kw.topic,
|
|
75899
|
+
col: kw.col,
|
|
75900
|
+
creating: !!kw.creating,
|
|
75901
|
+
changed: kw.changed || {}
|
|
75902
|
+
})) return -1;
|
|
75705
75903
|
if (built_on_a_replaced_model(gobj, event, kw)) return -1;
|
|
75706
75904
|
if (!topic || !kw.creating && !col) {
|
|
75707
75905
|
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: ${event} names no column: ${kw.topic}.${kw.col}`);
|
|
@@ -75829,7 +76027,13 @@ function ac_save_topic(gobj, event, kw, src) {
|
|
|
75829
76027
|
let treedb = current_treedb(gobj);
|
|
75830
76028
|
let topic = kw.creating ? null : find_topic(priv.model, priv.treedb_id, kw.topic);
|
|
75831
76029
|
if (refuse_if_readonly(gobj, event)) return -1;
|
|
75832
|
-
if (reload_first(gobj, event
|
|
76030
|
+
if (reload_first(gobj, event, {
|
|
76031
|
+
form: "topic",
|
|
76032
|
+
topic: kw.topic,
|
|
76033
|
+
col: "",
|
|
76034
|
+
creating: !!kw.creating,
|
|
76035
|
+
changed: kw.changed || {}
|
|
76036
|
+
})) return -1;
|
|
75833
76037
|
if (built_on_a_replaced_model(gobj, event, kw)) return -1;
|
|
75834
76038
|
if (!treedb || !kw.creating && !topic) {
|
|
75835
76039
|
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: ${event} names no topic: ${kw.topic}`);
|
|
@@ -76292,7 +76496,11 @@ function create_gclass$1(gclass_name) {
|
|
|
76292
76496
|
null
|
|
76293
76497
|
]
|
|
76294
76498
|
])],
|
|
76295
|
-
["ST_SAVING", COMMON.
|
|
76499
|
+
["ST_SAVING", COMMON.filter((a) => a[0] !== "EV_REFRESH").concat([[
|
|
76500
|
+
"EV_REFRESH",
|
|
76501
|
+
ac_refresh_after_the_writes,
|
|
76502
|
+
null
|
|
76503
|
+
]])]
|
|
76296
76504
|
];
|
|
76297
76505
|
const event_types = [
|
|
76298
76506
|
["EV_MT_COMMAND_ANSWER", _yuneta_gobj_js.event_flag_t.EVF_PUBLIC_EVENT],
|