@yuneta/gobj-ui 7.25.15 → 7.25.16
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 +59 -4
- package/dist/gobj-ui.cjs.js +222 -41
- package/dist/gobj-ui.es.js +222 -41
- package/package.json +2 -2
- package/src/c_g6_nodes_tree.js +37 -4
- package/src/c_yui_schema_editor.js +239 -29
- 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 +152 -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_topics_transport.wiring.test.js +1 -1
- package/src/yui_install.js +14 -3
- package/src/yui_install.test.js +23 -0
package/README.md
CHANGED
|
@@ -1809,6 +1809,21 @@ fails:
|
|
|
1809
1809
|
gobj_send_event(engine, "EV_GRAPHS_WRITE_REFUSED", {topic: record.topic}, gobj);
|
|
1810
1810
|
```
|
|
1811
1811
|
|
|
1812
|
+
**A refused write stays OWED until a Save writes it** (since `7.25.16`). In
|
|
1813
|
+
`7.25.15` the Save lit by the refusal went dark again at the next repaint of
|
|
1814
|
+
the history buttons -- they decide the Save from `history.canUndo()`, and they
|
|
1815
|
+
run on every history change, every change of mode and every redraw of the
|
|
1816
|
+
theme -- and a refusal heard in reading was never shown. The engine now keeps
|
|
1817
|
+
the topic as owed: the Save stays lit while one is, in edition and on entering
|
|
1818
|
+
it; the Save that writes the topic again pays it, and a reload of the data
|
|
1819
|
+
forgets it (the view holds what the backend holds).
|
|
1820
|
+
|
|
1821
|
+
```js
|
|
1822
|
+
gobj_send_event(engine, "EV_GRAPHS_WRITE_REFUSED", {topic: "users"}, host); // Save lit
|
|
1823
|
+
// ... a node moved and moved back (nothing to undo): Save still lit
|
|
1824
|
+
gobj_send_event(engine, "EV_SAVE_GRAPH", {}, engine); // writes users; Save dark
|
|
1825
|
+
```
|
|
1826
|
+
|
|
1812
1827
|
**Every saved look has a way back, in the context menu** (since `7.23.134`,
|
|
1813
1828
|
replacing `reset sizes` / `reset topic sizes`). In edition, the node, the port
|
|
1814
1829
|
and the edge menus each offer three resets — this one, its kind (`reset topic
|
|
@@ -2113,7 +2128,7 @@ columns**, each in its declared `order`, with the storage composed underneath
|
|
|
2113
2128
|
the qualified id, the fkey to the parent, the place among the siblings, and the
|
|
2114
2129
|
versions that publish the change.
|
|
2115
2130
|
|
|
2116
|
-
**An edit here is a draft** (7.23.196, with
|
|
2131
|
+
**An edit here is a draft** (7.23.196, with SDK 7.25.0). A write moves
|
|
2117
2132
|
no version and reaches no treedb. The HOST publishes it with `C_TREEDB`'s
|
|
2118
2133
|
`save-schema`, which raises the `topic_version` of each topic that changed
|
|
2119
2134
|
(the one that regenerates `topic_cols.json`) and the `schema_version` (the one
|
|
@@ -2206,6 +2221,7 @@ else.
|
|
|
2206
2221
|
master the tranger, so it refuses every write), `base_route`, `$container`.
|
|
2207
2222
|
- In: `EV_SHOW` (`{subpath}` — the tail it owns is `<treedb>[/<topic>]` or
|
|
2208
2223
|
`<treedb>/diagram`), `EV_HIDE`, `EV_TRANSPORT_STATE`, `EV_REFRESH`,
|
|
2224
|
+
`EV_DRAFTS` (`{drafts: {<treedb>: [<topic>, …]}}`, see above),
|
|
2209
2225
|
`EV_LANGUAGE_CHANGED`, `EV_MT_COMMAND_ANSWER`.
|
|
2210
2226
|
- A **drop** of the transport — `EV_TRANSPORT_STATE {connected: false}`, or a
|
|
2211
2227
|
failed answer that arrives while the transport is out of `ST_SESSION` — ends
|
|
@@ -2230,6 +2246,19 @@ else.
|
|
|
2230
2246
|
gobj_send_event(editor, "EV_SHOW", {subpath: "db"}, host); // waits
|
|
2231
2247
|
// ... the three `nodes` answers land -> ST_TOPICS of `db`
|
|
2232
2248
|
```
|
|
2249
|
+
|
|
2250
|
+
**`EV_REFRESH` waits too** (7.25.16). Heard in `ST_SAVING` -- a host that
|
|
2251
|
+
sends it after a Save while the writes are still in flight -- it is logged
|
|
2252
|
+
and run when the writes END, forgetting the drafts as a Refresh does. It
|
|
2253
|
+
ran at once: the load replaced `ST_SAVING`, and what was still queued (the
|
|
2254
|
+
topic of a topic delete, after its columns) was never sent, with no word.
|
|
2255
|
+
|
|
2256
|
+
```js
|
|
2257
|
+
gobj_send_event(editor, "EV_CONFIRMED", {what: "topic", topic: "users",
|
|
2258
|
+
model_gen: n}, editor); // ST_SAVING, 2 deletes
|
|
2259
|
+
gobj_send_event(editor, "EV_REFRESH", {}, host); // logged, waits
|
|
2260
|
+
// ... both deletes answered -> ST_LOADING -> the model is read again
|
|
2261
|
+
```
|
|
2233
2262
|
- **The loading screen is drawn** (7.25.8): the body is cleared, the drawing
|
|
2234
2263
|
destroyed and every toolbar button disabled, as in `ST_SAVING`, because
|
|
2235
2264
|
`ST_LOADING` declares none of a screen's actions. A **dialog** left open is
|
|
@@ -2315,6 +2344,28 @@ else.
|
|
|
2315
2344
|
// ... the load lands: the same click now opens the form
|
|
2316
2345
|
```
|
|
2317
2346
|
|
|
2347
|
+
**The Save of a form open when the reload is owed keeps what was typed**
|
|
2348
|
+
(7.25.16). It runs the owed reload and says
|
|
2349
|
+
`the schemas shown may be out of date: they are read again, and the form opens again on them with your changes`.
|
|
2350
|
+
The load that lands closes the form and opens it again on the schemas it
|
|
2351
|
+
read, with the fields the operator CHANGED put back on top -- only those,
|
|
2352
|
+
so a field left as it was shows what the store holds now and the next Save
|
|
2353
|
+
does not write the old value over a newer one. A new column or topic comes
|
|
2354
|
+
back whole (nothing of it is in the store). Before, the form was closed and
|
|
2355
|
+
what was typed was lost. It is not opened again when what it edited is not
|
|
2356
|
+
on the schemas read (a column deleted meanwhile, another treedb, another
|
|
2357
|
+
screen): that is said with
|
|
2358
|
+
`the schemas were read again and what the form was editing is not there any more`.
|
|
2359
|
+
A form the operator closed while the load ran stays closed. Both texts are
|
|
2360
|
+
i18n keys the consumer's locales carry.
|
|
2361
|
+
|
|
2362
|
+
```js
|
|
2363
|
+
// reload owed; column form of db.users.id open, header typed "Identifier"
|
|
2364
|
+
// Save -> refused, the model is read again
|
|
2365
|
+
// ... the load lands: the form opens again, header "Identifier", the rest
|
|
2366
|
+
// of the fields as the store holds them now; Save writes them
|
|
2367
|
+
```
|
|
2368
|
+
|
|
2318
2369
|
A write answered with no record reloads the model and
|
|
2319
2370
|
says what it did not send after it
|
|
2320
2371
|
(`the treedb did not describe a write back: the writes after it were not sent`).
|
|
@@ -3280,9 +3331,13 @@ a modal
|
|
|
3280
3331
|
`TOAST*`. Every button of that chrome -- each ✕, a dialog's back arrow, a
|
|
3281
3332
|
confirmation's answers (`CONFIRM_BTN`) -- carries a translatable `title` and
|
|
3282
3333
|
`aria-label` (7.25.10). An answer is named by its own label, so pass i18n
|
|
3283
|
-
KEYS as `yes_label` / `confirm_label` / … (`{yes_label: "install"}`)
|
|
3284
|
-
defaults
|
|
3285
|
-
|
|
3334
|
+
KEYS as `yes_label` / `confirm_label` / … (`{yes_label: "install"}`). The
|
|
3335
|
+
defaults are keys too since 7.25.16 -- `"ok"`, `"yes"`, `"no"`, `"delete"`
|
|
3336
|
+
and `"cancel"` (they were `"OK"`, `"Yes"`, … , which no validated locale can
|
|
3337
|
+
hold) -- so an app that mounts these dialogs defines those five keys, and
|
|
3338
|
+
its `validate-locales` asks for them. `yui_install_ask_once()` asks
|
|
3339
|
+
`"install this app"` (was `"Install this app?"`), answered `"install"` /
|
|
3340
|
+
`"not now"`.
|
|
3286
3341
|
|
|
3287
3342
|
Those names identify the *kind* of block, not the *instance*: every window in
|
|
3288
3343
|
the app is a `C_YUI_WINDOW`, every popup is a `MODAL`. To target **one**
|
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
|
}
|
|
@@ -72334,6 +72370,8 @@ var PRIVATE_DATA$1 = {
|
|
|
72334
72370
|
dropped_round: 0,
|
|
72335
72371
|
dropped_write: 0,
|
|
72336
72372
|
reload_after_write: false,
|
|
72373
|
+
refresh_after_write: false,
|
|
72374
|
+
reopen_form: null,
|
|
72337
72375
|
pending_seg: null,
|
|
72338
72376
|
import_plan: null,
|
|
72339
72377
|
import_pane: null,
|
|
@@ -72539,14 +72577,61 @@ function owes_reload(gobj) {
|
|
|
72539
72577
|
let state = (0, _yuneta_gobj_js.gobj_current_state)(gobj);
|
|
72540
72578
|
return gobj.priv.reload_on_open && transport_in_session(gobj) && state !== "ST_LOADING" && state !== "ST_SAVING";
|
|
72541
72579
|
}
|
|
72542
|
-
function reload_first(gobj, event) {
|
|
72580
|
+
function reload_first(gobj, event, reopen) {
|
|
72581
|
+
let priv = gobj.priv;
|
|
72543
72582
|
if (!owes_reload(gobj)) return false;
|
|
72544
|
-
|
|
72583
|
+
priv.reload_on_open = false;
|
|
72584
|
+
if (reopen && priv.dialog) {
|
|
72585
|
+
priv.reopen_form = Object.assign((0, _yuneta_gobj_js.json_deep_copy)(reopen), {
|
|
72586
|
+
dialog: priv.dialog,
|
|
72587
|
+
treedb_id: priv.treedb_id
|
|
72588
|
+
});
|
|
72589
|
+
(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`);
|
|
72590
|
+
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 });
|
|
72591
|
+
request_model(gobj, true);
|
|
72592
|
+
return true;
|
|
72593
|
+
}
|
|
72545
72594
|
(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
72595
|
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
72596
|
request_model(gobj, true);
|
|
72548
72597
|
return true;
|
|
72549
72598
|
}
|
|
72599
|
+
/***************************************************************
|
|
72600
|
+
* The form reload_first() took down, opened again on the model
|
|
72601
|
+
* the load just made, with the operator's changes on top.
|
|
72602
|
+
*
|
|
72603
|
+
* Only where it can mean the same thing: on the treedb it was
|
|
72604
|
+
* opened on, on the screen whose Save it has, and on a record
|
|
72605
|
+
* that is still there. Otherwise it is not opened, and that is
|
|
72606
|
+
* said -- a form opened on another treedb, or on nothing, would
|
|
72607
|
+
* save somewhere the operator never meant.
|
|
72608
|
+
***************************************************************/
|
|
72609
|
+
function reopen_form(gobj, r) {
|
|
72610
|
+
let priv = gobj.priv;
|
|
72611
|
+
let state = (0, _yuneta_gobj_js.gobj_current_state)(gobj);
|
|
72612
|
+
let treedb = current_treedb(gobj);
|
|
72613
|
+
let topic = null;
|
|
72614
|
+
let col = null;
|
|
72615
|
+
let fits = false;
|
|
72616
|
+
if (treedb && r.treedb_id === priv.treedb_id) {
|
|
72617
|
+
if (r.form === "column" && state === "ST_COLUMNS") {
|
|
72618
|
+
topic = find_topic(priv.model, priv.treedb_id, r.topic);
|
|
72619
|
+
col = topic && !r.creating ? find_col(priv.model, priv.treedb_id, r.topic, r.col) : null;
|
|
72620
|
+
fits = !!topic && (r.creating || !!col);
|
|
72621
|
+
} else if (r.form === "topic" && state === "ST_TOPICS") {
|
|
72622
|
+
topic = r.creating ? null : find_topic(priv.model, priv.treedb_id, r.topic);
|
|
72623
|
+
fits = r.creating || !!topic;
|
|
72624
|
+
}
|
|
72625
|
+
}
|
|
72626
|
+
if (!fits) {
|
|
72627
|
+
(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})`);
|
|
72628
|
+
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 });
|
|
72629
|
+
return -1;
|
|
72630
|
+
}
|
|
72631
|
+
if (r.form === "column") open_column_form(gobj, topic, col, null, r.changed);
|
|
72632
|
+
else open_topic_form(gobj, treedb, topic, r.changed);
|
|
72633
|
+
return 0;
|
|
72634
|
+
}
|
|
72550
72635
|
function reload_after_move(gobj) {
|
|
72551
72636
|
if (!owes_reload(gobj)) return 0;
|
|
72552
72637
|
gobj.priv.reload_on_open = false;
|
|
@@ -72692,7 +72777,7 @@ function build_model(gobj) {
|
|
|
72692
72777
|
* measurement of "changed since" can be measured against.
|
|
72693
72778
|
*
|
|
72694
72779
|
* `written` is forgotten only by an EV_REFRESH (the view's own
|
|
72695
|
-
* Refresh button, or a host that sends one). Since
|
|
72780
|
+
* Refresh button, or a host that sends one). Since 7.23.196 a write moves no
|
|
72696
72781
|
* version, so `written` is the draft chip of what this session
|
|
72697
72782
|
* wrote and no longer half of a version measurement: a reload of
|
|
72698
72783
|
* the reconnect, or of a write that turned out done, forgot the
|
|
@@ -73970,6 +74055,55 @@ function read_form($root) {
|
|
|
73970
74055
|
return out;
|
|
73971
74056
|
}
|
|
73972
74057
|
/***************************************************************
|
|
74058
|
+
* A column form as its Save sends it: the fields and the flags.
|
|
74059
|
+
***************************************************************/
|
|
74060
|
+
function column_form_state($form) {
|
|
74061
|
+
let values = read_form($form);
|
|
74062
|
+
values.flag = read_flags($form);
|
|
74063
|
+
return values;
|
|
74064
|
+
}
|
|
74065
|
+
/***************************************************************
|
|
74066
|
+
* The fields the operator CHANGED: those whose value is not the
|
|
74067
|
+
* one the form was opened with.
|
|
74068
|
+
***************************************************************/
|
|
74069
|
+
function form_changes(initial, values) {
|
|
74070
|
+
let changed = {};
|
|
74071
|
+
for (let name of Object.keys(values)) if (JSON.stringify(values[name]) !== JSON.stringify(initial[name])) changed[name] = values[name];
|
|
74072
|
+
return changed;
|
|
74073
|
+
}
|
|
74074
|
+
/***************************************************************
|
|
74075
|
+
* Put changes back into a form just built (reopen_form()). The
|
|
74076
|
+
* flags are drawn again for the type the changes leave, holding
|
|
74077
|
+
* the flags they name, so none of them is hidden by the type.
|
|
74078
|
+
***************************************************************/
|
|
74079
|
+
function apply_form_changes(gobj, $form, changes) {
|
|
74080
|
+
for (let name of Object.keys(changes)) {
|
|
74081
|
+
if (name === "flag") continue;
|
|
74082
|
+
let $control = $form.querySelector(`[data-name="${name}"]`);
|
|
74083
|
+
if (!$control) {
|
|
74084
|
+
(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`);
|
|
74085
|
+
continue;
|
|
74086
|
+
}
|
|
74087
|
+
if ($control.type === "checkbox") $control.checked = !!changes[name];
|
|
74088
|
+
else $control.value = changes[name];
|
|
74089
|
+
}
|
|
74090
|
+
let $type = $form.querySelector("[data-name=\"type\"]");
|
|
74091
|
+
if ($type && $form.querySelector(".SCHEMA_FLAGS")) {
|
|
74092
|
+
let flags = Array.isArray(changes.flag) ? changes.flag : read_flags($form);
|
|
74093
|
+
redraw_flags(gobj, $form, $type.value, flags);
|
|
74094
|
+
}
|
|
74095
|
+
}
|
|
74096
|
+
/***************************************************************
|
|
74097
|
+
* Draw the flags of a column form again, for `type`, with
|
|
74098
|
+
* `current` checked.
|
|
74099
|
+
***************************************************************/
|
|
74100
|
+
function redraw_flags(gobj, $form, type, current) {
|
|
74101
|
+
let $holder = $form.querySelector(".SCHEMA_FLAGS");
|
|
74102
|
+
let $new = (0, _yuneta_gobj_js.createElement2)(flags_field(gobj, type, current));
|
|
74103
|
+
$holder.parentNode.replaceChild($new, $holder);
|
|
74104
|
+
(0, _yuneta_gobj_js.refresh_language)($new, i18next.t);
|
|
74105
|
+
}
|
|
74106
|
+
/***************************************************************
|
|
73973
74107
|
* The flags of a column, as checkboxes that say what they do.
|
|
73974
74108
|
*
|
|
73975
74109
|
* Grouped the way they act, greyed when they are meaningless on
|
|
@@ -74043,7 +74177,7 @@ function read_flags($root) {
|
|
|
74043
74177
|
* Offering a field that silently does something else is worse
|
|
74044
74178
|
* than not offering it.
|
|
74045
74179
|
***************************************************************/
|
|
74046
|
-
function open_column_form(gobj, topic, col, prefill) {
|
|
74180
|
+
function open_column_form(gobj, topic, col, prefill, changes) {
|
|
74047
74181
|
let priv = gobj.priv;
|
|
74048
74182
|
let record = prefill || col && col.record || {};
|
|
74049
74183
|
let creating = !col;
|
|
@@ -74147,11 +74281,7 @@ function open_column_form(gobj, topic, col, prefill) {
|
|
|
74147
74281
|
]);
|
|
74148
74282
|
let $type = $form.querySelector("[data-name=\"type\"]");
|
|
74149
74283
|
$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);
|
|
74284
|
+
redraw_flags(gobj, $form, $type.value, read_flags($form));
|
|
74155
74285
|
});
|
|
74156
74286
|
$form.addEventListener("change", (evt) => {
|
|
74157
74287
|
let $box = evt.target.closest(".SCHEMA_FLAG_BOX");
|
|
@@ -74163,15 +74293,17 @@ function open_column_form(gobj, topic, col, prefill) {
|
|
|
74163
74293
|
evt.stopPropagation();
|
|
74164
74294
|
close_dialog(gobj);
|
|
74165
74295
|
});
|
|
74296
|
+
let initial = column_form_state($form);
|
|
74297
|
+
if (changes) apply_form_changes(gobj, $form, changes);
|
|
74166
74298
|
$form.querySelector(".SCHEMA_COL_FORM_SAVE").addEventListener("click", (evt) => {
|
|
74167
74299
|
evt.stopPropagation();
|
|
74168
|
-
let values =
|
|
74169
|
-
values.flag = read_flags($form);
|
|
74300
|
+
let values = column_form_state($form);
|
|
74170
74301
|
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_SAVE_COLUMN", {
|
|
74171
74302
|
topic: topic.name,
|
|
74172
74303
|
col: creating ? "" : col.name,
|
|
74173
74304
|
creating,
|
|
74174
74305
|
values,
|
|
74306
|
+
changed: creating ? values : form_changes(initial, values),
|
|
74175
74307
|
model_gen
|
|
74176
74308
|
}, gobj);
|
|
74177
74309
|
});
|
|
@@ -74191,7 +74323,7 @@ function stringify_field(value) {
|
|
|
74191
74323
|
* actually has: a pkey naming no column is a topic that does
|
|
74192
74324
|
* not open, and it is the first thing the validator looks for.
|
|
74193
74325
|
***************************************************************/
|
|
74194
|
-
function open_topic_form(gobj, treedb, topic) {
|
|
74326
|
+
function open_topic_form(gobj, treedb, topic, changes) {
|
|
74195
74327
|
let record = topic && topic.record || {};
|
|
74196
74328
|
let creating = !topic;
|
|
74197
74329
|
let col_names = topic ? topic.cols.map((c) => c.name) : [];
|
|
@@ -74286,12 +74418,16 @@ function open_topic_form(gobj, treedb, topic) {
|
|
|
74286
74418
|
evt.stopPropagation();
|
|
74287
74419
|
close_dialog(gobj);
|
|
74288
74420
|
});
|
|
74421
|
+
let initial = read_form($form);
|
|
74422
|
+
if (changes) apply_form_changes(gobj, $form, changes);
|
|
74289
74423
|
$form.querySelector(".SCHEMA_TOPIC_FORM_SAVE").addEventListener("click", (evt) => {
|
|
74290
74424
|
evt.stopPropagation();
|
|
74425
|
+
let values = read_form($form);
|
|
74291
74426
|
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_SAVE_TOPIC", {
|
|
74292
74427
|
topic: creating ? "" : topic.name,
|
|
74293
74428
|
creating,
|
|
74294
|
-
values
|
|
74429
|
+
values,
|
|
74430
|
+
changed: creating ? values : form_changes(initial, values),
|
|
74295
74431
|
model_gen
|
|
74296
74432
|
}, gobj);
|
|
74297
74433
|
});
|
|
@@ -75061,20 +75197,28 @@ function transport_dropped(gobj) {
|
|
|
75061
75197
|
function end_load(gobj) {
|
|
75062
75198
|
let priv = gobj.priv;
|
|
75063
75199
|
let seg = priv.pending_seg;
|
|
75200
|
+
let reopen = priv.reopen_form;
|
|
75064
75201
|
priv.pending_seg = null;
|
|
75202
|
+
priv.reopen_form = null;
|
|
75065
75203
|
if (priv.dialog && priv.dialog_gen !== priv.model_gen) {
|
|
75066
|
-
|
|
75204
|
+
if (!reopen || reopen.dialog !== priv.dialog) {
|
|
75205
|
+
reopen = null;
|
|
75206
|
+
(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`);
|
|
75207
|
+
yui_shell_show_error(yui_shell_of(gobj), "the schemas were read again: open the dialog again", { t: i18next.t });
|
|
75208
|
+
}
|
|
75067
75209
|
close_dialog(gobj);
|
|
75068
|
-
|
|
75069
|
-
|
|
75210
|
+
} else reopen = null;
|
|
75211
|
+
let ret = 0;
|
|
75070
75212
|
if (priv.model) {
|
|
75071
|
-
if (seg !== null)
|
|
75072
|
-
|
|
75213
|
+
if (seg !== null) ret = apply_seg(gobj, seg);
|
|
75214
|
+
else ret = go(gobj, priv.treedb_id, priv.topic_name, priv.diagram, false);
|
|
75215
|
+
} else {
|
|
75216
|
+
if (seg !== null) adopt_seg(gobj, seg);
|
|
75217
|
+
(0, _yuneta_gobj_js.gobj_change_state)(gobj, "ST_IDLE");
|
|
75218
|
+
render(gobj);
|
|
75073
75219
|
}
|
|
75074
|
-
if (
|
|
75075
|
-
|
|
75076
|
-
render(gobj);
|
|
75077
|
-
return 0;
|
|
75220
|
+
if (reopen) reopen_form(gobj, reopen);
|
|
75221
|
+
return ret;
|
|
75078
75222
|
}
|
|
75079
75223
|
/***************************************************************
|
|
75080
75224
|
* The queue is done, or gave up. Either way the model is what
|
|
@@ -75099,7 +75243,11 @@ function end_writes(gobj, error) {
|
|
|
75099
75243
|
render(gobj);
|
|
75100
75244
|
publish_check(gobj);
|
|
75101
75245
|
}
|
|
75102
|
-
|
|
75246
|
+
if (priv.refresh_after_write) {
|
|
75247
|
+
priv.refresh_after_write = false;
|
|
75248
|
+
priv.reload_after_write = false;
|
|
75249
|
+
request_model(gobj, false);
|
|
75250
|
+
} else reload_if_owed(gobj);
|
|
75103
75251
|
return error ? -1 : 0;
|
|
75104
75252
|
}
|
|
75105
75253
|
/***************************************************************
|
|
@@ -75380,7 +75528,9 @@ function ac_mt_command_answer(gobj, event, kw, src) {
|
|
|
75380
75528
|
priv.save_return = "";
|
|
75381
75529
|
priv.save_wrote = false;
|
|
75382
75530
|
(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
|
-
|
|
75531
|
+
let refresh = priv.refresh_after_write;
|
|
75532
|
+
priv.refresh_after_write = false;
|
|
75533
|
+
request_model(gobj, !refresh);
|
|
75384
75534
|
return 0;
|
|
75385
75535
|
}
|
|
75386
75536
|
}
|
|
@@ -75527,6 +75677,21 @@ function ac_refresh$1(gobj, event, kw, src) {
|
|
|
75527
75677
|
return request_model(gobj, false);
|
|
75528
75678
|
}
|
|
75529
75679
|
/***************************************************************
|
|
75680
|
+
* EV_REFRESH while writes are in flight: the view's own Refresh
|
|
75681
|
+
* is busy then, so it is a host's (after a Save, say).
|
|
75682
|
+
*
|
|
75683
|
+
* Run when the writes END (end_writes()), not now. Run now, the
|
|
75684
|
+
* load replaced ST_SAVING and what was still queued was never
|
|
75685
|
+
* sent, with no word: nothing but the end of what is in flight
|
|
75686
|
+
* moves this view out of ST_LOADING or ST_SAVING.
|
|
75687
|
+
***************************************************************/
|
|
75688
|
+
function ac_refresh_after_the_writes(gobj, event, kw, src) {
|
|
75689
|
+
let priv = gobj.priv;
|
|
75690
|
+
(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`);
|
|
75691
|
+
priv.refresh_after_write = true;
|
|
75692
|
+
return 0;
|
|
75693
|
+
}
|
|
75694
|
+
/***************************************************************
|
|
75530
75695
|
* What a DIALOG sends while the model is being read again: the
|
|
75531
75696
|
* Save of a form left open when the reload started, a
|
|
75532
75697
|
* confirmation, an import. The loading screen took the rest of
|
|
@@ -75701,7 +75866,13 @@ function ac_save_column(gobj, event, kw, src) {
|
|
|
75701
75866
|
let topic = find_topic(priv.model, priv.treedb_id, kw.topic);
|
|
75702
75867
|
let col = kw.creating ? null : find_col(priv.model, priv.treedb_id, kw.topic, kw.col);
|
|
75703
75868
|
if (refuse_if_readonly(gobj, event)) return -1;
|
|
75704
|
-
if (reload_first(gobj, event
|
|
75869
|
+
if (reload_first(gobj, event, {
|
|
75870
|
+
form: "column",
|
|
75871
|
+
topic: kw.topic,
|
|
75872
|
+
col: kw.col,
|
|
75873
|
+
creating: !!kw.creating,
|
|
75874
|
+
changed: kw.changed || {}
|
|
75875
|
+
})) return -1;
|
|
75705
75876
|
if (built_on_a_replaced_model(gobj, event, kw)) return -1;
|
|
75706
75877
|
if (!topic || !kw.creating && !col) {
|
|
75707
75878
|
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: ${event} names no column: ${kw.topic}.${kw.col}`);
|
|
@@ -75829,7 +76000,13 @@ function ac_save_topic(gobj, event, kw, src) {
|
|
|
75829
76000
|
let treedb = current_treedb(gobj);
|
|
75830
76001
|
let topic = kw.creating ? null : find_topic(priv.model, priv.treedb_id, kw.topic);
|
|
75831
76002
|
if (refuse_if_readonly(gobj, event)) return -1;
|
|
75832
|
-
if (reload_first(gobj, event
|
|
76003
|
+
if (reload_first(gobj, event, {
|
|
76004
|
+
form: "topic",
|
|
76005
|
+
topic: kw.topic,
|
|
76006
|
+
col: "",
|
|
76007
|
+
creating: !!kw.creating,
|
|
76008
|
+
changed: kw.changed || {}
|
|
76009
|
+
})) return -1;
|
|
75833
76010
|
if (built_on_a_replaced_model(gobj, event, kw)) return -1;
|
|
75834
76011
|
if (!treedb || !kw.creating && !topic) {
|
|
75835
76012
|
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: ${event} names no topic: ${kw.topic}`);
|
|
@@ -76292,7 +76469,11 @@ function create_gclass$1(gclass_name) {
|
|
|
76292
76469
|
null
|
|
76293
76470
|
]
|
|
76294
76471
|
])],
|
|
76295
|
-
["ST_SAVING", COMMON.
|
|
76472
|
+
["ST_SAVING", COMMON.filter((a) => a[0] !== "EV_REFRESH").concat([[
|
|
76473
|
+
"EV_REFRESH",
|
|
76474
|
+
ac_refresh_after_the_writes,
|
|
76475
|
+
null
|
|
76476
|
+
]])]
|
|
76296
76477
|
];
|
|
76297
76478
|
const event_types = [
|
|
76298
76479
|
["EV_MT_COMMAND_ANSWER", _yuneta_gobj_js.event_flag_t.EVF_PUBLIC_EVENT],
|