@yuneta/gobj-ui 7.25.11 → 7.25.12
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 +18 -4
- package/dist/gobj-ui.cjs.js +67 -15
- package/dist/gobj-ui.es.js +67 -15
- package/package.json +1 -1
- package/src/c_yui_schema_editor.js +83 -19
- package/src/schema_editor_reload.wiring.test.js +187 -1
package/README.md
CHANGED
|
@@ -2134,6 +2134,11 @@ And what the toolbar offers, each answering a question the storage could not:
|
|
|
2134
2134
|
answer. Escaping crosses two layers and the second is not JSON's:
|
|
2135
2135
|
`helper_quote2doublequote()` rewrites *every* single quote before the parse,
|
|
2136
2136
|
so a quote inside a value can only survive as `\u0027`.
|
|
2137
|
+
Its C / JSON switch is two named buttons, and a click on one is an event,
|
|
2138
|
+
`EV_EXPORT_VIEW` (`{pane: "c" | "json"}`), answered in every state: the
|
|
2139
|
+
texts were composed when the dialog opened, and the dialog outlives the
|
|
2140
|
+
screen and the loads under it (7.25.12; before, the switch ran in the DOM
|
|
2141
|
+
handler and the `machine` trace did not show it).
|
|
2137
2142
|
- **import** — the writes that make the stored schema equal a pasted one, shown
|
|
2138
2143
|
as a **plan** before it runs. Import is the one operation here that can delete
|
|
2139
2144
|
a column, so what is confirmed is what runs.
|
|
@@ -2201,8 +2206,10 @@ else.
|
|
|
2201
2206
|
column form sends every field it shows, so its Save after a reload wrote
|
|
2202
2207
|
the OLD record over the newer one -- 7.25.8 told the operator to "try
|
|
2203
2208
|
again", which did exactly that. The import plan is forgotten when a load
|
|
2204
|
-
|
|
2205
|
-
it
|
|
2209
|
+
LANDS, with the model it was computed on (7.25.12; from 7.25.9 to 7.25.11
|
|
2210
|
+
it went when the load LEFT, so a load that then failed left the dialog up
|
|
2211
|
+
with no plan and Import disabled). A load that fails or never leaves keeps
|
|
2212
|
+
it, and Import stays enabled. A Yes that finds it gone is said (`the import plan is gone: preview it again`). A load that
|
|
2206
2213
|
failed or never left replaced nothing, and the dialog stays with what was
|
|
2207
2214
|
typed. A confirmation is a shell modal and outlives a load: its Yes in
|
|
2208
2215
|
`ST_EMPTY` or `ST_IDLE` is refused with the same words, not *"NOT
|
|
@@ -2225,7 +2232,12 @@ else.
|
|
|
2225
2232
|
orphans -- is refused with
|
|
2226
2233
|
`the schemas shown may be out of date: they are read again, try again when they are in`
|
|
2227
2234
|
and the model is read again (keeping the draft chips); a move goes where it
|
|
2228
|
-
was going and reads there
|
|
2235
|
+
was going and reads there -- the editor's own moves, and since 7.25.12 the
|
|
2236
|
+
host's too (`EV_SHOW` from a url or the browser's Back). **Any load that
|
|
2237
|
+
lands pays it** (7.25.12): the operator's Refresh, a late write's reload,
|
|
2238
|
+
the reconnect. Before, only the reload the editor asked for itself cleared
|
|
2239
|
+
it, so after a Refresh that landed the next edit was refused and read the
|
|
2240
|
+
store again. Not at once and not on a timer: a load refused
|
|
2229
2241
|
on a deadline asked again at once is refused the same way, and one asked
|
|
2230
2242
|
on a clock is polling. A Refresh asked while a load is in flight keeps the
|
|
2231
2243
|
records of the model shown (7.25.10), not the half the first load got.
|
|
@@ -2235,7 +2247,9 @@ else.
|
|
|
2235
2247
|
// the load failed in session: model kept, reload owed
|
|
2236
2248
|
gobj_send_event(editor, "EV_EDIT_COLUMN", {col: "id"}, host); // refused, said; ST_LOADING
|
|
2237
2249
|
// ... the load lands: the same click now opens the form
|
|
2238
|
-
```
|
|
2250
|
+
```
|
|
2251
|
+
|
|
2252
|
+
A write answered with no record reloads the model and
|
|
2239
2253
|
says what it did not send after it
|
|
2240
2254
|
(`the treedb did not describe a write back: the writes after it were not sent`).
|
|
2241
2255
|
- The toolbar offers Diagram, Check, Export, Import, New topic and New column
|
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -72220,7 +72220,8 @@ var PRIVATE_DATA$1 = {
|
|
|
72220
72220
|
pending_seg: null,
|
|
72221
72221
|
import_plan: null,
|
|
72222
72222
|
import_pane: null,
|
|
72223
|
-
import_run: null
|
|
72223
|
+
import_run: null,
|
|
72224
|
+
export_view: null
|
|
72224
72225
|
};
|
|
72225
72226
|
var __gclass__$1 = null;
|
|
72226
72227
|
/******************************
|
|
@@ -72405,7 +72406,12 @@ function built_on_a_replaced_model(gobj, event, kw) {
|
|
|
72405
72406
|
* export) -- is refused and said: it would be computed on what
|
|
72406
72407
|
* the store may no longer hold, and the load that lands closes a
|
|
72407
72408
|
* dialog built on the old model anyway (end_load()). A move is
|
|
72408
|
-
* not refused (reload_after_move()): it goes, and reads there
|
|
72409
|
+
* not refused (reload_after_move()): it goes, and reads there --
|
|
72410
|
+
* the editor's own moves and the host's alike (ac_show(): a url,
|
|
72411
|
+
* the browser's Back).
|
|
72412
|
+
*
|
|
72413
|
+
* Paid by ANY load that lands, whoever asked it
|
|
72414
|
+
* (ac_mt_command_answer()): the store has just been read whole.
|
|
72409
72415
|
*
|
|
72410
72416
|
* Not on a timer, and not at once: a load refused on a deadline
|
|
72411
72417
|
* asked again at once is refused the same way, and one asked on a
|
|
@@ -72447,9 +72453,10 @@ function reload_after_move(gobj) {
|
|
|
72447
72453
|
* left open is answered in ST_LOADING instead (ac_wait_for_the_load),
|
|
72448
72454
|
* and a load that LANDS closes it (end_load()): it was built on the
|
|
72449
72455
|
* model the load replaced, and its Save sends every field it shows.
|
|
72450
|
-
* An import plan is forgotten
|
|
72451
|
-
*
|
|
72452
|
-
*
|
|
72456
|
+
* An import plan is forgotten for the same reason, and at the same
|
|
72457
|
+
* moment: when the load LANDS and the model it was computed on goes
|
|
72458
|
+
* (ac_mt_command_answer()). A load that cannot leave, or that fails,
|
|
72459
|
+
* replaces nothing, and the plan stays with the dialog showing it.
|
|
72453
72460
|
*
|
|
72454
72461
|
* `keep_written`: a load nobody ASKED for -- the reconnect, a write
|
|
72455
72462
|
* that turned out done, the reload a refused load owed -- keeps what
|
|
@@ -72503,7 +72510,6 @@ function request_model(gobj, keep_written) {
|
|
|
72503
72510
|
end_load(gobj);
|
|
72504
72511
|
return -1;
|
|
72505
72512
|
}
|
|
72506
|
-
forget_import_plan(gobj);
|
|
72507
72513
|
priv.pending = left;
|
|
72508
72514
|
return 0;
|
|
72509
72515
|
}
|
|
@@ -73663,6 +73669,7 @@ function close_dialog(gobj) {
|
|
|
73663
73669
|
if (!priv.dialog) return;
|
|
73664
73670
|
let dialog = priv.dialog;
|
|
73665
73671
|
priv.dialog = null;
|
|
73672
|
+
priv.export_view = null;
|
|
73666
73673
|
try {
|
|
73667
73674
|
dialog.close();
|
|
73668
73675
|
} catch (e) {
|
|
@@ -73681,6 +73688,7 @@ function open_dialog(gobj, $content, title, logical, title_prefix) {
|
|
|
73681
73688
|
t: i18next.t,
|
|
73682
73689
|
on_close: () => {
|
|
73683
73690
|
priv.dialog = null;
|
|
73691
|
+
priv.export_view = null;
|
|
73684
73692
|
}
|
|
73685
73693
|
});
|
|
73686
73694
|
(0, _yuneta_gobj_js.refresh_language)($content, i18next.t);
|
|
@@ -74409,17 +74417,43 @@ function open_export(gobj, treedb) {
|
|
|
74409
74417
|
let $text = $content.querySelector(".SCHEMA_EXPORT_TEXT");
|
|
74410
74418
|
for (let $tab of $content.querySelectorAll(".SCHEMA_EXPORT_TAB")) $tab.addEventListener("click", (evt) => {
|
|
74411
74419
|
evt.stopPropagation();
|
|
74412
|
-
|
|
74413
|
-
$other.classList.toggle("selected_state", $other === $tab);
|
|
74414
|
-
$other.setAttribute("aria-pressed", $other === $tab ? "true" : "false");
|
|
74415
|
-
}
|
|
74416
|
-
$text.value = $tab.dataset.pane === "c" ? c_text : json_text;
|
|
74420
|
+
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_EXPORT_VIEW", { pane: $tab.dataset.pane }, gobj);
|
|
74417
74421
|
});
|
|
74418
74422
|
$content.querySelector(".SCHEMA_EXPORT_COPY").addEventListener("click", (evt) => {
|
|
74419
74423
|
evt.stopPropagation();
|
|
74420
74424
|
copy_text(gobj, $text);
|
|
74421
74425
|
});
|
|
74422
74426
|
open_dialog(gobj, $content, "export", "SCHEMA_EXPORT_DIALOG", treedb.id);
|
|
74427
|
+
priv.export_view = {
|
|
74428
|
+
$content,
|
|
74429
|
+
texts: {
|
|
74430
|
+
c: c_text,
|
|
74431
|
+
json: json_text
|
|
74432
|
+
}
|
|
74433
|
+
};
|
|
74434
|
+
}
|
|
74435
|
+
/***************************************************************
|
|
74436
|
+
* Show one of the export's two texts, and say which one is shown
|
|
74437
|
+
* (`selected_state` + aria-pressed). Reached only through
|
|
74438
|
+
* EV_EXPORT_VIEW: a click is an action like any other.
|
|
74439
|
+
***************************************************************/
|
|
74440
|
+
function show_export_view(gobj, pane) {
|
|
74441
|
+
let view = gobj.priv.export_view;
|
|
74442
|
+
if (!view) {
|
|
74443
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: export view '${pane}' asked with no export open`);
|
|
74444
|
+
return -1;
|
|
74445
|
+
}
|
|
74446
|
+
if (!Object.prototype.hasOwnProperty.call(view.texts, pane)) {
|
|
74447
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: the export has no view '${pane}'`);
|
|
74448
|
+
return -1;
|
|
74449
|
+
}
|
|
74450
|
+
for (let $tab of view.$content.querySelectorAll(".SCHEMA_EXPORT_TAB")) {
|
|
74451
|
+
let shown = $tab.dataset.pane === pane;
|
|
74452
|
+
$tab.classList.toggle("selected_state", shown);
|
|
74453
|
+
$tab.setAttribute("aria-pressed", shown ? "true" : "false");
|
|
74454
|
+
}
|
|
74455
|
+
view.$content.querySelector(".SCHEMA_EXPORT_TEXT").value = view.texts[pane];
|
|
74456
|
+
return 0;
|
|
74423
74457
|
}
|
|
74424
74458
|
/***************************************************************
|
|
74425
74459
|
* Copy through the clipboard when the page is allowed one, and
|
|
@@ -74574,9 +74608,9 @@ function open_import(gobj, treedb) {
|
|
|
74574
74608
|
}
|
|
74575
74609
|
/***************************************************************
|
|
74576
74610
|
* The plan is a list of writes computed against the model shown:
|
|
74577
|
-
* a load replaces the model, so the plan goes with it
|
|
74578
|
-
*
|
|
74579
|
-
*
|
|
74611
|
+
* a load that LANDS replaces the model, so the plan goes with it
|
|
74612
|
+
* (and end_load() closes the dialog built on that model). A load
|
|
74613
|
+
* that fails or never leaves keeps the model, and the plan.
|
|
74580
74614
|
***************************************************************/
|
|
74581
74615
|
function forget_import_plan(gobj) {
|
|
74582
74616
|
let priv = gobj.priv;
|
|
@@ -75143,6 +75177,8 @@ function ac_mt_command_answer(gobj, event, kw, src) {
|
|
|
75143
75177
|
priv.order_undo = {};
|
|
75144
75178
|
priv.records_before = null;
|
|
75145
75179
|
priv.model_gen++;
|
|
75180
|
+
priv.reload_on_open = false;
|
|
75181
|
+
forget_import_plan(gobj);
|
|
75146
75182
|
build_model(gobj);
|
|
75147
75183
|
start_measuring(gobj);
|
|
75148
75184
|
return end_load(gobj);
|
|
@@ -75273,7 +75309,8 @@ function ac_show(gobj, event, kw, src) {
|
|
|
75273
75309
|
priv.pending_seg = seg;
|
|
75274
75310
|
return 0;
|
|
75275
75311
|
}
|
|
75276
|
-
|
|
75312
|
+
apply_seg(gobj, seg);
|
|
75313
|
+
return reload_after_move(gobj);
|
|
75277
75314
|
}
|
|
75278
75315
|
/***************************************************************
|
|
75279
75316
|
* Hidden by the host: drop the overlays. A dialog outlives the
|
|
@@ -75712,6 +75749,15 @@ function ac_export(gobj, event, kw, src) {
|
|
|
75712
75749
|
open_export(gobj, treedb);
|
|
75713
75750
|
return 0;
|
|
75714
75751
|
}
|
|
75752
|
+
/***************************************************************
|
|
75753
|
+
* The export dialog's C / JSON switch. Its texts were composed
|
|
75754
|
+
* when it opened, so it reads nothing of the model and is
|
|
75755
|
+
* answered in every state: the dialog stays up through a load
|
|
75756
|
+
* that fails and through a move sent by the host.
|
|
75757
|
+
***************************************************************/
|
|
75758
|
+
function ac_export_view(gobj, event, kw, src) {
|
|
75759
|
+
return show_export_view(gobj, kw && kw.pane);
|
|
75760
|
+
}
|
|
75715
75761
|
function ac_import(gobj, event, kw, src) {
|
|
75716
75762
|
let treedb = current_treedb(gobj);
|
|
75717
75763
|
if (refuse_if_readonly(gobj, event)) return -1;
|
|
@@ -75895,6 +75941,11 @@ function create_gclass$1(gclass_name) {
|
|
|
75895
75941
|
"EV_DRAFTS",
|
|
75896
75942
|
ac_drafts,
|
|
75897
75943
|
null
|
|
75944
|
+
],
|
|
75945
|
+
[
|
|
75946
|
+
"EV_EXPORT_VIEW",
|
|
75947
|
+
ac_export_view,
|
|
75948
|
+
null
|
|
75898
75949
|
]
|
|
75899
75950
|
];
|
|
75900
75951
|
const TREEDB_WIDE = [
|
|
@@ -76102,6 +76153,7 @@ function create_gclass$1(gclass_name) {
|
|
|
76102
76153
|
["EV_UNDO_ORDER", 0],
|
|
76103
76154
|
["EV_VALIDATE", 0],
|
|
76104
76155
|
["EV_EXPORT", 0],
|
|
76156
|
+
["EV_EXPORT_VIEW", 0],
|
|
76105
76157
|
["EV_IMPORT", 0],
|
|
76106
76158
|
["EV_PREVIEW_IMPORT", 0],
|
|
76107
76159
|
["EV_APPLY_IMPORT", 0],
|
package/dist/gobj-ui.es.js
CHANGED
|
@@ -72215,7 +72215,8 @@ var PRIVATE_DATA$1 = {
|
|
|
72215
72215
|
pending_seg: null,
|
|
72216
72216
|
import_plan: null,
|
|
72217
72217
|
import_pane: null,
|
|
72218
|
-
import_run: null
|
|
72218
|
+
import_run: null,
|
|
72219
|
+
export_view: null
|
|
72219
72220
|
};
|
|
72220
72221
|
var __gclass__$1 = null;
|
|
72221
72222
|
/******************************
|
|
@@ -72400,7 +72401,12 @@ function built_on_a_replaced_model(gobj, event, kw) {
|
|
|
72400
72401
|
* export) -- is refused and said: it would be computed on what
|
|
72401
72402
|
* the store may no longer hold, and the load that lands closes a
|
|
72402
72403
|
* dialog built on the old model anyway (end_load()). A move is
|
|
72403
|
-
* not refused (reload_after_move()): it goes, and reads there
|
|
72404
|
+
* not refused (reload_after_move()): it goes, and reads there --
|
|
72405
|
+
* the editor's own moves and the host's alike (ac_show(): a url,
|
|
72406
|
+
* the browser's Back).
|
|
72407
|
+
*
|
|
72408
|
+
* Paid by ANY load that lands, whoever asked it
|
|
72409
|
+
* (ac_mt_command_answer()): the store has just been read whole.
|
|
72404
72410
|
*
|
|
72405
72411
|
* Not on a timer, and not at once: a load refused on a deadline
|
|
72406
72412
|
* asked again at once is refused the same way, and one asked on a
|
|
@@ -72442,9 +72448,10 @@ function reload_after_move(gobj) {
|
|
|
72442
72448
|
* left open is answered in ST_LOADING instead (ac_wait_for_the_load),
|
|
72443
72449
|
* and a load that LANDS closes it (end_load()): it was built on the
|
|
72444
72450
|
* model the load replaced, and its Save sends every field it shows.
|
|
72445
|
-
* An import plan is forgotten
|
|
72446
|
-
*
|
|
72447
|
-
*
|
|
72451
|
+
* An import plan is forgotten for the same reason, and at the same
|
|
72452
|
+
* moment: when the load LANDS and the model it was computed on goes
|
|
72453
|
+
* (ac_mt_command_answer()). A load that cannot leave, or that fails,
|
|
72454
|
+
* replaces nothing, and the plan stays with the dialog showing it.
|
|
72448
72455
|
*
|
|
72449
72456
|
* `keep_written`: a load nobody ASKED for -- the reconnect, a write
|
|
72450
72457
|
* that turned out done, the reload a refused load owed -- keeps what
|
|
@@ -72498,7 +72505,6 @@ function request_model(gobj, keep_written) {
|
|
|
72498
72505
|
end_load(gobj);
|
|
72499
72506
|
return -1;
|
|
72500
72507
|
}
|
|
72501
|
-
forget_import_plan(gobj);
|
|
72502
72508
|
priv.pending = left;
|
|
72503
72509
|
return 0;
|
|
72504
72510
|
}
|
|
@@ -73658,6 +73664,7 @@ function close_dialog(gobj) {
|
|
|
73658
73664
|
if (!priv.dialog) return;
|
|
73659
73665
|
let dialog = priv.dialog;
|
|
73660
73666
|
priv.dialog = null;
|
|
73667
|
+
priv.export_view = null;
|
|
73661
73668
|
try {
|
|
73662
73669
|
dialog.close();
|
|
73663
73670
|
} catch (e) {
|
|
@@ -73676,6 +73683,7 @@ function open_dialog(gobj, $content, title, logical, title_prefix) {
|
|
|
73676
73683
|
t,
|
|
73677
73684
|
on_close: () => {
|
|
73678
73685
|
priv.dialog = null;
|
|
73686
|
+
priv.export_view = null;
|
|
73679
73687
|
}
|
|
73680
73688
|
});
|
|
73681
73689
|
refresh_language($content, t);
|
|
@@ -74404,17 +74412,43 @@ function open_export(gobj, treedb) {
|
|
|
74404
74412
|
let $text = $content.querySelector(".SCHEMA_EXPORT_TEXT");
|
|
74405
74413
|
for (let $tab of $content.querySelectorAll(".SCHEMA_EXPORT_TAB")) $tab.addEventListener("click", (evt) => {
|
|
74406
74414
|
evt.stopPropagation();
|
|
74407
|
-
|
|
74408
|
-
$other.classList.toggle("selected_state", $other === $tab);
|
|
74409
|
-
$other.setAttribute("aria-pressed", $other === $tab ? "true" : "false");
|
|
74410
|
-
}
|
|
74411
|
-
$text.value = $tab.dataset.pane === "c" ? c_text : json_text;
|
|
74415
|
+
gobj_send_event(gobj, "EV_EXPORT_VIEW", { pane: $tab.dataset.pane }, gobj);
|
|
74412
74416
|
});
|
|
74413
74417
|
$content.querySelector(".SCHEMA_EXPORT_COPY").addEventListener("click", (evt) => {
|
|
74414
74418
|
evt.stopPropagation();
|
|
74415
74419
|
copy_text(gobj, $text);
|
|
74416
74420
|
});
|
|
74417
74421
|
open_dialog(gobj, $content, "export", "SCHEMA_EXPORT_DIALOG", treedb.id);
|
|
74422
|
+
priv.export_view = {
|
|
74423
|
+
$content,
|
|
74424
|
+
texts: {
|
|
74425
|
+
c: c_text,
|
|
74426
|
+
json: json_text
|
|
74427
|
+
}
|
|
74428
|
+
};
|
|
74429
|
+
}
|
|
74430
|
+
/***************************************************************
|
|
74431
|
+
* Show one of the export's two texts, and say which one is shown
|
|
74432
|
+
* (`selected_state` + aria-pressed). Reached only through
|
|
74433
|
+
* EV_EXPORT_VIEW: a click is an action like any other.
|
|
74434
|
+
***************************************************************/
|
|
74435
|
+
function show_export_view(gobj, pane) {
|
|
74436
|
+
let view = gobj.priv.export_view;
|
|
74437
|
+
if (!view) {
|
|
74438
|
+
log_error(`${gobj_short_name(gobj)}: export view '${pane}' asked with no export open`);
|
|
74439
|
+
return -1;
|
|
74440
|
+
}
|
|
74441
|
+
if (!Object.prototype.hasOwnProperty.call(view.texts, pane)) {
|
|
74442
|
+
log_error(`${gobj_short_name(gobj)}: the export has no view '${pane}'`);
|
|
74443
|
+
return -1;
|
|
74444
|
+
}
|
|
74445
|
+
for (let $tab of view.$content.querySelectorAll(".SCHEMA_EXPORT_TAB")) {
|
|
74446
|
+
let shown = $tab.dataset.pane === pane;
|
|
74447
|
+
$tab.classList.toggle("selected_state", shown);
|
|
74448
|
+
$tab.setAttribute("aria-pressed", shown ? "true" : "false");
|
|
74449
|
+
}
|
|
74450
|
+
view.$content.querySelector(".SCHEMA_EXPORT_TEXT").value = view.texts[pane];
|
|
74451
|
+
return 0;
|
|
74418
74452
|
}
|
|
74419
74453
|
/***************************************************************
|
|
74420
74454
|
* Copy through the clipboard when the page is allowed one, and
|
|
@@ -74569,9 +74603,9 @@ function open_import(gobj, treedb) {
|
|
|
74569
74603
|
}
|
|
74570
74604
|
/***************************************************************
|
|
74571
74605
|
* The plan is a list of writes computed against the model shown:
|
|
74572
|
-
* a load replaces the model, so the plan goes with it
|
|
74573
|
-
*
|
|
74574
|
-
*
|
|
74606
|
+
* a load that LANDS replaces the model, so the plan goes with it
|
|
74607
|
+
* (and end_load() closes the dialog built on that model). A load
|
|
74608
|
+
* that fails or never leaves keeps the model, and the plan.
|
|
74575
74609
|
***************************************************************/
|
|
74576
74610
|
function forget_import_plan(gobj) {
|
|
74577
74611
|
let priv = gobj.priv;
|
|
@@ -75138,6 +75172,8 @@ function ac_mt_command_answer(gobj, event, kw, src) {
|
|
|
75138
75172
|
priv.order_undo = {};
|
|
75139
75173
|
priv.records_before = null;
|
|
75140
75174
|
priv.model_gen++;
|
|
75175
|
+
priv.reload_on_open = false;
|
|
75176
|
+
forget_import_plan(gobj);
|
|
75141
75177
|
build_model(gobj);
|
|
75142
75178
|
start_measuring(gobj);
|
|
75143
75179
|
return end_load(gobj);
|
|
@@ -75268,7 +75304,8 @@ function ac_show(gobj, event, kw, src) {
|
|
|
75268
75304
|
priv.pending_seg = seg;
|
|
75269
75305
|
return 0;
|
|
75270
75306
|
}
|
|
75271
|
-
|
|
75307
|
+
apply_seg(gobj, seg);
|
|
75308
|
+
return reload_after_move(gobj);
|
|
75272
75309
|
}
|
|
75273
75310
|
/***************************************************************
|
|
75274
75311
|
* Hidden by the host: drop the overlays. A dialog outlives the
|
|
@@ -75707,6 +75744,15 @@ function ac_export(gobj, event, kw, src) {
|
|
|
75707
75744
|
open_export(gobj, treedb);
|
|
75708
75745
|
return 0;
|
|
75709
75746
|
}
|
|
75747
|
+
/***************************************************************
|
|
75748
|
+
* The export dialog's C / JSON switch. Its texts were composed
|
|
75749
|
+
* when it opened, so it reads nothing of the model and is
|
|
75750
|
+
* answered in every state: the dialog stays up through a load
|
|
75751
|
+
* that fails and through a move sent by the host.
|
|
75752
|
+
***************************************************************/
|
|
75753
|
+
function ac_export_view(gobj, event, kw, src) {
|
|
75754
|
+
return show_export_view(gobj, kw && kw.pane);
|
|
75755
|
+
}
|
|
75710
75756
|
function ac_import(gobj, event, kw, src) {
|
|
75711
75757
|
let treedb = current_treedb(gobj);
|
|
75712
75758
|
if (refuse_if_readonly(gobj, event)) return -1;
|
|
@@ -75890,6 +75936,11 @@ function create_gclass$1(gclass_name) {
|
|
|
75890
75936
|
"EV_DRAFTS",
|
|
75891
75937
|
ac_drafts,
|
|
75892
75938
|
null
|
|
75939
|
+
],
|
|
75940
|
+
[
|
|
75941
|
+
"EV_EXPORT_VIEW",
|
|
75942
|
+
ac_export_view,
|
|
75943
|
+
null
|
|
75893
75944
|
]
|
|
75894
75945
|
];
|
|
75895
75946
|
const TREEDB_WIDE = [
|
|
@@ -76097,6 +76148,7 @@ function create_gclass$1(gclass_name) {
|
|
|
76097
76148
|
["EV_UNDO_ORDER", 0],
|
|
76098
76149
|
["EV_VALIDATE", 0],
|
|
76099
76150
|
["EV_EXPORT", 0],
|
|
76151
|
+
["EV_EXPORT_VIEW", 0],
|
|
76100
76152
|
["EV_IMPORT", 0],
|
|
76101
76153
|
["EV_PREVIEW_IMPORT", 0],
|
|
76102
76154
|
["EV_APPLY_IMPORT", 0],
|
package/package.json
CHANGED
|
@@ -249,6 +249,9 @@ let PRIVATE_DATA = {
|
|
|
249
249
|
import_plan: null,
|
|
250
250
|
import_pane: null,
|
|
251
251
|
import_run: null,
|
|
252
|
+
|
|
253
|
+
/* The export dialog while it is up: its content and its two texts */
|
|
254
|
+
export_view: null,
|
|
252
255
|
};
|
|
253
256
|
|
|
254
257
|
let __gclass__ = null;
|
|
@@ -494,7 +497,12 @@ function built_on_a_replaced_model(gobj, event, kw)
|
|
|
494
497
|
* export) -- is refused and said: it would be computed on what
|
|
495
498
|
* the store may no longer hold, and the load that lands closes a
|
|
496
499
|
* dialog built on the old model anyway (end_load()). A move is
|
|
497
|
-
* not refused (reload_after_move()): it goes, and reads there
|
|
500
|
+
* not refused (reload_after_move()): it goes, and reads there --
|
|
501
|
+
* the editor's own moves and the host's alike (ac_show(): a url,
|
|
502
|
+
* the browser's Back).
|
|
503
|
+
*
|
|
504
|
+
* Paid by ANY load that lands, whoever asked it
|
|
505
|
+
* (ac_mt_command_answer()): the store has just been read whole.
|
|
498
506
|
*
|
|
499
507
|
* Not on a timer, and not at once: a load refused on a deadline
|
|
500
508
|
* asked again at once is refused the same way, and one asked on a
|
|
@@ -558,9 +566,10 @@ function reload_after_move(gobj)
|
|
|
558
566
|
* left open is answered in ST_LOADING instead (ac_wait_for_the_load),
|
|
559
567
|
* and a load that LANDS closes it (end_load()): it was built on the
|
|
560
568
|
* model the load replaced, and its Save sends every field it shows.
|
|
561
|
-
* An import plan is forgotten
|
|
562
|
-
*
|
|
563
|
-
*
|
|
569
|
+
* An import plan is forgotten for the same reason, and at the same
|
|
570
|
+
* moment: when the load LANDS and the model it was computed on goes
|
|
571
|
+
* (ac_mt_command_answer()). A load that cannot leave, or that fails,
|
|
572
|
+
* replaces nothing, and the plan stays with the dialog showing it.
|
|
564
573
|
*
|
|
565
574
|
* `keep_written`: a load nobody ASKED for -- the reconnect, a write
|
|
566
575
|
* that turned out done, the reload a refused load owed -- keeps what
|
|
@@ -626,9 +635,6 @@ function request_model(gobj, keep_written)
|
|
|
626
635
|
end_load(gobj);
|
|
627
636
|
return -1;
|
|
628
637
|
}
|
|
629
|
-
/* Only a load that LEFT replaces the model the plan was computed
|
|
630
|
-
* on; one that could not be sent keeps it, and the plan with it. */
|
|
631
|
-
forget_import_plan(gobj);
|
|
632
638
|
priv.pending = left;
|
|
633
639
|
return 0;
|
|
634
640
|
}
|
|
@@ -1739,6 +1745,7 @@ function close_dialog(gobj)
|
|
|
1739
1745
|
}
|
|
1740
1746
|
let dialog = priv.dialog;
|
|
1741
1747
|
priv.dialog = null;
|
|
1748
|
+
priv.export_view = null;
|
|
1742
1749
|
try {
|
|
1743
1750
|
dialog.close();
|
|
1744
1751
|
} catch(e) {
|
|
@@ -1760,6 +1767,7 @@ function open_dialog(gobj, $content, title, logical, title_prefix)
|
|
|
1760
1767
|
t: t,
|
|
1761
1768
|
on_close: () => {
|
|
1762
1769
|
priv.dialog = null;
|
|
1770
|
+
priv.export_view = null;
|
|
1763
1771
|
}
|
|
1764
1772
|
});
|
|
1765
1773
|
refresh_language($content, t);
|
|
@@ -2279,11 +2287,7 @@ function open_export(gobj, treedb)
|
|
|
2279
2287
|
for(let $tab of $content.querySelectorAll(".SCHEMA_EXPORT_TAB")) {
|
|
2280
2288
|
$tab.addEventListener("click", (evt) => {
|
|
2281
2289
|
evt.stopPropagation();
|
|
2282
|
-
|
|
2283
|
-
$other.classList.toggle("selected_state", $other === $tab);
|
|
2284
|
-
$other.setAttribute("aria-pressed", ($other === $tab)? "true": "false");
|
|
2285
|
-
}
|
|
2286
|
-
$text.value = ($tab.dataset.pane === "c") ? c_text : json_text;
|
|
2290
|
+
gobj_send_event(gobj, "EV_EXPORT_VIEW", {pane: $tab.dataset.pane}, gobj);
|
|
2287
2291
|
});
|
|
2288
2292
|
}
|
|
2289
2293
|
$content.querySelector(".SCHEMA_EXPORT_COPY").addEventListener("click", (evt) => {
|
|
@@ -2292,6 +2296,35 @@ function open_export(gobj, treedb)
|
|
|
2292
2296
|
});
|
|
2293
2297
|
|
|
2294
2298
|
open_dialog(gobj, $content, "export", "SCHEMA_EXPORT_DIALOG", treedb.id);
|
|
2299
|
+
/* After open_dialog(): it closes the dialog before, and that forgets
|
|
2300
|
+
* the view of the one it closes. */
|
|
2301
|
+
priv.export_view = {$content: $content, texts: {c: c_text, json: json_text}};
|
|
2302
|
+
}
|
|
2303
|
+
|
|
2304
|
+
/***************************************************************
|
|
2305
|
+
* Show one of the export's two texts, and say which one is shown
|
|
2306
|
+
* (`selected_state` + aria-pressed). Reached only through
|
|
2307
|
+
* EV_EXPORT_VIEW: a click is an action like any other.
|
|
2308
|
+
***************************************************************/
|
|
2309
|
+
function show_export_view(gobj, pane)
|
|
2310
|
+
{
|
|
2311
|
+
let view = gobj.priv.export_view;
|
|
2312
|
+
|
|
2313
|
+
if(!view) {
|
|
2314
|
+
log_error(`${gobj_short_name(gobj)}: export view '${pane}' asked with no export open`);
|
|
2315
|
+
return -1;
|
|
2316
|
+
}
|
|
2317
|
+
if(!Object.prototype.hasOwnProperty.call(view.texts, pane)) {
|
|
2318
|
+
log_error(`${gobj_short_name(gobj)}: the export has no view '${pane}'`);
|
|
2319
|
+
return -1;
|
|
2320
|
+
}
|
|
2321
|
+
for(let $tab of view.$content.querySelectorAll(".SCHEMA_EXPORT_TAB")) {
|
|
2322
|
+
let shown = ($tab.dataset.pane === pane);
|
|
2323
|
+
$tab.classList.toggle("selected_state", shown);
|
|
2324
|
+
$tab.setAttribute("aria-pressed", shown ? "true" : "false");
|
|
2325
|
+
}
|
|
2326
|
+
view.$content.querySelector(".SCHEMA_EXPORT_TEXT").value = view.texts[pane];
|
|
2327
|
+
return 0;
|
|
2295
2328
|
}
|
|
2296
2329
|
|
|
2297
2330
|
/***************************************************************
|
|
@@ -2384,9 +2417,9 @@ function open_import(gobj, treedb)
|
|
|
2384
2417
|
|
|
2385
2418
|
/***************************************************************
|
|
2386
2419
|
* The plan is a list of writes computed against the model shown:
|
|
2387
|
-
* a load replaces the model, so the plan goes with it
|
|
2388
|
-
*
|
|
2389
|
-
*
|
|
2420
|
+
* a load that LANDS replaces the model, so the plan goes with it
|
|
2421
|
+
* (and end_load() closes the dialog built on that model). A load
|
|
2422
|
+
* that fails or never leaves keeps the model, and the plan.
|
|
2390
2423
|
***************************************************************/
|
|
2391
2424
|
function forget_import_plan(gobj)
|
|
2392
2425
|
{
|
|
@@ -3103,6 +3136,17 @@ function ac_mt_command_answer(gobj, event, kw, src)
|
|
|
3103
3136
|
priv.order_undo = {};
|
|
3104
3137
|
priv.records_before = null;
|
|
3105
3138
|
priv.model_gen++;
|
|
3139
|
+
/* The store was read whole: whatever reload was owed is paid,
|
|
3140
|
+
* whoever asked for this one -- the operator's Refresh, a late
|
|
3141
|
+
* write, the reconnect. Left owed, the next edit was refused
|
|
3142
|
+
* and read the store AGAIN (sixth independent review). */
|
|
3143
|
+
priv.reload_on_open = false;
|
|
3144
|
+
/* The plan was a list of writes computed on the model this load
|
|
3145
|
+
* replaces. Forgotten HERE, where the model goes, and not when
|
|
3146
|
+
* the requests leave: a load that fails replaces nothing, and
|
|
3147
|
+
* forgetting early left its dialog up with no plan and Import
|
|
3148
|
+
* disabled (sixth independent review). */
|
|
3149
|
+
forget_import_plan(gobj);
|
|
3106
3150
|
build_model(gobj);
|
|
3107
3151
|
/* Same reason as order_undo above: this is the LOAD, and the
|
|
3108
3152
|
* baseline is what a later "the version did not move" is measured
|
|
@@ -3297,7 +3341,12 @@ function ac_show(gobj, event, kw, src)
|
|
|
3297
3341
|
priv.pending_seg = seg;
|
|
3298
3342
|
return 0; /* applied when the write lands (end_writes) or the load (end_load) */
|
|
3299
3343
|
}
|
|
3300
|
-
|
|
3344
|
+
/* A move like the editor's own (ac_back() and the rest): it goes,
|
|
3345
|
+
* and pays the reload a refused load owes there. Without it a url
|
|
3346
|
+
* or the browser's Back left it owed on a screen that asked for
|
|
3347
|
+
* nothing (sixth independent review). */
|
|
3348
|
+
apply_seg(gobj, seg);
|
|
3349
|
+
return reload_after_move(gobj);
|
|
3301
3350
|
}
|
|
3302
3351
|
|
|
3303
3352
|
/***************************************************************
|
|
@@ -3903,6 +3952,17 @@ function ac_export(gobj, event, kw, src)
|
|
|
3903
3952
|
return 0;
|
|
3904
3953
|
}
|
|
3905
3954
|
|
|
3955
|
+
/***************************************************************
|
|
3956
|
+
* The export dialog's C / JSON switch. Its texts were composed
|
|
3957
|
+
* when it opened, so it reads nothing of the model and is
|
|
3958
|
+
* answered in every state: the dialog stays up through a load
|
|
3959
|
+
* that fails and through a move sent by the host.
|
|
3960
|
+
***************************************************************/
|
|
3961
|
+
function ac_export_view(gobj, event, kw, src)
|
|
3962
|
+
{
|
|
3963
|
+
return show_export_view(gobj, kw && kw.pane);
|
|
3964
|
+
}
|
|
3965
|
+
|
|
3906
3966
|
function ac_import(gobj, event, kw, src)
|
|
3907
3967
|
{
|
|
3908
3968
|
let treedb = current_treedb(gobj);
|
|
@@ -3994,8 +4054,9 @@ function run_import(gobj)
|
|
|
3994
4054
|
let priv = gobj.priv;
|
|
3995
4055
|
let plan = priv.import_plan;
|
|
3996
4056
|
|
|
3997
|
-
/* Not an ERROR: a load that
|
|
3998
|
-
* and the confirmation of it may still be
|
|
4057
|
+
/* Not an ERROR: a load that lands forgets the plan
|
|
4058
|
+
* (ac_mt_command_answer()), and the confirmation of it may still be
|
|
4059
|
+
* up. The operator's Yes
|
|
3999
4060
|
* is answered, not lost in the log. */
|
|
4000
4061
|
if(!plan) {
|
|
4001
4062
|
log_warning(`${gobj_short_name(gobj)}: the import plan is gone`);
|
|
@@ -4099,7 +4160,9 @@ function create_gclass(gclass_name)
|
|
|
4099
4160
|
["EV_TRANSPORT_STATE", ac_transport_state, null],
|
|
4100
4161
|
["EV_LANGUAGE_CHANGED", ac_language_changed, null],
|
|
4101
4162
|
["EV_REFRESH", ac_refresh, null],
|
|
4102
|
-
["EV_DRAFTS", ac_drafts, null]
|
|
4163
|
+
["EV_DRAFTS", ac_drafts, null],
|
|
4164
|
+
/* The export dialog outlives the screen it was opened from. */
|
|
4165
|
+
["EV_EXPORT_VIEW", ac_export_view, null]
|
|
4103
4166
|
];
|
|
4104
4167
|
|
|
4105
4168
|
/* What a treedb is open for: reading it whole, and writing it
|
|
@@ -4215,6 +4278,7 @@ function create_gclass(gclass_name)
|
|
|
4215
4278
|
["EV_UNDO_ORDER", 0],
|
|
4216
4279
|
["EV_VALIDATE", 0],
|
|
4217
4280
|
["EV_EXPORT", 0],
|
|
4281
|
+
["EV_EXPORT_VIEW", 0],
|
|
4218
4282
|
["EV_IMPORT", 0],
|
|
4219
4283
|
["EV_PREVIEW_IMPORT", 0],
|
|
4220
4284
|
["EV_APPLY_IMPORT", 0],
|
|
@@ -25,6 +25,14 @@
|
|
|
25
25
|
* silence, and a toolbar gated on the state instead of on the
|
|
26
26
|
* treedb being there.
|
|
27
27
|
*
|
|
28
|
+
* The sixth independent review (same day) found where the owed
|
|
29
|
+
* reload still lingered: a load that LANDED by another road (the
|
|
30
|
+
* operator's Refresh, a late write) left it owed, so the next
|
|
31
|
+
* edit was refused and read the store again; a move sent by the
|
|
32
|
+
* host did not run it; a load that failed forgot the import plan
|
|
33
|
+
* of a dialog it left up; and the export's two views switched in
|
|
34
|
+
* a DOM handler, out of the machine.
|
|
35
|
+
*
|
|
28
36
|
* Driven through the FSM on a document double, with a fake
|
|
29
37
|
* transport whose state is the one the library reads.
|
|
30
38
|
*
|
|
@@ -68,6 +76,7 @@ const {
|
|
|
68
76
|
gobj_start_up, gobj_create_yuno, gobj_create, gobj_create_service,
|
|
69
77
|
gobj_start, gobj_send_event, gobj_read_attr,
|
|
70
78
|
gobj_change_state, gobj_current_state,
|
|
79
|
+
gobj_set_gobj_trace,
|
|
71
80
|
set_log_callback,
|
|
72
81
|
} = await import("@yuneta/gobj-js");
|
|
73
82
|
const {register_c_yui_schema_editor} = await import("./c_yui_schema_editor.js");
|
|
@@ -575,11 +584,12 @@ describe("a dialog built on the model a reload replaced (fourth review)", () =>
|
|
|
575
584
|
expect(editor.priv.import_plan.writes.length).toBeGreaterThan(0);
|
|
576
585
|
|
|
577
586
|
gobj_send_event(editor, "EV_REFRESH", {}, host);
|
|
578
|
-
expect(editor.priv.import_plan).toBe(null);
|
|
579
587
|
answer_the_load_with(editor, remote, records_with((r) => {
|
|
580
588
|
r.cols.push({id: "db.users.email", value: "email", order: 2, type: "integer",
|
|
581
589
|
topics: ["topics^db.users^cols"]});
|
|
582
590
|
}));
|
|
591
|
+
/* Forgotten when the load LANDS, not when it leaves (sixth review). */
|
|
592
|
+
expect(editor.priv.import_plan).toBe(null);
|
|
583
593
|
expect(dialog.closed).toBe(true);
|
|
584
594
|
|
|
585
595
|
dialog.$content.querySelector(".SCHEMA_IMPORT_RUN").disabled = false;
|
|
@@ -1035,3 +1045,179 @@ describe("the answers of the editor's confirmations are i18n keys (fifth review,
|
|
|
1035
1045
|
.toEqual(["delete", "cancel"]);
|
|
1036
1046
|
});
|
|
1037
1047
|
});
|
|
1048
|
+
|
|
1049
|
+
describe("the owed reload, settled wherever a load lands (sixth review)", () => {
|
|
1050
|
+
|
|
1051
|
+
function refused_load(name, subpath)
|
|
1052
|
+
{
|
|
1053
|
+
const built = build(name, subpath);
|
|
1054
|
+
gobj_send_event(built.editor, "EV_REFRESH", {}, built.host);
|
|
1055
|
+
const asked = take("nodes");
|
|
1056
|
+
answer(built.editor, built.remote, asked[0], -1, null, "deadline");
|
|
1057
|
+
answer(built.editor, built.remote, asked[1], 0, RECORDS[asked[1].kw.topic_name]);
|
|
1058
|
+
answer(built.editor, built.remote, asked[2], 0, RECORDS[asked[2].kw.topic_name]);
|
|
1059
|
+
expect(built.editor.priv.reload_on_open).toBe(true);
|
|
1060
|
+
expect(shown).toEqual([KEPT]);
|
|
1061
|
+
return built;
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
test("the operator's Refresh that lands pays it: the next edit opens its form", () => {
|
|
1065
|
+
const {editor, remote, host} = refused_load("q1", "db/users");
|
|
1066
|
+
gobj_send_event(editor, "EV_REFRESH", {}, host);
|
|
1067
|
+
expect(answer_the_load(editor, remote)).toBe(3);
|
|
1068
|
+
expect(gobj_current_state(editor)).toBe("ST_COLUMNS");
|
|
1069
|
+
expect(editor.priv.reload_on_open).toBe(false);
|
|
1070
|
+
|
|
1071
|
+
const before = modals.length;
|
|
1072
|
+
gobj_send_event(editor, "EV_EDIT_COLUMN", {col: "id"}, host);
|
|
1073
|
+
expect(modals.length).toBe(before + 1);
|
|
1074
|
+
expect(take("nodes")).toEqual([]);
|
|
1075
|
+
expect(shown).toEqual([KEPT]);
|
|
1076
|
+
expect(errors()).toEqual([]);
|
|
1077
|
+
expect(not_defined()).toEqual([]);
|
|
1078
|
+
});
|
|
1079
|
+
|
|
1080
|
+
test("the reload of a late write that lands pays it too", () => {
|
|
1081
|
+
const {editor, remote, host} = build("q2", "db/users");
|
|
1082
|
+
const w = start_a_write(editor, host, "name");
|
|
1083
|
+
drop(editor, remote, host);
|
|
1084
|
+
reconnect(editor, remote, host);
|
|
1085
|
+
expect(answer_the_load(editor, remote)).toBe(3);
|
|
1086
|
+
|
|
1087
|
+
gobj_send_event(editor, "EV_REFRESH", {}, host);
|
|
1088
|
+
const asked = take("nodes");
|
|
1089
|
+
answer(editor, remote, asked[0], -1, null, "deadline");
|
|
1090
|
+
answer(editor, remote, asked[1], 0, RECORDS[asked[1].kw.topic_name]);
|
|
1091
|
+
answer(editor, remote, asked[2], 0, RECORDS[asked[2].kw.topic_name]);
|
|
1092
|
+
expect(editor.priv.reload_on_open).toBe(true);
|
|
1093
|
+
|
|
1094
|
+
/* The write given up answers DONE: the model is read again. */
|
|
1095
|
+
answer(editor, remote, w, 0, {id: "db.users.name", value: "name", type: "string",
|
|
1096
|
+
order: 2, topics: [{id: "db.users", topic_name: "topics", hook_name: "cols"}]});
|
|
1097
|
+
expect(gobj_current_state(editor)).toBe("ST_LOADING");
|
|
1098
|
+
expect(answer_the_load(editor, remote)).toBe(3);
|
|
1099
|
+
expect(editor.priv.reload_on_open).toBe(false);
|
|
1100
|
+
|
|
1101
|
+
const before = modals.length;
|
|
1102
|
+
gobj_send_event(editor, "EV_EDIT_COLUMN", {col: "id"}, host);
|
|
1103
|
+
expect(modals.length).toBe(before + 1);
|
|
1104
|
+
expect(take("nodes")).toEqual([]);
|
|
1105
|
+
expect(errors()).toEqual([]);
|
|
1106
|
+
});
|
|
1107
|
+
|
|
1108
|
+
test("a move sent by the HOST (a url, the browser's Back) runs it, as the editor's own moves do", () => {
|
|
1109
|
+
const {editor, remote, host} = refused_load("q3", "db/users");
|
|
1110
|
+
gobj_send_event(editor, "EV_SHOW", {subpath: "db"}, host);
|
|
1111
|
+
expect(gobj_current_state(editor)).toBe("ST_LOADING");
|
|
1112
|
+
expect(editor.priv.reload_on_open).toBe(false);
|
|
1113
|
+
expect(shown).toEqual([KEPT]); /* a move is not refused */
|
|
1114
|
+
expect(answer_the_load(editor, remote)).toBe(3);
|
|
1115
|
+
expect(gobj_current_state(editor)).toBe("ST_TOPICS");
|
|
1116
|
+
expect(errors()).toEqual([]);
|
|
1117
|
+
expect(not_defined()).toEqual([]);
|
|
1118
|
+
});
|
|
1119
|
+
|
|
1120
|
+
test("a host EV_SHOW with nothing owed asks for nothing", () => {
|
|
1121
|
+
const {editor, remote, host} = build("q4", "db/users");
|
|
1122
|
+
gobj_send_event(editor, "EV_SHOW", {subpath: "db"}, host);
|
|
1123
|
+
expect(gobj_current_state(editor)).toBe("ST_TOPICS");
|
|
1124
|
+
expect(take("nodes")).toEqual([]);
|
|
1125
|
+
});
|
|
1126
|
+
});
|
|
1127
|
+
|
|
1128
|
+
describe("the import plan outlives a load that fails (sixth review)", () => {
|
|
1129
|
+
|
|
1130
|
+
const IMPORT = JSON.stringify({id: "db", topics: [{id: "users", pkey: "id", cols: [
|
|
1131
|
+
{id: "id", type: "string", flag: ["persistent", "required"]},
|
|
1132
|
+
{id: "email", type: "string"}
|
|
1133
|
+
]}]});
|
|
1134
|
+
|
|
1135
|
+
test("a load that LEFT and failed replaced nothing: the plan and its Import stay", () => {
|
|
1136
|
+
const {editor, remote, host} = build("m1", "db");
|
|
1137
|
+
gobj_send_event(editor, "EV_IMPORT", {}, host);
|
|
1138
|
+
const dialog = modals[modals.length - 1];
|
|
1139
|
+
gobj_send_event(editor, "EV_PREVIEW_IMPORT", {prune: false, text: IMPORT,
|
|
1140
|
+
model_gen: editor.priv.model_gen}, editor);
|
|
1141
|
+
const plan = editor.priv.import_plan;
|
|
1142
|
+
expect(plan.writes.length).toBeGreaterThan(0);
|
|
1143
|
+
|
|
1144
|
+
gobj_send_event(editor, "EV_REFRESH", {}, host);
|
|
1145
|
+
const asked = take("nodes");
|
|
1146
|
+
answer(editor, remote, asked[0], -1, null, "deadline");
|
|
1147
|
+
answer(editor, remote, asked[1], 0, RECORDS[asked[1].kw.topic_name]);
|
|
1148
|
+
answer(editor, remote, asked[2], 0, RECORDS[asked[2].kw.topic_name]);
|
|
1149
|
+
|
|
1150
|
+
expect(dialog.closed).toBe(false);
|
|
1151
|
+
expect(editor.priv.import_plan).toBe(plan);
|
|
1152
|
+
expect(dialog.$content.querySelector(".SCHEMA_IMPORT_RUN").disabled).toBe(false);
|
|
1153
|
+
expect(dialog.$content.querySelector(".SCHEMA_IMPORT_PLAN").childNodes.length)
|
|
1154
|
+
.toBeGreaterThan(0);
|
|
1155
|
+
expect(errors()).toEqual([]);
|
|
1156
|
+
});
|
|
1157
|
+
|
|
1158
|
+
test("a load that LANDS forgets it, and closes the dialog it was shown in", () => {
|
|
1159
|
+
const {editor, remote, host} = build("m2", "db");
|
|
1160
|
+
gobj_send_event(editor, "EV_IMPORT", {}, host);
|
|
1161
|
+
const dialog = modals[modals.length - 1];
|
|
1162
|
+
gobj_send_event(editor, "EV_PREVIEW_IMPORT", {prune: false, text: IMPORT,
|
|
1163
|
+
model_gen: editor.priv.model_gen}, editor);
|
|
1164
|
+
expect(editor.priv.import_plan).toBeTruthy();
|
|
1165
|
+
|
|
1166
|
+
gobj_send_event(editor, "EV_REFRESH", {}, host);
|
|
1167
|
+
expect(editor.priv.import_plan).toBeTruthy(); /* in the air: nothing replaced yet */
|
|
1168
|
+
expect(answer_the_load(editor, remote)).toBe(3);
|
|
1169
|
+
expect(editor.priv.import_plan).toBe(null);
|
|
1170
|
+
expect(dialog.closed).toBe(true);
|
|
1171
|
+
expect(shown).toEqual([STALE]);
|
|
1172
|
+
expect(errors()).toEqual([]);
|
|
1173
|
+
});
|
|
1174
|
+
});
|
|
1175
|
+
|
|
1176
|
+
describe("the export's two views go through the machine (sixth review)", () => {
|
|
1177
|
+
|
|
1178
|
+
test("a click on a view is an event, and the action switches the text", () => {
|
|
1179
|
+
const {editor, remote, host} = build("y1", "db");
|
|
1180
|
+
gobj_send_event(editor, "EV_EXPORT", {}, host);
|
|
1181
|
+
const $content = modals[modals.length - 1].$content;
|
|
1182
|
+
const $tabs = [...$content.querySelectorAll(".SCHEMA_EXPORT_TAB")];
|
|
1183
|
+
const $text = $content.querySelector(".SCHEMA_EXPORT_TEXT");
|
|
1184
|
+
|
|
1185
|
+
gobj_set_gobj_trace(editor, "machine", true);
|
|
1186
|
+
try {
|
|
1187
|
+
$tabs[1].click();
|
|
1188
|
+
} finally {
|
|
1189
|
+
gobj_set_gobj_trace(editor, "machine", false);
|
|
1190
|
+
}
|
|
1191
|
+
expect(logged.some((l) => /EV_EXPORT_VIEW/.test(l.msg))).toBe(true);
|
|
1192
|
+
expect($text.value.trim().startsWith("{")).toBe(true);
|
|
1193
|
+
expect($tabs.map(($b) => $b.getAttribute("aria-pressed"))).toEqual(["false", "true"]);
|
|
1194
|
+
expect($tabs.map(($b) => $b.classList.contains("selected_state"))).toEqual([false, true]);
|
|
1195
|
+
|
|
1196
|
+
gobj_send_event(editor, "EV_EXPORT_VIEW", {pane: "c"}, editor);
|
|
1197
|
+
expect($text.value.trim().startsWith("{")).toBe(false);
|
|
1198
|
+
expect($tabs.map(($b) => $b.getAttribute("aria-pressed"))).toEqual(["true", "false"]);
|
|
1199
|
+
expect(errors()).toEqual([]);
|
|
1200
|
+
expect(not_defined()).toEqual([]);
|
|
1201
|
+
});
|
|
1202
|
+
|
|
1203
|
+
test("answered while a load is in the air, where the dialog is still up", () => {
|
|
1204
|
+
const {editor, remote, host} = build("y2", "db");
|
|
1205
|
+
gobj_send_event(editor, "EV_EXPORT", {}, host);
|
|
1206
|
+
const $content = modals[modals.length - 1].$content;
|
|
1207
|
+
gobj_send_event(editor, "EV_REFRESH", {}, host);
|
|
1208
|
+
expect(gobj_current_state(editor)).toBe("ST_LOADING");
|
|
1209
|
+
$content.querySelectorAll(".SCHEMA_EXPORT_TAB")[1].click();
|
|
1210
|
+
expect($content.querySelector(".SCHEMA_EXPORT_TEXT").value.trim().startsWith("{")).toBe(true);
|
|
1211
|
+
expect(not_defined()).toEqual([]);
|
|
1212
|
+
expect(answer_the_load(editor, remote)).toBe(3);
|
|
1213
|
+
expect(errors()).toEqual([]);
|
|
1214
|
+
});
|
|
1215
|
+
|
|
1216
|
+
test("a view that is not one, or no export open, is an ERROR, not a guess", () => {
|
|
1217
|
+
const {editor, remote, host} = build("y3", "db");
|
|
1218
|
+
gobj_send_event(editor, "EV_EXPORT_VIEW", {pane: "c"}, editor);
|
|
1219
|
+
gobj_send_event(editor, "EV_EXPORT", {}, host);
|
|
1220
|
+
gobj_send_event(editor, "EV_EXPORT_VIEW", {pane: "yaml"}, editor);
|
|
1221
|
+
expect(errors().length).toBe(2);
|
|
1222
|
+
});
|
|
1223
|
+
});
|