@yuneta/gobj-ui 7.23.182 → 7.23.184
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/dist/gobj-ui.cjs.js +191 -17
- package/dist/gobj-ui.es.js +191 -17
- package/package.json +1 -1
- package/src/c_yui_treedb_topic_with_form.js +170 -1
- package/src/c_yui_treedb_topics.js +42 -2
- package/src/yui_dev.js +20 -15
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -24640,7 +24640,7 @@ function get_gobj_formtable(gobj, topic_name) {
|
|
|
24640
24640
|
/************************************************************
|
|
24641
24641
|
* Command to remote service
|
|
24642
24642
|
************************************************************/
|
|
24643
|
-
function treedb_nodes$1(gobj, treedb_name, topic_name, options, page) {
|
|
24643
|
+
function treedb_nodes$1(gobj, treedb_name, topic_name, options, page, purpose) {
|
|
24644
24644
|
let command = "nodes";
|
|
24645
24645
|
let gobj_remote_yuno = (0, _yuneta_gobj_js.gobj_read_pointer_attr)(gobj, "gobj_remote_yuno");
|
|
24646
24646
|
let kw = {
|
|
@@ -24650,6 +24650,7 @@ function treedb_nodes$1(gobj, treedb_name, topic_name, options, page) {
|
|
|
24650
24650
|
options: options || {}
|
|
24651
24651
|
};
|
|
24652
24652
|
kw.__md_command__ = { topic_name };
|
|
24653
|
+
if (purpose) kw.__md_command__.purpose = purpose;
|
|
24653
24654
|
if (page) {
|
|
24654
24655
|
kw.from = page.from;
|
|
24655
24656
|
kw.limit = page.limit;
|
|
@@ -24931,7 +24932,8 @@ function ac_mt_command_answer$2(gobj, event, kw, src) {
|
|
|
24931
24932
|
let gobj_topic_form = (0, _yuneta_gobj_js.gobj_find_child)(gobj, { __gobj_name__: `${(0, _yuneta_gobj_js.gobj_name)(gobj)}?${topic_name}` });
|
|
24932
24933
|
let answer = nodes_answer(data);
|
|
24933
24934
|
let req_id = (0, _yuneta_gobj_js.kw_get_str)(gobj, kw_command, "req_id", "", 0);
|
|
24934
|
-
if (
|
|
24935
|
+
if ((0, _yuneta_gobj_js.kw_get_str)(gobj, kw_command, "purpose", "", 0) === "json") (0, _yuneta_gobj_js.gobj_send_event)(gobj_topic_form, "EV_JSON_LOADED", { rows: answer.rows }, gobj);
|
|
24936
|
+
else if (req_id) (0, _yuneta_gobj_js.gobj_send_event)(gobj_topic_form, "EV_PAGE_LOADED", {
|
|
24935
24937
|
req_id,
|
|
24936
24938
|
rows: answer.rows,
|
|
24937
24939
|
pages: answer.pages,
|
|
@@ -25175,6 +25177,20 @@ function ac_create_record(gobj, event, kw, src) {
|
|
|
25175
25177
|
});
|
|
25176
25178
|
}
|
|
25177
25179
|
/********************************************
|
|
25180
|
+
* A topic table wants its records as json, WITH the metadata of
|
|
25181
|
+
* each one (its Raw JSON button). The table's own rows are read
|
|
25182
|
+
* without it, so this is a read of its own: the whole topic, and
|
|
25183
|
+
* the table keeps to the rows it shows.
|
|
25184
|
+
********************************************/
|
|
25185
|
+
function ac_request_json(gobj, event, kw, src) {
|
|
25186
|
+
let topic_name = kw.topic_name || (0, _yuneta_gobj_js.gobj_read_attr)(src, "topic_name");
|
|
25187
|
+
if (!topic_name) {
|
|
25188
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: a json request with no topic`);
|
|
25189
|
+
return -1;
|
|
25190
|
+
}
|
|
25191
|
+
return treedb_nodes$1(gobj, (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "treedb_name"), topic_name, Object.assign({}, TABLE_READ_OPTIONS, { with_metadata: true }), null, "json");
|
|
25192
|
+
}
|
|
25193
|
+
/********************************************
|
|
25178
25194
|
* A topic table wants a page.
|
|
25179
25195
|
*
|
|
25180
25196
|
* The transport is ours, so the table asks and we fetch; the answer
|
|
@@ -25458,6 +25474,11 @@ function create_gclass$6(gclass_name) {
|
|
|
25458
25474
|
ac_request_page,
|
|
25459
25475
|
null
|
|
25460
25476
|
],
|
|
25477
|
+
[
|
|
25478
|
+
"EV_REQUEST_JSON",
|
|
25479
|
+
ac_request_json,
|
|
25480
|
+
null
|
|
25481
|
+
],
|
|
25461
25482
|
[
|
|
25462
25483
|
"EV_REQUEST_ASSET",
|
|
25463
25484
|
ac_request_asset,
|
|
@@ -25548,6 +25569,7 @@ function create_gclass$6(gclass_name) {
|
|
|
25548
25569
|
["EV_UPDATE_RECORD", 0],
|
|
25549
25570
|
["EV_UPDATE_FIELD", 0],
|
|
25550
25571
|
["EV_REQUEST_PAGE", 0],
|
|
25572
|
+
["EV_REQUEST_JSON", 0],
|
|
25551
25573
|
["EV_REQUEST_ASSET", 0],
|
|
25552
25574
|
["EV_OPEN_LINKED", 0],
|
|
25553
25575
|
["EV_DELETE_RECORD", 0],
|
|
@@ -26359,6 +26381,7 @@ var attrs_table$5 = [
|
|
|
26359
26381
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_BOOLEAN, "with_search_button", 0, true, "Button toolbar SEARCH"),
|
|
26360
26382
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_BOOLEAN, "with_schema_button", 0, true, "Button toolbar SCHEMA (show the topic's desc)"),
|
|
26361
26383
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_BOOLEAN, "with_columns_button", 0, true, "Button toolbar COLUMNS (choose which columns the table shows)"),
|
|
26384
|
+
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_BOOLEAN, "with_json_button", 0, true, "Button toolbar RAW JSON (the table's records as json, with the metadata of each record)"),
|
|
26362
26385
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_BOOLEAN, "with_export_button", 0, true, "Button toolbar EXPORT (download as CSV what the table holds)"),
|
|
26363
26386
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_BOOLEAN, "with_header_filters", 0, true, "Per-column filter box in the table header, on the columns a text/number match means something (not hooks, fkeys or json)"),
|
|
26364
26387
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_BOOLEAN, "with_inline_edit", 0, true, "Edit a writable scalar cell in place while in edition mode (the record form keeps the rest)"),
|
|
@@ -26409,6 +26432,9 @@ var PRIVATE_DATA$5 = {
|
|
|
26409
26432
|
schema_win: null,
|
|
26410
26433
|
cell_json_gobj: null,
|
|
26411
26434
|
cell_json_modal: null,
|
|
26435
|
+
table_json_gobj: null,
|
|
26436
|
+
table_json_win: null,
|
|
26437
|
+
table_json_modal: null,
|
|
26412
26438
|
cell_json_win: null,
|
|
26413
26439
|
cell_file_box: null,
|
|
26414
26440
|
cell_file_modal: null,
|
|
@@ -26551,6 +26577,7 @@ function mt_stop$5(gobj) {
|
|
|
26551
26577
|
close_form_dialog(gobj);
|
|
26552
26578
|
close_schema_dialog(gobj);
|
|
26553
26579
|
close_cell_json_dialog(gobj);
|
|
26580
|
+
close_table_json_dialog(gobj);
|
|
26554
26581
|
close_cell_file_dialog(gobj);
|
|
26555
26582
|
close_hook_choice(gobj);
|
|
26556
26583
|
drop_pending_assets(gobj);
|
|
@@ -26563,6 +26590,7 @@ function mt_destroy$5(gobj) {
|
|
|
26563
26590
|
close_form_dialog(gobj);
|
|
26564
26591
|
close_schema_dialog(gobj);
|
|
26565
26592
|
close_cell_json_dialog(gobj);
|
|
26593
|
+
close_table_json_dialog(gobj);
|
|
26566
26594
|
close_cell_file_dialog(gobj);
|
|
26567
26595
|
close_hook_choice(gobj);
|
|
26568
26596
|
drop_pending_assets(gobj);
|
|
@@ -26792,6 +26820,7 @@ function build_ui$5(gobj) {
|
|
|
26792
26820
|
let with_search_button = (0, _yuneta_gobj_js.gobj_read_bool_attr)(gobj, "with_search_button");
|
|
26793
26821
|
let with_schema_button = (0, _yuneta_gobj_js.gobj_read_bool_attr)(gobj, "with_schema_button");
|
|
26794
26822
|
let with_columns_button = (0, _yuneta_gobj_js.gobj_read_bool_attr)(gobj, "with_columns_button");
|
|
26823
|
+
let with_json_button = (0, _yuneta_gobj_js.gobj_read_bool_attr)(gobj, "with_json_button");
|
|
26795
26824
|
let with_export_button = (0, _yuneta_gobj_js.gobj_read_bool_attr)(gobj, "with_export_button");
|
|
26796
26825
|
if (with_search_button) {
|
|
26797
26826
|
let search_id = `${toolbar_id}_search`;
|
|
@@ -26899,6 +26928,32 @@ function build_ui$5(gobj) {
|
|
|
26899
26928
|
]);
|
|
26900
26929
|
$view_toolbar.appendChild($columns);
|
|
26901
26930
|
}
|
|
26931
|
+
if (with_json_button) {
|
|
26932
|
+
let $json = (0, _yuneta_gobj_js.createElement2)([
|
|
26933
|
+
"button",
|
|
26934
|
+
{
|
|
26935
|
+
class: "TREEDB_TABLE_JSON button mr-1",
|
|
26936
|
+
title: (0, i18next.t)("raw json"),
|
|
26937
|
+
"data-i18n-title": "raw json",
|
|
26938
|
+
"aria-label": (0, i18next.t)("raw json"),
|
|
26939
|
+
"data-i18n-aria-label": "raw json"
|
|
26940
|
+
},
|
|
26941
|
+
[yui_toolbar_icon("yi-eye"), [
|
|
26942
|
+
"span",
|
|
26943
|
+
{
|
|
26944
|
+
class: "is-hidden-mobile",
|
|
26945
|
+
i18n: "raw json",
|
|
26946
|
+
style: "padding-left:5px;"
|
|
26947
|
+
},
|
|
26948
|
+
"raw json"
|
|
26949
|
+
]],
|
|
26950
|
+
{ "click": (event) => {
|
|
26951
|
+
event.stopPropagation();
|
|
26952
|
+
(0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_SHOW_TABLE_JSON", {}, gobj);
|
|
26953
|
+
} }
|
|
26954
|
+
]);
|
|
26955
|
+
$view_toolbar.appendChild($json);
|
|
26956
|
+
}
|
|
26902
26957
|
if (with_export_button) {
|
|
26903
26958
|
let $export = (0, _yuneta_gobj_js.createElement2)([
|
|
26904
26959
|
"button",
|
|
@@ -29776,6 +29831,107 @@ function ac_export_table(gobj, event, kw, src) {
|
|
|
29776
29831
|
return 0;
|
|
29777
29832
|
}
|
|
29778
29833
|
/************************************************************
|
|
29834
|
+
* The records of the table as json, with their metadata: ask
|
|
29835
|
+
* the host for them (it owns the link to the backend). The rows
|
|
29836
|
+
* the table holds were read WITHOUT metadata, so they cannot
|
|
29837
|
+
* answer this themselves.
|
|
29838
|
+
************************************************************/
|
|
29839
|
+
function ac_show_table_json(gobj, event, kw, src) {
|
|
29840
|
+
(0, _yuneta_gobj_js.gobj_publish_event)(gobj, "EV_REQUEST_JSON", { topic_name: (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "topic_name") });
|
|
29841
|
+
return 0;
|
|
29842
|
+
}
|
|
29843
|
+
/************************************************************
|
|
29844
|
+
* The host's answer: the topic's records with metadata. What is
|
|
29845
|
+
* shown is what the TABLE shows: when a filter or the search
|
|
29846
|
+
* leaves some rows out, only the records of the rows left in
|
|
29847
|
+
* (matched by id) are kept.
|
|
29848
|
+
************************************************************/
|
|
29849
|
+
function ac_json_loaded(gobj, event, kw, src) {
|
|
29850
|
+
let records = kw && Array.isArray(kw.rows) ? kw.rows : [];
|
|
29851
|
+
let tabulator = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "tabulator");
|
|
29852
|
+
if (tabulator) try {
|
|
29853
|
+
let active = tabulator.getData("active");
|
|
29854
|
+
if (active.length < tabulator.getDataCount()) {
|
|
29855
|
+
let ids = new Set(active.map((r) => String(r.id)));
|
|
29856
|
+
records = records.filter((r) => ids.has(String(r && r.id)));
|
|
29857
|
+
}
|
|
29858
|
+
} catch (e) {
|
|
29859
|
+
(0, _yuneta_gobj_js.log_warning)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: cannot read the active rows: ${e}`);
|
|
29860
|
+
}
|
|
29861
|
+
open_table_json_dialog(gobj, records);
|
|
29862
|
+
return 0;
|
|
29863
|
+
}
|
|
29864
|
+
/************************************************************
|
|
29865
|
+
* Show the table's records in the adaptive json popup (a
|
|
29866
|
+
* window on a laptop, a sheet on a phone). One at a time: a
|
|
29867
|
+
* second open replaces the first.
|
|
29868
|
+
************************************************************/
|
|
29869
|
+
function open_table_json_dialog(gobj, records) {
|
|
29870
|
+
close_table_json_dialog(gobj);
|
|
29871
|
+
let priv = gobj.priv;
|
|
29872
|
+
let json_view = (0, _yuneta_gobj_js.gobj_create_pure_child)("tablejson_" + (0, _yuneta_gobj_js.clean_name)((0, _yuneta_gobj_js.gobj_name)(gobj)), "C_YUI_JSON", {}, gobj);
|
|
29873
|
+
if (!json_view) {
|
|
29874
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: cannot create the table json viewer`);
|
|
29875
|
+
return;
|
|
29876
|
+
}
|
|
29877
|
+
priv.table_json_gobj = json_view;
|
|
29878
|
+
(0, _yuneta_gobj_js.gobj_start)(json_view);
|
|
29879
|
+
let $box = (0, _yuneta_gobj_js.gobj_read_attr)(json_view, "$container");
|
|
29880
|
+
if (!$box) {
|
|
29881
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: the table json viewer built no $container`);
|
|
29882
|
+
teardown_table_json_child(gobj);
|
|
29883
|
+
return;
|
|
29884
|
+
}
|
|
29885
|
+
let presented = present_json_popup(gobj, $box, {
|
|
29886
|
+
name: "tablejsonwin_" + (0, _yuneta_gobj_js.clean_name)((0, _yuneta_gobj_js.gobj_name)(gobj)),
|
|
29887
|
+
logical_class: "TREEDB_TABLE_JSON",
|
|
29888
|
+
title_prefix: (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "topic_name"),
|
|
29889
|
+
title: "raw json",
|
|
29890
|
+
icon: "yi-eye",
|
|
29891
|
+
forget_window: function() {
|
|
29892
|
+
priv.table_json_win = null;
|
|
29893
|
+
},
|
|
29894
|
+
on_close: function() {
|
|
29895
|
+
teardown_table_json_child(gobj);
|
|
29896
|
+
}
|
|
29897
|
+
});
|
|
29898
|
+
if (!presented) {
|
|
29899
|
+
teardown_table_json_child(gobj);
|
|
29900
|
+
return;
|
|
29901
|
+
}
|
|
29902
|
+
priv.table_json_modal = presented.modal;
|
|
29903
|
+
priv.table_json_win = presented.win;
|
|
29904
|
+
(0, _yuneta_gobj_js.gobj_send_event)(json_view, "EV_SET_JSON", { json: records }, gobj);
|
|
29905
|
+
}
|
|
29906
|
+
/************************************************************
|
|
29907
|
+
* Destroy the hosted C_YUI_JSON child of the table json.
|
|
29908
|
+
************************************************************/
|
|
29909
|
+
function teardown_table_json_child(gobj) {
|
|
29910
|
+
let priv = gobj.priv;
|
|
29911
|
+
if (priv.table_json_gobj) {
|
|
29912
|
+
if ((0, _yuneta_gobj_js.gobj_is_running)(priv.table_json_gobj)) (0, _yuneta_gobj_js.gobj_stop)(priv.table_json_gobj);
|
|
29913
|
+
(0, _yuneta_gobj_js.gobj_destroy)(priv.table_json_gobj);
|
|
29914
|
+
priv.table_json_gobj = null;
|
|
29915
|
+
}
|
|
29916
|
+
let win = priv.table_json_win;
|
|
29917
|
+
priv.table_json_win = null;
|
|
29918
|
+
retire_popup_window(win);
|
|
29919
|
+
priv.table_json_modal = null;
|
|
29920
|
+
}
|
|
29921
|
+
/************************************************************
|
|
29922
|
+
* Close the table json dialog (teardown, or a second open).
|
|
29923
|
+
************************************************************/
|
|
29924
|
+
function close_table_json_dialog(gobj) {
|
|
29925
|
+
let priv = gobj.priv;
|
|
29926
|
+
if (priv.table_json_modal) {
|
|
29927
|
+
let modal = priv.table_json_modal;
|
|
29928
|
+
priv.table_json_modal = null;
|
|
29929
|
+
modal.close();
|
|
29930
|
+
return;
|
|
29931
|
+
}
|
|
29932
|
+
teardown_table_json_child(gobj);
|
|
29933
|
+
}
|
|
29934
|
+
/************************************************************
|
|
29779
29935
|
* {
|
|
29780
29936
|
* href: href
|
|
29781
29937
|
* }
|
|
@@ -30014,6 +30170,16 @@ function create_gclass$5(gclass_name) {
|
|
|
30014
30170
|
ac_export_table,
|
|
30015
30171
|
null
|
|
30016
30172
|
],
|
|
30173
|
+
[
|
|
30174
|
+
"EV_SHOW_TABLE_JSON",
|
|
30175
|
+
ac_show_table_json,
|
|
30176
|
+
null
|
|
30177
|
+
],
|
|
30178
|
+
[
|
|
30179
|
+
"EV_JSON_LOADED",
|
|
30180
|
+
ac_json_loaded,
|
|
30181
|
+
null
|
|
30182
|
+
],
|
|
30017
30183
|
[
|
|
30018
30184
|
"EV_SHOW",
|
|
30019
30185
|
ac_show$4,
|
|
@@ -30071,6 +30237,9 @@ function create_gclass$5(gclass_name) {
|
|
|
30071
30237
|
["EV_EDIT_RECORD", 0],
|
|
30072
30238
|
["EV_TOGGLE_COLUMN", 0],
|
|
30073
30239
|
["EV_EXPORT_TABLE", 0],
|
|
30240
|
+
["EV_SHOW_TABLE_JSON", 0],
|
|
30241
|
+
["EV_JSON_LOADED", 0],
|
|
30242
|
+
["EV_REQUEST_JSON", _yuneta_gobj_js.event_flag_t.EVF_OUTPUT_EVENT],
|
|
30074
30243
|
["EV_CREATE_RECORD", _yuneta_gobj_js.event_flag_t.EVF_OUTPUT_EVENT],
|
|
30075
30244
|
["EV_UPDATE_RECORD", _yuneta_gobj_js.event_flag_t.EVF_OUTPUT_EVENT],
|
|
30076
30245
|
["EV_DELETE_RECORD", _yuneta_gobj_js.event_flag_t.EVF_OUTPUT_EVENT],
|
|
@@ -76385,9 +76554,14 @@ function ensure_dev_style() {
|
|
|
76385
76554
|
flex: 0 0 auto; display: flex; flex-wrap: wrap; gap: 14px;
|
|
76386
76555
|
padding: 6px 10px; border-top: 1px solid rgba(0,0,0,0.1);
|
|
76387
76556
|
background: rgba(0,0,0,0.03);
|
|
76388
|
-
font-family: "DejaVu Sans Mono", monospace; font-size:
|
|
76557
|
+
font-family: "DejaVu Sans Mono", monospace; font-size: 0.875rem;
|
|
76389
76558
|
opacity: 0.9; font-variant-numeric: tabular-nums;
|
|
76390
76559
|
}
|
|
76560
|
+
/* Sizes in rem, not px: they follow the reader's zoom and root size. The
|
|
76561
|
+
controls (chips, segments, search) are at 1rem with a finger's padding --
|
|
76562
|
+
this window used to be all 9-13px, controls included, which is what
|
|
76563
|
+
is-small is not for. Only secondary ink (source, size/time, the
|
|
76564
|
+
uppercase labels) goes under 0.9rem. (No backticks: template literal.) */
|
|
76391
76565
|
/* -------- control bar -------- */
|
|
76392
76566
|
.YDEV_BAR {
|
|
76393
76567
|
display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px;
|
|
@@ -76396,12 +76570,12 @@ function ensure_dev_style() {
|
|
|
76396
76570
|
}
|
|
76397
76571
|
.YDEV_GROUP { display: inline-flex; align-items: center; gap: 5px; }
|
|
76398
76572
|
.YDEV_LABEL {
|
|
76399
|
-
font-size:
|
|
76400
|
-
opacity: 0.
|
|
76573
|
+
font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.08em;
|
|
76574
|
+
opacity: 0.6; align-self: center;
|
|
76401
76575
|
}
|
|
76402
76576
|
.YDEV_SEP { width: 1px; align-self: stretch; background: rgba(0,0,0,0.12); }
|
|
76403
76577
|
.YDEV_CHIP {
|
|
76404
|
-
font: inherit; font-size:
|
|
76578
|
+
font: inherit; font-size: 1rem; line-height: 1.4; padding: 0.4rem 0.8rem;
|
|
76405
76579
|
border: 1px solid rgba(0,0,0,0.18); border-radius: 999px;
|
|
76406
76580
|
background: transparent; color: inherit; cursor: pointer;
|
|
76407
76581
|
display: inline-flex; align-items: center; gap: 5px;
|
|
@@ -76414,14 +76588,14 @@ function ensure_dev_style() {
|
|
|
76414
76588
|
.YDEV_CHIP[data-dir]:not(.is-active) { opacity: 0.4; text-decoration: line-through; }
|
|
76415
76589
|
.YDEV_SEG { display: inline-flex; border: 1px solid rgba(0,0,0,0.18); border-radius: 7px; overflow: hidden; }
|
|
76416
76590
|
.YDEV_SEG_BTN {
|
|
76417
|
-
font: inherit; font-size:
|
|
76591
|
+
font: inherit; font-size: 1rem; padding: 0.4rem 0.85rem; border: 0;
|
|
76418
76592
|
border-right: 1px solid rgba(0,0,0,0.12);
|
|
76419
76593
|
background: transparent; color: inherit; cursor: pointer;
|
|
76420
76594
|
}
|
|
76421
76595
|
.YDEV_SEG_BTN:last-child { border-right: 0; }
|
|
76422
76596
|
.YDEV_SEG_BTN.is-active { background: #2563eb; color: #fff; font-weight: 600; }
|
|
76423
76597
|
.YDEV_SEARCH {
|
|
76424
|
-
font: inherit; font-size:
|
|
76598
|
+
font: inherit; font-size: 1rem; padding: 0.4rem 0.7rem; min-width: 13rem;
|
|
76425
76599
|
border: 1px solid rgba(0,0,0,0.18); border-radius: 7px;
|
|
76426
76600
|
background: transparent; color: inherit;
|
|
76427
76601
|
}
|
|
@@ -76430,7 +76604,7 @@ function ensure_dev_style() {
|
|
|
76430
76604
|
.YDEV_STAT.is-strong { font-weight: 700; }
|
|
76431
76605
|
.YDEV_TITLE { display: flex; align-items: baseline; gap: 8px; }
|
|
76432
76606
|
.YDEV_TITLE_MAIN { font-weight: 700; }
|
|
76433
|
-
.YDEV_TITLE_SUB { opacity: 0.7; font-size:
|
|
76607
|
+
.YDEV_TITLE_SUB { opacity: 0.7; font-size: 0.875rem; }
|
|
76434
76608
|
/* The ink of the log.
|
|
76435
76609
|
*
|
|
76436
76610
|
* It used to be one grey dimmed with opacity per role -- 0.85 for a key,
|
|
@@ -76469,7 +76643,7 @@ function ensure_dev_style() {
|
|
|
76469
76643
|
/* -------- entries (shared) -------- */
|
|
76470
76644
|
.TRAFFIC_ENTRY {
|
|
76471
76645
|
border-left: 3px solid #94a3b8; border-radius: 3px;
|
|
76472
|
-
font-family: "DejaVu Sans Mono", monospace, consolas, monaco; font-size:
|
|
76646
|
+
font-family: "DejaVu Sans Mono", monospace, consolas, monaco; font-size: 0.9375rem;
|
|
76473
76647
|
background: rgba(0,0,0,0.02);
|
|
76474
76648
|
}
|
|
76475
76649
|
.TRAFFIC_ENTRY { margin: 6px 0; padding: 4px 8px; line-height: 1.55; }
|
|
@@ -76483,18 +76657,18 @@ function ensure_dev_style() {
|
|
|
76483
76657
|
/* Where the message went through. min-width 0 and flex 0 1 auto so it is the
|
|
76484
76658
|
part that gives way when the row runs out of width -- the event name and
|
|
76485
76659
|
the size/time must not be the ones to go. */
|
|
76486
|
-
.TRAFFIC_SRC { color: var(--ydev-src); font-size:
|
|
76660
|
+
.TRAFFIC_SRC { color: var(--ydev-src); font-size: 0.8125rem; flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
76487
76661
|
.dir-out .TRAFFIC_ARROW, .dir-out .TRAFFIC_EVENT { color: #2563eb; }
|
|
76488
76662
|
.dir-in .TRAFFIC_ARROW, .dir-in .TRAFFIC_EVENT { color: #059669; }
|
|
76489
76663
|
.dir-err .TRAFFIC_ARROW, .dir-err .TRAFFIC_EVENT { color: #dc2626; }
|
|
76490
|
-
.TRAFFIC_META { margin-left: auto; color: var(--ydev-dim); font-size:
|
|
76664
|
+
.TRAFFIC_META { margin-left: auto; color: var(--ydev-dim); font-size: 0.8125rem; white-space: nowrap; }
|
|
76491
76665
|
/* The indent of a nested block is NOT a hover effect: it used to be given
|
|
76492
76666
|
only on .TRAFFIC_ENTRY:hover, so moving the cursor across the log made
|
|
76493
76667
|
every payload under it jump 16px sideways and reflow. A payload being
|
|
76494
76668
|
read must not move because the pointer passed over it.
|
|
76495
76669
|
(No backticks in here: this stylesheet is a template literal.) */
|
|
76496
76670
|
.TRAFFIC_KW { margin: 2px 0 0 16px; }
|
|
76497
|
-
.TRAFFIC_FULL { margin: 4px 0 0 16px; padding: 6px 8px; font-family: monospace; font-size:
|
|
76671
|
+
.TRAFFIC_FULL { margin: 4px 0 0 16px; padding: 6px 8px; font-family: monospace; font-size: 0.875rem; line-height: 1.45; white-space: pre-wrap; word-break: break-word; background: rgba(0,0,0,0.04); border-radius: 4px; overflow-x: auto; }
|
|
76498
76672
|
.TRAFFIC_ROW { display: flex; gap: 6px; align-items: baseline; }
|
|
76499
76673
|
.TRAFFIC_BULLET { color: var(--ydev-bullet); flex: 0 0 auto; }
|
|
76500
76674
|
.TRAFFIC_KEY { color: var(--ydev-key); flex: 0 0 auto; }
|
|
@@ -76519,17 +76693,17 @@ details.TRAFFIC_NEST > summary::-webkit-details-marker { display: none; }
|
|
|
76519
76693
|
.TRAFFIC_PREV.t-bool { color: var(--ydev-bool); }
|
|
76520
76694
|
.TRAFFIC_PREV.t-null { color: var(--ydev-bool); font-style: italic; }
|
|
76521
76695
|
.TRAFFIC_PREV.t-empty { color: var(--ydev-dim); }
|
|
76522
|
-
.YDEV_EMPTY { color: var(--ydev-dim); font-size:
|
|
76696
|
+
.YDEV_EMPTY { color: var(--ydev-dim); font-size: 0.875rem; padding: 18px 10px; text-align: center; }
|
|
76523
76697
|
/* -------- mirrored console logs (error/warning/info/debug/msg; the automata trace shows as debug) -------- */
|
|
76524
|
-
.YDEV_LOGROW { display: flex; align-items: baseline; gap: 8px; margin: 1px 0; padding: 2px 8px; border-left: 3px solid #94a3b8; border-radius: 3px; font-family: "DejaVu Sans Mono", monospace, consolas, monaco; font-size:
|
|
76525
|
-
.YDEV_LOG_LVL { flex: 0 0 auto; text-transform: uppercase; font-size:
|
|
76698
|
+
.YDEV_LOGROW { display: flex; align-items: baseline; gap: 8px; margin: 1px 0; padding: 2px 8px; border-left: 3px solid #94a3b8; border-radius: 3px; font-family: "DejaVu Sans Mono", monospace, consolas, monaco; font-size: 0.9375rem; background: rgba(0,0,0,0.015); }
|
|
76699
|
+
.YDEV_LOG_LVL { flex: 0 0 auto; text-transform: uppercase; font-size: 0.75rem; font-weight: 700; letter-spacing: 0.04em; color: var(--ydev-dim); min-width: 4.5rem; }
|
|
76526
76700
|
.YDEV_LOG_TXT { flex: 1 1 auto; min-width: 0; white-space: pre-wrap; word-break: break-word; color: var(--ydev-ink); }
|
|
76527
76701
|
.YDEV_LOG_error { border-left-color: #dc2626; } .YDEV_LOG_error .YDEV_LOG_LVL { color: #dc2626; }
|
|
76528
76702
|
.YDEV_LOG_warning { border-left-color: #d97706; } .YDEV_LOG_warning .YDEV_LOG_LVL { color: #d97706; }
|
|
76529
76703
|
.YDEV_LOG_info { border-left-color: #2563eb; } .YDEV_LOG_info .YDEV_LOG_LVL { color: #2563eb; }
|
|
76530
76704
|
.YDEV_LOG_msg { border-left-color: #0891b2; } .YDEV_LOG_msg .YDEV_LOG_LVL { color: #0891b2; }
|
|
76531
76705
|
.YDEV_LOG_debug { border-left-color: #94a3b8; } .YDEV_LOG_debug .YDEV_LOG_LVL { color: #94a3b8; } .YDEV_LOG_debug .YDEV_LOG_TXT { color: var(--ydev-dim); }
|
|
76532
|
-
.YDEV_LOG_json { border-left-color: #9333ea; align-items: flex-start; } .YDEV_LOG_json .YDEV_LOG_LVL { color: #9333ea; } .YDEV_LOG_json .YDEV_LOG_TXT { font-size:
|
|
76706
|
+
.YDEV_LOG_json { border-left-color: #9333ea; align-items: flex-start; } .YDEV_LOG_json .YDEV_LOG_LVL { color: #9333ea; } .YDEV_LOG_json .YDEV_LOG_TXT { font-size: 0.875rem; line-height: 1.4; color: var(--ydev-dim); }
|
|
76533
76707
|
/* -------- dark theme -------- */
|
|
76534
76708
|
:root[data-theme="dark"] .TRAFFIC_FULL { background: rgba(255,255,255,0.05); }
|
|
76535
76709
|
:root[data-theme="dark"] .YDEV_BAR, :root[data-theme="dark"] .YDEV_STATS { background: rgba(255,255,255,0.04); }
|
package/dist/gobj-ui.es.js
CHANGED
|
@@ -24635,7 +24635,7 @@ function get_gobj_formtable(gobj, topic_name) {
|
|
|
24635
24635
|
/************************************************************
|
|
24636
24636
|
* Command to remote service
|
|
24637
24637
|
************************************************************/
|
|
24638
|
-
function treedb_nodes$1(gobj, treedb_name, topic_name, options, page) {
|
|
24638
|
+
function treedb_nodes$1(gobj, treedb_name, topic_name, options, page, purpose) {
|
|
24639
24639
|
let command = "nodes";
|
|
24640
24640
|
let gobj_remote_yuno = gobj_read_pointer_attr(gobj, "gobj_remote_yuno");
|
|
24641
24641
|
let kw = {
|
|
@@ -24645,6 +24645,7 @@ function treedb_nodes$1(gobj, treedb_name, topic_name, options, page) {
|
|
|
24645
24645
|
options: options || {}
|
|
24646
24646
|
};
|
|
24647
24647
|
kw.__md_command__ = { topic_name };
|
|
24648
|
+
if (purpose) kw.__md_command__.purpose = purpose;
|
|
24648
24649
|
if (page) {
|
|
24649
24650
|
kw.from = page.from;
|
|
24650
24651
|
kw.limit = page.limit;
|
|
@@ -24926,7 +24927,8 @@ function ac_mt_command_answer$2(gobj, event, kw, src) {
|
|
|
24926
24927
|
let gobj_topic_form = gobj_find_child(gobj, { __gobj_name__: `${gobj_name(gobj)}?${topic_name}` });
|
|
24927
24928
|
let answer = nodes_answer(data);
|
|
24928
24929
|
let req_id = kw_get_str(gobj, kw_command, "req_id", "", 0);
|
|
24929
|
-
if (
|
|
24930
|
+
if (kw_get_str(gobj, kw_command, "purpose", "", 0) === "json") gobj_send_event(gobj_topic_form, "EV_JSON_LOADED", { rows: answer.rows }, gobj);
|
|
24931
|
+
else if (req_id) gobj_send_event(gobj_topic_form, "EV_PAGE_LOADED", {
|
|
24930
24932
|
req_id,
|
|
24931
24933
|
rows: answer.rows,
|
|
24932
24934
|
pages: answer.pages,
|
|
@@ -25170,6 +25172,20 @@ function ac_create_record(gobj, event, kw, src) {
|
|
|
25170
25172
|
});
|
|
25171
25173
|
}
|
|
25172
25174
|
/********************************************
|
|
25175
|
+
* A topic table wants its records as json, WITH the metadata of
|
|
25176
|
+
* each one (its Raw JSON button). The table's own rows are read
|
|
25177
|
+
* without it, so this is a read of its own: the whole topic, and
|
|
25178
|
+
* the table keeps to the rows it shows.
|
|
25179
|
+
********************************************/
|
|
25180
|
+
function ac_request_json(gobj, event, kw, src) {
|
|
25181
|
+
let topic_name = kw.topic_name || gobj_read_attr(src, "topic_name");
|
|
25182
|
+
if (!topic_name) {
|
|
25183
|
+
log_error(`${gobj_short_name(gobj)}: a json request with no topic`);
|
|
25184
|
+
return -1;
|
|
25185
|
+
}
|
|
25186
|
+
return treedb_nodes$1(gobj, gobj_read_str_attr(gobj, "treedb_name"), topic_name, Object.assign({}, TABLE_READ_OPTIONS, { with_metadata: true }), null, "json");
|
|
25187
|
+
}
|
|
25188
|
+
/********************************************
|
|
25173
25189
|
* A topic table wants a page.
|
|
25174
25190
|
*
|
|
25175
25191
|
* The transport is ours, so the table asks and we fetch; the answer
|
|
@@ -25453,6 +25469,11 @@ function create_gclass$6(gclass_name) {
|
|
|
25453
25469
|
ac_request_page,
|
|
25454
25470
|
null
|
|
25455
25471
|
],
|
|
25472
|
+
[
|
|
25473
|
+
"EV_REQUEST_JSON",
|
|
25474
|
+
ac_request_json,
|
|
25475
|
+
null
|
|
25476
|
+
],
|
|
25456
25477
|
[
|
|
25457
25478
|
"EV_REQUEST_ASSET",
|
|
25458
25479
|
ac_request_asset,
|
|
@@ -25543,6 +25564,7 @@ function create_gclass$6(gclass_name) {
|
|
|
25543
25564
|
["EV_UPDATE_RECORD", 0],
|
|
25544
25565
|
["EV_UPDATE_FIELD", 0],
|
|
25545
25566
|
["EV_REQUEST_PAGE", 0],
|
|
25567
|
+
["EV_REQUEST_JSON", 0],
|
|
25546
25568
|
["EV_REQUEST_ASSET", 0],
|
|
25547
25569
|
["EV_OPEN_LINKED", 0],
|
|
25548
25570
|
["EV_DELETE_RECORD", 0],
|
|
@@ -26354,6 +26376,7 @@ var attrs_table$5 = [
|
|
|
26354
26376
|
SDATA(data_type_t.DTP_BOOLEAN, "with_search_button", 0, true, "Button toolbar SEARCH"),
|
|
26355
26377
|
SDATA(data_type_t.DTP_BOOLEAN, "with_schema_button", 0, true, "Button toolbar SCHEMA (show the topic's desc)"),
|
|
26356
26378
|
SDATA(data_type_t.DTP_BOOLEAN, "with_columns_button", 0, true, "Button toolbar COLUMNS (choose which columns the table shows)"),
|
|
26379
|
+
SDATA(data_type_t.DTP_BOOLEAN, "with_json_button", 0, true, "Button toolbar RAW JSON (the table's records as json, with the metadata of each record)"),
|
|
26357
26380
|
SDATA(data_type_t.DTP_BOOLEAN, "with_export_button", 0, true, "Button toolbar EXPORT (download as CSV what the table holds)"),
|
|
26358
26381
|
SDATA(data_type_t.DTP_BOOLEAN, "with_header_filters", 0, true, "Per-column filter box in the table header, on the columns a text/number match means something (not hooks, fkeys or json)"),
|
|
26359
26382
|
SDATA(data_type_t.DTP_BOOLEAN, "with_inline_edit", 0, true, "Edit a writable scalar cell in place while in edition mode (the record form keeps the rest)"),
|
|
@@ -26404,6 +26427,9 @@ var PRIVATE_DATA$5 = {
|
|
|
26404
26427
|
schema_win: null,
|
|
26405
26428
|
cell_json_gobj: null,
|
|
26406
26429
|
cell_json_modal: null,
|
|
26430
|
+
table_json_gobj: null,
|
|
26431
|
+
table_json_win: null,
|
|
26432
|
+
table_json_modal: null,
|
|
26407
26433
|
cell_json_win: null,
|
|
26408
26434
|
cell_file_box: null,
|
|
26409
26435
|
cell_file_modal: null,
|
|
@@ -26546,6 +26572,7 @@ function mt_stop$5(gobj) {
|
|
|
26546
26572
|
close_form_dialog(gobj);
|
|
26547
26573
|
close_schema_dialog(gobj);
|
|
26548
26574
|
close_cell_json_dialog(gobj);
|
|
26575
|
+
close_table_json_dialog(gobj);
|
|
26549
26576
|
close_cell_file_dialog(gobj);
|
|
26550
26577
|
close_hook_choice(gobj);
|
|
26551
26578
|
drop_pending_assets(gobj);
|
|
@@ -26558,6 +26585,7 @@ function mt_destroy$5(gobj) {
|
|
|
26558
26585
|
close_form_dialog(gobj);
|
|
26559
26586
|
close_schema_dialog(gobj);
|
|
26560
26587
|
close_cell_json_dialog(gobj);
|
|
26588
|
+
close_table_json_dialog(gobj);
|
|
26561
26589
|
close_cell_file_dialog(gobj);
|
|
26562
26590
|
close_hook_choice(gobj);
|
|
26563
26591
|
drop_pending_assets(gobj);
|
|
@@ -26787,6 +26815,7 @@ function build_ui$5(gobj) {
|
|
|
26787
26815
|
let with_search_button = gobj_read_bool_attr(gobj, "with_search_button");
|
|
26788
26816
|
let with_schema_button = gobj_read_bool_attr(gobj, "with_schema_button");
|
|
26789
26817
|
let with_columns_button = gobj_read_bool_attr(gobj, "with_columns_button");
|
|
26818
|
+
let with_json_button = gobj_read_bool_attr(gobj, "with_json_button");
|
|
26790
26819
|
let with_export_button = gobj_read_bool_attr(gobj, "with_export_button");
|
|
26791
26820
|
if (with_search_button) {
|
|
26792
26821
|
let search_id = `${toolbar_id}_search`;
|
|
@@ -26894,6 +26923,32 @@ function build_ui$5(gobj) {
|
|
|
26894
26923
|
]);
|
|
26895
26924
|
$view_toolbar.appendChild($columns);
|
|
26896
26925
|
}
|
|
26926
|
+
if (with_json_button) {
|
|
26927
|
+
let $json = createElement2([
|
|
26928
|
+
"button",
|
|
26929
|
+
{
|
|
26930
|
+
class: "TREEDB_TABLE_JSON button mr-1",
|
|
26931
|
+
title: t("raw json"),
|
|
26932
|
+
"data-i18n-title": "raw json",
|
|
26933
|
+
"aria-label": t("raw json"),
|
|
26934
|
+
"data-i18n-aria-label": "raw json"
|
|
26935
|
+
},
|
|
26936
|
+
[yui_toolbar_icon("yi-eye"), [
|
|
26937
|
+
"span",
|
|
26938
|
+
{
|
|
26939
|
+
class: "is-hidden-mobile",
|
|
26940
|
+
i18n: "raw json",
|
|
26941
|
+
style: "padding-left:5px;"
|
|
26942
|
+
},
|
|
26943
|
+
"raw json"
|
|
26944
|
+
]],
|
|
26945
|
+
{ "click": (event) => {
|
|
26946
|
+
event.stopPropagation();
|
|
26947
|
+
gobj_send_event(gobj, "EV_SHOW_TABLE_JSON", {}, gobj);
|
|
26948
|
+
} }
|
|
26949
|
+
]);
|
|
26950
|
+
$view_toolbar.appendChild($json);
|
|
26951
|
+
}
|
|
26897
26952
|
if (with_export_button) {
|
|
26898
26953
|
let $export = createElement2([
|
|
26899
26954
|
"button",
|
|
@@ -29771,6 +29826,107 @@ function ac_export_table(gobj, event, kw, src) {
|
|
|
29771
29826
|
return 0;
|
|
29772
29827
|
}
|
|
29773
29828
|
/************************************************************
|
|
29829
|
+
* The records of the table as json, with their metadata: ask
|
|
29830
|
+
* the host for them (it owns the link to the backend). The rows
|
|
29831
|
+
* the table holds were read WITHOUT metadata, so they cannot
|
|
29832
|
+
* answer this themselves.
|
|
29833
|
+
************************************************************/
|
|
29834
|
+
function ac_show_table_json(gobj, event, kw, src) {
|
|
29835
|
+
gobj_publish_event(gobj, "EV_REQUEST_JSON", { topic_name: gobj_read_str_attr(gobj, "topic_name") });
|
|
29836
|
+
return 0;
|
|
29837
|
+
}
|
|
29838
|
+
/************************************************************
|
|
29839
|
+
* The host's answer: the topic's records with metadata. What is
|
|
29840
|
+
* shown is what the TABLE shows: when a filter or the search
|
|
29841
|
+
* leaves some rows out, only the records of the rows left in
|
|
29842
|
+
* (matched by id) are kept.
|
|
29843
|
+
************************************************************/
|
|
29844
|
+
function ac_json_loaded(gobj, event, kw, src) {
|
|
29845
|
+
let records = kw && Array.isArray(kw.rows) ? kw.rows : [];
|
|
29846
|
+
let tabulator = gobj_read_attr(gobj, "tabulator");
|
|
29847
|
+
if (tabulator) try {
|
|
29848
|
+
let active = tabulator.getData("active");
|
|
29849
|
+
if (active.length < tabulator.getDataCount()) {
|
|
29850
|
+
let ids = new Set(active.map((r) => String(r.id)));
|
|
29851
|
+
records = records.filter((r) => ids.has(String(r && r.id)));
|
|
29852
|
+
}
|
|
29853
|
+
} catch (e) {
|
|
29854
|
+
log_warning(`${gobj_short_name(gobj)}: cannot read the active rows: ${e}`);
|
|
29855
|
+
}
|
|
29856
|
+
open_table_json_dialog(gobj, records);
|
|
29857
|
+
return 0;
|
|
29858
|
+
}
|
|
29859
|
+
/************************************************************
|
|
29860
|
+
* Show the table's records in the adaptive json popup (a
|
|
29861
|
+
* window on a laptop, a sheet on a phone). One at a time: a
|
|
29862
|
+
* second open replaces the first.
|
|
29863
|
+
************************************************************/
|
|
29864
|
+
function open_table_json_dialog(gobj, records) {
|
|
29865
|
+
close_table_json_dialog(gobj);
|
|
29866
|
+
let priv = gobj.priv;
|
|
29867
|
+
let json_view = gobj_create_pure_child("tablejson_" + clean_name(gobj_name(gobj)), "C_YUI_JSON", {}, gobj);
|
|
29868
|
+
if (!json_view) {
|
|
29869
|
+
log_error(`${gobj_short_name(gobj)}: cannot create the table json viewer`);
|
|
29870
|
+
return;
|
|
29871
|
+
}
|
|
29872
|
+
priv.table_json_gobj = json_view;
|
|
29873
|
+
gobj_start(json_view);
|
|
29874
|
+
let $box = gobj_read_attr(json_view, "$container");
|
|
29875
|
+
if (!$box) {
|
|
29876
|
+
log_error(`${gobj_short_name(gobj)}: the table json viewer built no $container`);
|
|
29877
|
+
teardown_table_json_child(gobj);
|
|
29878
|
+
return;
|
|
29879
|
+
}
|
|
29880
|
+
let presented = present_json_popup(gobj, $box, {
|
|
29881
|
+
name: "tablejsonwin_" + clean_name(gobj_name(gobj)),
|
|
29882
|
+
logical_class: "TREEDB_TABLE_JSON",
|
|
29883
|
+
title_prefix: gobj_read_str_attr(gobj, "topic_name"),
|
|
29884
|
+
title: "raw json",
|
|
29885
|
+
icon: "yi-eye",
|
|
29886
|
+
forget_window: function() {
|
|
29887
|
+
priv.table_json_win = null;
|
|
29888
|
+
},
|
|
29889
|
+
on_close: function() {
|
|
29890
|
+
teardown_table_json_child(gobj);
|
|
29891
|
+
}
|
|
29892
|
+
});
|
|
29893
|
+
if (!presented) {
|
|
29894
|
+
teardown_table_json_child(gobj);
|
|
29895
|
+
return;
|
|
29896
|
+
}
|
|
29897
|
+
priv.table_json_modal = presented.modal;
|
|
29898
|
+
priv.table_json_win = presented.win;
|
|
29899
|
+
gobj_send_event(json_view, "EV_SET_JSON", { json: records }, gobj);
|
|
29900
|
+
}
|
|
29901
|
+
/************************************************************
|
|
29902
|
+
* Destroy the hosted C_YUI_JSON child of the table json.
|
|
29903
|
+
************************************************************/
|
|
29904
|
+
function teardown_table_json_child(gobj) {
|
|
29905
|
+
let priv = gobj.priv;
|
|
29906
|
+
if (priv.table_json_gobj) {
|
|
29907
|
+
if (gobj_is_running(priv.table_json_gobj)) gobj_stop(priv.table_json_gobj);
|
|
29908
|
+
gobj_destroy(priv.table_json_gobj);
|
|
29909
|
+
priv.table_json_gobj = null;
|
|
29910
|
+
}
|
|
29911
|
+
let win = priv.table_json_win;
|
|
29912
|
+
priv.table_json_win = null;
|
|
29913
|
+
retire_popup_window(win);
|
|
29914
|
+
priv.table_json_modal = null;
|
|
29915
|
+
}
|
|
29916
|
+
/************************************************************
|
|
29917
|
+
* Close the table json dialog (teardown, or a second open).
|
|
29918
|
+
************************************************************/
|
|
29919
|
+
function close_table_json_dialog(gobj) {
|
|
29920
|
+
let priv = gobj.priv;
|
|
29921
|
+
if (priv.table_json_modal) {
|
|
29922
|
+
let modal = priv.table_json_modal;
|
|
29923
|
+
priv.table_json_modal = null;
|
|
29924
|
+
modal.close();
|
|
29925
|
+
return;
|
|
29926
|
+
}
|
|
29927
|
+
teardown_table_json_child(gobj);
|
|
29928
|
+
}
|
|
29929
|
+
/************************************************************
|
|
29774
29930
|
* {
|
|
29775
29931
|
* href: href
|
|
29776
29932
|
* }
|
|
@@ -30009,6 +30165,16 @@ function create_gclass$5(gclass_name) {
|
|
|
30009
30165
|
ac_export_table,
|
|
30010
30166
|
null
|
|
30011
30167
|
],
|
|
30168
|
+
[
|
|
30169
|
+
"EV_SHOW_TABLE_JSON",
|
|
30170
|
+
ac_show_table_json,
|
|
30171
|
+
null
|
|
30172
|
+
],
|
|
30173
|
+
[
|
|
30174
|
+
"EV_JSON_LOADED",
|
|
30175
|
+
ac_json_loaded,
|
|
30176
|
+
null
|
|
30177
|
+
],
|
|
30012
30178
|
[
|
|
30013
30179
|
"EV_SHOW",
|
|
30014
30180
|
ac_show$4,
|
|
@@ -30066,6 +30232,9 @@ function create_gclass$5(gclass_name) {
|
|
|
30066
30232
|
["EV_EDIT_RECORD", 0],
|
|
30067
30233
|
["EV_TOGGLE_COLUMN", 0],
|
|
30068
30234
|
["EV_EXPORT_TABLE", 0],
|
|
30235
|
+
["EV_SHOW_TABLE_JSON", 0],
|
|
30236
|
+
["EV_JSON_LOADED", 0],
|
|
30237
|
+
["EV_REQUEST_JSON", event_flag_t.EVF_OUTPUT_EVENT],
|
|
30069
30238
|
["EV_CREATE_RECORD", event_flag_t.EVF_OUTPUT_EVENT],
|
|
30070
30239
|
["EV_UPDATE_RECORD", event_flag_t.EVF_OUTPUT_EVENT],
|
|
30071
30240
|
["EV_DELETE_RECORD", event_flag_t.EVF_OUTPUT_EVENT],
|
|
@@ -76380,9 +76549,14 @@ function ensure_dev_style() {
|
|
|
76380
76549
|
flex: 0 0 auto; display: flex; flex-wrap: wrap; gap: 14px;
|
|
76381
76550
|
padding: 6px 10px; border-top: 1px solid rgba(0,0,0,0.1);
|
|
76382
76551
|
background: rgba(0,0,0,0.03);
|
|
76383
|
-
font-family: "DejaVu Sans Mono", monospace; font-size:
|
|
76552
|
+
font-family: "DejaVu Sans Mono", monospace; font-size: 0.875rem;
|
|
76384
76553
|
opacity: 0.9; font-variant-numeric: tabular-nums;
|
|
76385
76554
|
}
|
|
76555
|
+
/* Sizes in rem, not px: they follow the reader's zoom and root size. The
|
|
76556
|
+
controls (chips, segments, search) are at 1rem with a finger's padding --
|
|
76557
|
+
this window used to be all 9-13px, controls included, which is what
|
|
76558
|
+
is-small is not for. Only secondary ink (source, size/time, the
|
|
76559
|
+
uppercase labels) goes under 0.9rem. (No backticks: template literal.) */
|
|
76386
76560
|
/* -------- control bar -------- */
|
|
76387
76561
|
.YDEV_BAR {
|
|
76388
76562
|
display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px;
|
|
@@ -76391,12 +76565,12 @@ function ensure_dev_style() {
|
|
|
76391
76565
|
}
|
|
76392
76566
|
.YDEV_GROUP { display: inline-flex; align-items: center; gap: 5px; }
|
|
76393
76567
|
.YDEV_LABEL {
|
|
76394
|
-
font-size:
|
|
76395
|
-
opacity: 0.
|
|
76568
|
+
font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.08em;
|
|
76569
|
+
opacity: 0.6; align-self: center;
|
|
76396
76570
|
}
|
|
76397
76571
|
.YDEV_SEP { width: 1px; align-self: stretch; background: rgba(0,0,0,0.12); }
|
|
76398
76572
|
.YDEV_CHIP {
|
|
76399
|
-
font: inherit; font-size:
|
|
76573
|
+
font: inherit; font-size: 1rem; line-height: 1.4; padding: 0.4rem 0.8rem;
|
|
76400
76574
|
border: 1px solid rgba(0,0,0,0.18); border-radius: 999px;
|
|
76401
76575
|
background: transparent; color: inherit; cursor: pointer;
|
|
76402
76576
|
display: inline-flex; align-items: center; gap: 5px;
|
|
@@ -76409,14 +76583,14 @@ function ensure_dev_style() {
|
|
|
76409
76583
|
.YDEV_CHIP[data-dir]:not(.is-active) { opacity: 0.4; text-decoration: line-through; }
|
|
76410
76584
|
.YDEV_SEG { display: inline-flex; border: 1px solid rgba(0,0,0,0.18); border-radius: 7px; overflow: hidden; }
|
|
76411
76585
|
.YDEV_SEG_BTN {
|
|
76412
|
-
font: inherit; font-size:
|
|
76586
|
+
font: inherit; font-size: 1rem; padding: 0.4rem 0.85rem; border: 0;
|
|
76413
76587
|
border-right: 1px solid rgba(0,0,0,0.12);
|
|
76414
76588
|
background: transparent; color: inherit; cursor: pointer;
|
|
76415
76589
|
}
|
|
76416
76590
|
.YDEV_SEG_BTN:last-child { border-right: 0; }
|
|
76417
76591
|
.YDEV_SEG_BTN.is-active { background: #2563eb; color: #fff; font-weight: 600; }
|
|
76418
76592
|
.YDEV_SEARCH {
|
|
76419
|
-
font: inherit; font-size:
|
|
76593
|
+
font: inherit; font-size: 1rem; padding: 0.4rem 0.7rem; min-width: 13rem;
|
|
76420
76594
|
border: 1px solid rgba(0,0,0,0.18); border-radius: 7px;
|
|
76421
76595
|
background: transparent; color: inherit;
|
|
76422
76596
|
}
|
|
@@ -76425,7 +76599,7 @@ function ensure_dev_style() {
|
|
|
76425
76599
|
.YDEV_STAT.is-strong { font-weight: 700; }
|
|
76426
76600
|
.YDEV_TITLE { display: flex; align-items: baseline; gap: 8px; }
|
|
76427
76601
|
.YDEV_TITLE_MAIN { font-weight: 700; }
|
|
76428
|
-
.YDEV_TITLE_SUB { opacity: 0.7; font-size:
|
|
76602
|
+
.YDEV_TITLE_SUB { opacity: 0.7; font-size: 0.875rem; }
|
|
76429
76603
|
/* The ink of the log.
|
|
76430
76604
|
*
|
|
76431
76605
|
* It used to be one grey dimmed with opacity per role -- 0.85 for a key,
|
|
@@ -76464,7 +76638,7 @@ function ensure_dev_style() {
|
|
|
76464
76638
|
/* -------- entries (shared) -------- */
|
|
76465
76639
|
.TRAFFIC_ENTRY {
|
|
76466
76640
|
border-left: 3px solid #94a3b8; border-radius: 3px;
|
|
76467
|
-
font-family: "DejaVu Sans Mono", monospace, consolas, monaco; font-size:
|
|
76641
|
+
font-family: "DejaVu Sans Mono", monospace, consolas, monaco; font-size: 0.9375rem;
|
|
76468
76642
|
background: rgba(0,0,0,0.02);
|
|
76469
76643
|
}
|
|
76470
76644
|
.TRAFFIC_ENTRY { margin: 6px 0; padding: 4px 8px; line-height: 1.55; }
|
|
@@ -76478,18 +76652,18 @@ function ensure_dev_style() {
|
|
|
76478
76652
|
/* Where the message went through. min-width 0 and flex 0 1 auto so it is the
|
|
76479
76653
|
part that gives way when the row runs out of width -- the event name and
|
|
76480
76654
|
the size/time must not be the ones to go. */
|
|
76481
|
-
.TRAFFIC_SRC { color: var(--ydev-src); font-size:
|
|
76655
|
+
.TRAFFIC_SRC { color: var(--ydev-src); font-size: 0.8125rem; flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
76482
76656
|
.dir-out .TRAFFIC_ARROW, .dir-out .TRAFFIC_EVENT { color: #2563eb; }
|
|
76483
76657
|
.dir-in .TRAFFIC_ARROW, .dir-in .TRAFFIC_EVENT { color: #059669; }
|
|
76484
76658
|
.dir-err .TRAFFIC_ARROW, .dir-err .TRAFFIC_EVENT { color: #dc2626; }
|
|
76485
|
-
.TRAFFIC_META { margin-left: auto; color: var(--ydev-dim); font-size:
|
|
76659
|
+
.TRAFFIC_META { margin-left: auto; color: var(--ydev-dim); font-size: 0.8125rem; white-space: nowrap; }
|
|
76486
76660
|
/* The indent of a nested block is NOT a hover effect: it used to be given
|
|
76487
76661
|
only on .TRAFFIC_ENTRY:hover, so moving the cursor across the log made
|
|
76488
76662
|
every payload under it jump 16px sideways and reflow. A payload being
|
|
76489
76663
|
read must not move because the pointer passed over it.
|
|
76490
76664
|
(No backticks in here: this stylesheet is a template literal.) */
|
|
76491
76665
|
.TRAFFIC_KW { margin: 2px 0 0 16px; }
|
|
76492
|
-
.TRAFFIC_FULL { margin: 4px 0 0 16px; padding: 6px 8px; font-family: monospace; font-size:
|
|
76666
|
+
.TRAFFIC_FULL { margin: 4px 0 0 16px; padding: 6px 8px; font-family: monospace; font-size: 0.875rem; line-height: 1.45; white-space: pre-wrap; word-break: break-word; background: rgba(0,0,0,0.04); border-radius: 4px; overflow-x: auto; }
|
|
76493
76667
|
.TRAFFIC_ROW { display: flex; gap: 6px; align-items: baseline; }
|
|
76494
76668
|
.TRAFFIC_BULLET { color: var(--ydev-bullet); flex: 0 0 auto; }
|
|
76495
76669
|
.TRAFFIC_KEY { color: var(--ydev-key); flex: 0 0 auto; }
|
|
@@ -76514,17 +76688,17 @@ details.TRAFFIC_NEST > summary::-webkit-details-marker { display: none; }
|
|
|
76514
76688
|
.TRAFFIC_PREV.t-bool { color: var(--ydev-bool); }
|
|
76515
76689
|
.TRAFFIC_PREV.t-null { color: var(--ydev-bool); font-style: italic; }
|
|
76516
76690
|
.TRAFFIC_PREV.t-empty { color: var(--ydev-dim); }
|
|
76517
|
-
.YDEV_EMPTY { color: var(--ydev-dim); font-size:
|
|
76691
|
+
.YDEV_EMPTY { color: var(--ydev-dim); font-size: 0.875rem; padding: 18px 10px; text-align: center; }
|
|
76518
76692
|
/* -------- mirrored console logs (error/warning/info/debug/msg; the automata trace shows as debug) -------- */
|
|
76519
|
-
.YDEV_LOGROW { display: flex; align-items: baseline; gap: 8px; margin: 1px 0; padding: 2px 8px; border-left: 3px solid #94a3b8; border-radius: 3px; font-family: "DejaVu Sans Mono", monospace, consolas, monaco; font-size:
|
|
76520
|
-
.YDEV_LOG_LVL { flex: 0 0 auto; text-transform: uppercase; font-size:
|
|
76693
|
+
.YDEV_LOGROW { display: flex; align-items: baseline; gap: 8px; margin: 1px 0; padding: 2px 8px; border-left: 3px solid #94a3b8; border-radius: 3px; font-family: "DejaVu Sans Mono", monospace, consolas, monaco; font-size: 0.9375rem; background: rgba(0,0,0,0.015); }
|
|
76694
|
+
.YDEV_LOG_LVL { flex: 0 0 auto; text-transform: uppercase; font-size: 0.75rem; font-weight: 700; letter-spacing: 0.04em; color: var(--ydev-dim); min-width: 4.5rem; }
|
|
76521
76695
|
.YDEV_LOG_TXT { flex: 1 1 auto; min-width: 0; white-space: pre-wrap; word-break: break-word; color: var(--ydev-ink); }
|
|
76522
76696
|
.YDEV_LOG_error { border-left-color: #dc2626; } .YDEV_LOG_error .YDEV_LOG_LVL { color: #dc2626; }
|
|
76523
76697
|
.YDEV_LOG_warning { border-left-color: #d97706; } .YDEV_LOG_warning .YDEV_LOG_LVL { color: #d97706; }
|
|
76524
76698
|
.YDEV_LOG_info { border-left-color: #2563eb; } .YDEV_LOG_info .YDEV_LOG_LVL { color: #2563eb; }
|
|
76525
76699
|
.YDEV_LOG_msg { border-left-color: #0891b2; } .YDEV_LOG_msg .YDEV_LOG_LVL { color: #0891b2; }
|
|
76526
76700
|
.YDEV_LOG_debug { border-left-color: #94a3b8; } .YDEV_LOG_debug .YDEV_LOG_LVL { color: #94a3b8; } .YDEV_LOG_debug .YDEV_LOG_TXT { color: var(--ydev-dim); }
|
|
76527
|
-
.YDEV_LOG_json { border-left-color: #9333ea; align-items: flex-start; } .YDEV_LOG_json .YDEV_LOG_LVL { color: #9333ea; } .YDEV_LOG_json .YDEV_LOG_TXT { font-size:
|
|
76701
|
+
.YDEV_LOG_json { border-left-color: #9333ea; align-items: flex-start; } .YDEV_LOG_json .YDEV_LOG_LVL { color: #9333ea; } .YDEV_LOG_json .YDEV_LOG_TXT { font-size: 0.875rem; line-height: 1.4; color: var(--ydev-dim); }
|
|
76528
76702
|
/* -------- dark theme -------- */
|
|
76529
76703
|
:root[data-theme="dark"] .TRAFFIC_FULL { background: rgba(255,255,255,0.05); }
|
|
76530
76704
|
:root[data-theme="dark"] .YDEV_BAR, :root[data-theme="dark"] .YDEV_STATS { background: rgba(255,255,255,0.04); }
|
package/package.json
CHANGED
|
@@ -199,6 +199,7 @@ SDATA(data_type_t.DTP_BOOLEAN, "with_refresh_button", 0, true, "Button
|
|
|
199
199
|
SDATA(data_type_t.DTP_BOOLEAN, "with_search_button", 0, true, "Button toolbar SEARCH"),
|
|
200
200
|
SDATA(data_type_t.DTP_BOOLEAN, "with_schema_button", 0, true, "Button toolbar SCHEMA (show the topic's desc)"),
|
|
201
201
|
SDATA(data_type_t.DTP_BOOLEAN, "with_columns_button", 0, true, "Button toolbar COLUMNS (choose which columns the table shows)"),
|
|
202
|
+
SDATA(data_type_t.DTP_BOOLEAN, "with_json_button", 0, true, "Button toolbar RAW JSON (the table's records as json, with the metadata of each record)"),
|
|
202
203
|
SDATA(data_type_t.DTP_BOOLEAN, "with_export_button", 0, true, "Button toolbar EXPORT (download as CSV what the table holds)"),
|
|
203
204
|
SDATA(data_type_t.DTP_BOOLEAN, "with_header_filters", 0, true, "Per-column filter box in the table header, on the columns a text/number match means something (not hooks, fkeys or json)"),
|
|
204
205
|
SDATA(data_type_t.DTP_BOOLEAN, "with_inline_edit", 0, true, "Edit a writable scalar cell in place while in edition mode (the record form keeps the rest)"),
|
|
@@ -255,6 +256,9 @@ let PRIVATE_DATA = {
|
|
|
255
256
|
schema_win: null, // C_YUI_WINDOW presenting it (laptop)
|
|
256
257
|
cell_json_gobj: null, // hosted C_YUI_JSON child (while a cell is open)
|
|
257
258
|
cell_json_modal: null, // { close } handle of the cell dialog (phone)
|
|
259
|
+
table_json_gobj: null, // hosted C_YUI_JSON child (while the table json is open)
|
|
260
|
+
table_json_win: null, // C_YUI_WINDOW presenting it (laptop)
|
|
261
|
+
table_json_modal: null, // { close } handle of the table json dialog (phone)
|
|
258
262
|
cell_json_win: null, // C_YUI_WINDOW presenting it (laptop)
|
|
259
263
|
cell_file_box: null, // $box of the file popup (while a file cell is open)
|
|
260
264
|
cell_file_modal: null, // { close } handle of the file dialog (phone)
|
|
@@ -465,6 +469,7 @@ function mt_stop(gobj)
|
|
|
465
469
|
close_form_dialog(gobj);
|
|
466
470
|
close_schema_dialog(gobj);
|
|
467
471
|
close_cell_json_dialog(gobj);
|
|
472
|
+
close_table_json_dialog(gobj);
|
|
468
473
|
close_cell_file_dialog(gobj);
|
|
469
474
|
close_hook_choice(gobj);
|
|
470
475
|
drop_pending_assets(gobj);
|
|
@@ -483,6 +488,7 @@ function mt_destroy(gobj)
|
|
|
483
488
|
close_form_dialog(gobj);
|
|
484
489
|
close_schema_dialog(gobj);
|
|
485
490
|
close_cell_json_dialog(gobj);
|
|
491
|
+
close_table_json_dialog(gobj);
|
|
486
492
|
close_cell_file_dialog(gobj);
|
|
487
493
|
close_hook_choice(gobj);
|
|
488
494
|
drop_pending_assets(gobj);
|
|
@@ -746,6 +752,7 @@ function build_ui(gobj)
|
|
|
746
752
|
let with_search_button = gobj_read_bool_attr(gobj, "with_search_button");
|
|
747
753
|
let with_schema_button = gobj_read_bool_attr(gobj, "with_schema_button");
|
|
748
754
|
let with_columns_button = gobj_read_bool_attr(gobj, "with_columns_button");
|
|
755
|
+
let with_json_button = gobj_read_bool_attr(gobj, "with_json_button");
|
|
749
756
|
let with_export_button = gobj_read_bool_attr(gobj, "with_export_button");
|
|
750
757
|
|
|
751
758
|
if(with_search_button) {
|
|
@@ -818,7 +825,7 @@ function build_ui(gobj)
|
|
|
818
825
|
|
|
819
826
|
/* The ORDER is a contract shared with every table toolbar of the
|
|
820
827
|
* ecosystem: what is particular to this view first (search, schema),
|
|
821
|
-
* then the common block ALWAYS as Refresh, Columns, Export, then Close
|
|
828
|
+
* then the common block ALWAYS as Refresh, Columns, (Raw JSON,) Export, then Close
|
|
822
829
|
* when there is one. A button that moves from view to view has to be
|
|
823
830
|
* looked for every time. */
|
|
824
831
|
if(with_refresh_button) {
|
|
@@ -859,6 +866,27 @@ function build_ui(gobj)
|
|
|
859
866
|
$view_toolbar.appendChild($columns);
|
|
860
867
|
}
|
|
861
868
|
|
|
869
|
+
if(with_json_button) {
|
|
870
|
+
/* The records of the table as json, WITH the metadata of each one
|
|
871
|
+
* (__md_treedb__: rowids, t/tm, tag, pure_node...). The rows the
|
|
872
|
+
* table holds carry no metadata -- it is filtered out of the read
|
|
873
|
+
* that fills it -- so the host asks the backend again, with it. */
|
|
874
|
+
let $json = createElement2(
|
|
875
|
+
['button', {class: 'TREEDB_TABLE_JSON button mr-1',
|
|
876
|
+
title: t('raw json'), 'data-i18n-title': 'raw json',
|
|
877
|
+
'aria-label': t('raw json'), 'data-i18n-aria-label': 'raw json'}, [
|
|
878
|
+
yui_toolbar_icon('yi-eye'),
|
|
879
|
+
['span', {class: 'is-hidden-mobile', i18n: 'raw json', style: 'padding-left:5px;'}, 'raw json']
|
|
880
|
+
], {
|
|
881
|
+
'click': (event) => {
|
|
882
|
+
event.stopPropagation();
|
|
883
|
+
gobj_send_event(gobj, "EV_SHOW_TABLE_JSON", {}, gobj);
|
|
884
|
+
}
|
|
885
|
+
}]
|
|
886
|
+
);
|
|
887
|
+
$view_toolbar.appendChild($json);
|
|
888
|
+
}
|
|
889
|
+
|
|
862
890
|
if(with_export_button) {
|
|
863
891
|
/* What the TABLE holds, filters and column choice applied — not the
|
|
864
892
|
* topic. A server-side dump of every node is not something this view
|
|
@@ -4976,6 +5004,142 @@ function ac_export_table(gobj, event, kw, src)
|
|
|
4976
5004
|
return 0;
|
|
4977
5005
|
}
|
|
4978
5006
|
|
|
5007
|
+
/************************************************************
|
|
5008
|
+
* The records of the table as json, with their metadata: ask
|
|
5009
|
+
* the host for them (it owns the link to the backend). The rows
|
|
5010
|
+
* the table holds were read WITHOUT metadata, so they cannot
|
|
5011
|
+
* answer this themselves.
|
|
5012
|
+
************************************************************/
|
|
5013
|
+
function ac_show_table_json(gobj, event, kw, src)
|
|
5014
|
+
{
|
|
5015
|
+
gobj_publish_event(
|
|
5016
|
+
gobj,
|
|
5017
|
+
"EV_REQUEST_JSON",
|
|
5018
|
+
{
|
|
5019
|
+
topic_name: gobj_read_str_attr(gobj, "topic_name")
|
|
5020
|
+
}
|
|
5021
|
+
);
|
|
5022
|
+
return 0;
|
|
5023
|
+
}
|
|
5024
|
+
|
|
5025
|
+
/************************************************************
|
|
5026
|
+
* The host's answer: the topic's records with metadata. What is
|
|
5027
|
+
* shown is what the TABLE shows: when a filter or the search
|
|
5028
|
+
* leaves some rows out, only the records of the rows left in
|
|
5029
|
+
* (matched by id) are kept.
|
|
5030
|
+
************************************************************/
|
|
5031
|
+
function ac_json_loaded(gobj, event, kw, src)
|
|
5032
|
+
{
|
|
5033
|
+
let records = (kw && Array.isArray(kw.rows)) ? kw.rows : [];
|
|
5034
|
+
|
|
5035
|
+
let tabulator = gobj_read_attr(gobj, "tabulator");
|
|
5036
|
+
if(tabulator) {
|
|
5037
|
+
try {
|
|
5038
|
+
let active = tabulator.getData("active");
|
|
5039
|
+
if(active.length < tabulator.getDataCount()) {
|
|
5040
|
+
let ids = new Set(active.map((r) => String(r.id)));
|
|
5041
|
+
records = records.filter((r) => ids.has(String(r && r.id)));
|
|
5042
|
+
}
|
|
5043
|
+
} catch(e) {
|
|
5044
|
+
log_warning(`${gobj_short_name(gobj)}: cannot read the active rows: ${e}`);
|
|
5045
|
+
}
|
|
5046
|
+
}
|
|
5047
|
+
|
|
5048
|
+
open_table_json_dialog(gobj, records);
|
|
5049
|
+
return 0;
|
|
5050
|
+
}
|
|
5051
|
+
|
|
5052
|
+
/************************************************************
|
|
5053
|
+
* Show the table's records in the adaptive json popup (a
|
|
5054
|
+
* window on a laptop, a sheet on a phone). One at a time: a
|
|
5055
|
+
* second open replaces the first.
|
|
5056
|
+
************************************************************/
|
|
5057
|
+
function open_table_json_dialog(gobj, records)
|
|
5058
|
+
{
|
|
5059
|
+
close_table_json_dialog(gobj);
|
|
5060
|
+
|
|
5061
|
+
let priv = gobj.priv;
|
|
5062
|
+
|
|
5063
|
+
let json_view = gobj_create_pure_child(
|
|
5064
|
+
"tablejson_" + clean_name(gobj_name(gobj)),
|
|
5065
|
+
"C_YUI_JSON",
|
|
5066
|
+
{
|
|
5067
|
+
/* No `title`: the popup header already titles it. */
|
|
5068
|
+
},
|
|
5069
|
+
gobj
|
|
5070
|
+
);
|
|
5071
|
+
if(!json_view) {
|
|
5072
|
+
log_error(`${gobj_short_name(gobj)}: cannot create the table json viewer`);
|
|
5073
|
+
return;
|
|
5074
|
+
}
|
|
5075
|
+
priv.table_json_gobj = json_view;
|
|
5076
|
+
gobj_start(json_view);
|
|
5077
|
+
|
|
5078
|
+
let $box = gobj_read_attr(json_view, "$container");
|
|
5079
|
+
if(!$box) {
|
|
5080
|
+
log_error(`${gobj_short_name(gobj)}: the table json viewer built no $container`);
|
|
5081
|
+
teardown_table_json_child(gobj);
|
|
5082
|
+
return;
|
|
5083
|
+
}
|
|
5084
|
+
|
|
5085
|
+
/* The topic is DATA (the prefix), the title carries its key. */
|
|
5086
|
+
let presented = present_json_popup(gobj, $box, {
|
|
5087
|
+
name: "tablejsonwin_" + clean_name(gobj_name(gobj)),
|
|
5088
|
+
logical_class: "TREEDB_TABLE_JSON",
|
|
5089
|
+
title_prefix: gobj_read_str_attr(gobj, "topic_name"),
|
|
5090
|
+
title: "raw json",
|
|
5091
|
+
icon: "yi-eye",
|
|
5092
|
+
forget_window: function() {
|
|
5093
|
+
priv.table_json_win = null;
|
|
5094
|
+
},
|
|
5095
|
+
on_close: function() {
|
|
5096
|
+
teardown_table_json_child(gobj);
|
|
5097
|
+
}
|
|
5098
|
+
});
|
|
5099
|
+
if(!presented) {
|
|
5100
|
+
teardown_table_json_child(gobj); // Error already logged
|
|
5101
|
+
return;
|
|
5102
|
+
}
|
|
5103
|
+
priv.table_json_modal = presented.modal;
|
|
5104
|
+
priv.table_json_win = presented.win;
|
|
5105
|
+
|
|
5106
|
+
gobj_send_event(json_view, "EV_SET_JSON", {json: records}, gobj);
|
|
5107
|
+
}
|
|
5108
|
+
|
|
5109
|
+
/************************************************************
|
|
5110
|
+
* Destroy the hosted C_YUI_JSON child of the table json.
|
|
5111
|
+
************************************************************/
|
|
5112
|
+
function teardown_table_json_child(gobj)
|
|
5113
|
+
{
|
|
5114
|
+
let priv = gobj.priv;
|
|
5115
|
+
if(priv.table_json_gobj) {
|
|
5116
|
+
if(gobj_is_running(priv.table_json_gobj)) {
|
|
5117
|
+
gobj_stop(priv.table_json_gobj);
|
|
5118
|
+
}
|
|
5119
|
+
gobj_destroy(priv.table_json_gobj);
|
|
5120
|
+
priv.table_json_gobj = null;
|
|
5121
|
+
}
|
|
5122
|
+
let win = priv.table_json_win;
|
|
5123
|
+
priv.table_json_win = null;
|
|
5124
|
+
retire_popup_window(win);
|
|
5125
|
+
priv.table_json_modal = null;
|
|
5126
|
+
}
|
|
5127
|
+
|
|
5128
|
+
/************************************************************
|
|
5129
|
+
* Close the table json dialog (teardown, or a second open).
|
|
5130
|
+
************************************************************/
|
|
5131
|
+
function close_table_json_dialog(gobj)
|
|
5132
|
+
{
|
|
5133
|
+
let priv = gobj.priv;
|
|
5134
|
+
if(priv.table_json_modal) {
|
|
5135
|
+
let modal = priv.table_json_modal;
|
|
5136
|
+
priv.table_json_modal = null;
|
|
5137
|
+
modal.close(); // -> on_close -> teardown_table_json_child
|
|
5138
|
+
return;
|
|
5139
|
+
}
|
|
5140
|
+
teardown_table_json_child(gobj);
|
|
5141
|
+
}
|
|
5142
|
+
|
|
4979
5143
|
/************************************************************
|
|
4980
5144
|
* {
|
|
4981
5145
|
* href: href
|
|
@@ -5075,6 +5239,8 @@ function create_gclass(gclass_name)
|
|
|
5075
5239
|
["EV_EDIT_RECORD", ac_edit_record, null],
|
|
5076
5240
|
["EV_TOGGLE_COLUMN", ac_toggle_column, null],
|
|
5077
5241
|
["EV_EXPORT_TABLE", ac_export_table, null],
|
|
5242
|
+
["EV_SHOW_TABLE_JSON", ac_show_table_json, null],
|
|
5243
|
+
["EV_JSON_LOADED", ac_json_loaded, null],
|
|
5078
5244
|
["EV_SHOW", ac_show, null],
|
|
5079
5245
|
["EV_HIDE", ac_hide, null]
|
|
5080
5246
|
]]
|
|
@@ -5130,6 +5296,9 @@ function create_gclass(gclass_name)
|
|
|
5130
5296
|
["EV_EDIT_RECORD", 0],
|
|
5131
5297
|
["EV_TOGGLE_COLUMN", 0],
|
|
5132
5298
|
["EV_EXPORT_TABLE", 0],
|
|
5299
|
+
["EV_SHOW_TABLE_JSON", 0],
|
|
5300
|
+
["EV_JSON_LOADED", 0],
|
|
5301
|
+
["EV_REQUEST_JSON", event_flag_t.EVF_OUTPUT_EVENT],
|
|
5133
5302
|
|
|
5134
5303
|
["EV_CREATE_RECORD", event_flag_t.EVF_OUTPUT_EVENT],
|
|
5135
5304
|
["EV_UPDATE_RECORD", event_flag_t.EVF_OUTPUT_EVENT],
|
|
@@ -1502,7 +1502,7 @@ function get_gobj_formtable(gobj, topic_name)
|
|
|
1502
1502
|
/************************************************************
|
|
1503
1503
|
* Command to remote service
|
|
1504
1504
|
************************************************************/
|
|
1505
|
-
function treedb_nodes(gobj, treedb_name, topic_name, options, page)
|
|
1505
|
+
function treedb_nodes(gobj, treedb_name, topic_name, options, page, purpose)
|
|
1506
1506
|
{
|
|
1507
1507
|
let command = "nodes";
|
|
1508
1508
|
|
|
@@ -1517,6 +1517,9 @@ function treedb_nodes(gobj, treedb_name, topic_name, options, page)
|
|
|
1517
1517
|
kw.__md_command__ = { // Data to be returned
|
|
1518
1518
|
topic_name: topic_name,
|
|
1519
1519
|
};
|
|
1520
|
+
if(purpose) {
|
|
1521
|
+
kw.__md_command__.purpose = purpose;
|
|
1522
|
+
}
|
|
1520
1523
|
|
|
1521
1524
|
/* A PAGE, when the table asked for one. `from` is 1-based and a
|
|
1522
1525
|
* backend that does not know these two answers the whole list, which
|
|
@@ -2006,7 +2009,19 @@ function ac_mt_command_answer(gobj, event, kw, src)
|
|
|
2006
2009
|
* never travels to the backend as a parameter it does not
|
|
2007
2010
|
* know. */
|
|
2008
2011
|
let req_id = kw_get_str(gobj, kw_command, "req_id", "", 0);
|
|
2009
|
-
|
|
2012
|
+
let purpose = kw_get_str(gobj, kw_command, "purpose", "", 0);
|
|
2013
|
+
if(purpose === "json") {
|
|
2014
|
+
/* The table's Raw JSON: the same records WITH their
|
|
2015
|
+
* metadata, for the viewer -- never for the table,
|
|
2016
|
+
* whose rows must stay metadata-free (they go back to
|
|
2017
|
+
* the backend on a save). */
|
|
2018
|
+
gobj_send_event(
|
|
2019
|
+
gobj_topic_form,
|
|
2020
|
+
"EV_JSON_LOADED",
|
|
2021
|
+
{rows: answer.rows},
|
|
2022
|
+
gobj
|
|
2023
|
+
);
|
|
2024
|
+
} else if(req_id) {
|
|
2010
2025
|
gobj_send_event(
|
|
2011
2026
|
gobj_topic_form,
|
|
2012
2027
|
"EV_PAGE_LOADED",
|
|
@@ -2415,6 +2430,29 @@ function ac_create_record(gobj, event, kw, src)
|
|
|
2415
2430
|
);
|
|
2416
2431
|
}
|
|
2417
2432
|
|
|
2433
|
+
/********************************************
|
|
2434
|
+
* A topic table wants its records as json, WITH the metadata of
|
|
2435
|
+
* each one (its Raw JSON button). The table's own rows are read
|
|
2436
|
+
* without it, so this is a read of its own: the whole topic, and
|
|
2437
|
+
* the table keeps to the rows it shows.
|
|
2438
|
+
********************************************/
|
|
2439
|
+
function ac_request_json(gobj, event, kw, src)
|
|
2440
|
+
{
|
|
2441
|
+
let topic_name = kw.topic_name || gobj_read_attr(src, "topic_name");
|
|
2442
|
+
if(!topic_name) {
|
|
2443
|
+
log_error(`${gobj_short_name(gobj)}: a json request with no topic`);
|
|
2444
|
+
return -1;
|
|
2445
|
+
}
|
|
2446
|
+
return treedb_nodes(
|
|
2447
|
+
gobj,
|
|
2448
|
+
gobj_read_str_attr(gobj, "treedb_name"),
|
|
2449
|
+
topic_name,
|
|
2450
|
+
Object.assign({}, TABLE_READ_OPTIONS, {with_metadata: true}),
|
|
2451
|
+
null,
|
|
2452
|
+
"json"
|
|
2453
|
+
); // Error already logged
|
|
2454
|
+
}
|
|
2455
|
+
|
|
2418
2456
|
/********************************************
|
|
2419
2457
|
* A topic table wants a page.
|
|
2420
2458
|
*
|
|
@@ -2779,6 +2817,7 @@ function create_gclass(gclass_name)
|
|
|
2779
2817
|
["EV_UPDATE_RECORD", ac_update_record, null],
|
|
2780
2818
|
["EV_UPDATE_FIELD", ac_update_field, null],
|
|
2781
2819
|
["EV_REQUEST_PAGE", ac_request_page, null],
|
|
2820
|
+
["EV_REQUEST_JSON", ac_request_json, null],
|
|
2782
2821
|
["EV_REQUEST_ASSET", ac_request_asset, null],
|
|
2783
2822
|
["EV_OPEN_LINKED", ac_open_linked, null],
|
|
2784
2823
|
["EV_DELETE_RECORD", ac_delete_record, null],
|
|
@@ -2810,6 +2849,7 @@ function create_gclass(gclass_name)
|
|
|
2810
2849
|
["EV_UPDATE_RECORD", 0],
|
|
2811
2850
|
["EV_UPDATE_FIELD", 0],
|
|
2812
2851
|
["EV_REQUEST_PAGE", 0],
|
|
2852
|
+
["EV_REQUEST_JSON", 0],
|
|
2813
2853
|
["EV_REQUEST_ASSET", 0],
|
|
2814
2854
|
["EV_OPEN_LINKED", 0],
|
|
2815
2855
|
["EV_DELETE_RECORD", 0],
|
package/src/yui_dev.js
CHANGED
|
@@ -404,9 +404,14 @@ function ensure_dev_style()
|
|
|
404
404
|
flex: 0 0 auto; display: flex; flex-wrap: wrap; gap: 14px;
|
|
405
405
|
padding: 6px 10px; border-top: 1px solid rgba(0,0,0,0.1);
|
|
406
406
|
background: rgba(0,0,0,0.03);
|
|
407
|
-
font-family: "DejaVu Sans Mono", monospace; font-size:
|
|
407
|
+
font-family: "DejaVu Sans Mono", monospace; font-size: 0.875rem;
|
|
408
408
|
opacity: 0.9; font-variant-numeric: tabular-nums;
|
|
409
409
|
}
|
|
410
|
+
/* Sizes in rem, not px: they follow the reader's zoom and root size. The
|
|
411
|
+
controls (chips, segments, search) are at 1rem with a finger's padding --
|
|
412
|
+
this window used to be all 9-13px, controls included, which is what
|
|
413
|
+
is-small is not for. Only secondary ink (source, size/time, the
|
|
414
|
+
uppercase labels) goes under 0.9rem. (No backticks: template literal.) */
|
|
410
415
|
/* -------- control bar -------- */
|
|
411
416
|
.YDEV_BAR {
|
|
412
417
|
display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px;
|
|
@@ -415,12 +420,12 @@ function ensure_dev_style()
|
|
|
415
420
|
}
|
|
416
421
|
.YDEV_GROUP { display: inline-flex; align-items: center; gap: 5px; }
|
|
417
422
|
.YDEV_LABEL {
|
|
418
|
-
font-size:
|
|
419
|
-
opacity: 0.
|
|
423
|
+
font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.08em;
|
|
424
|
+
opacity: 0.6; align-self: center;
|
|
420
425
|
}
|
|
421
426
|
.YDEV_SEP { width: 1px; align-self: stretch; background: rgba(0,0,0,0.12); }
|
|
422
427
|
.YDEV_CHIP {
|
|
423
|
-
font: inherit; font-size:
|
|
428
|
+
font: inherit; font-size: 1rem; line-height: 1.4; padding: 0.4rem 0.8rem;
|
|
424
429
|
border: 1px solid rgba(0,0,0,0.18); border-radius: 999px;
|
|
425
430
|
background: transparent; color: inherit; cursor: pointer;
|
|
426
431
|
display: inline-flex; align-items: center; gap: 5px;
|
|
@@ -433,14 +438,14 @@ function ensure_dev_style()
|
|
|
433
438
|
.YDEV_CHIP[data-dir]:not(.is-active) { opacity: 0.4; text-decoration: line-through; }
|
|
434
439
|
.YDEV_SEG { display: inline-flex; border: 1px solid rgba(0,0,0,0.18); border-radius: 7px; overflow: hidden; }
|
|
435
440
|
.YDEV_SEG_BTN {
|
|
436
|
-
font: inherit; font-size:
|
|
441
|
+
font: inherit; font-size: 1rem; padding: 0.4rem 0.85rem; border: 0;
|
|
437
442
|
border-right: 1px solid rgba(0,0,0,0.12);
|
|
438
443
|
background: transparent; color: inherit; cursor: pointer;
|
|
439
444
|
}
|
|
440
445
|
.YDEV_SEG_BTN:last-child { border-right: 0; }
|
|
441
446
|
.YDEV_SEG_BTN.is-active { background: #2563eb; color: #fff; font-weight: 600; }
|
|
442
447
|
.YDEV_SEARCH {
|
|
443
|
-
font: inherit; font-size:
|
|
448
|
+
font: inherit; font-size: 1rem; padding: 0.4rem 0.7rem; min-width: 13rem;
|
|
444
449
|
border: 1px solid rgba(0,0,0,0.18); border-radius: 7px;
|
|
445
450
|
background: transparent; color: inherit;
|
|
446
451
|
}
|
|
@@ -449,7 +454,7 @@ function ensure_dev_style()
|
|
|
449
454
|
.YDEV_STAT.is-strong { font-weight: 700; }
|
|
450
455
|
.YDEV_TITLE { display: flex; align-items: baseline; gap: 8px; }
|
|
451
456
|
.YDEV_TITLE_MAIN { font-weight: 700; }
|
|
452
|
-
.YDEV_TITLE_SUB { opacity: 0.7; font-size:
|
|
457
|
+
.YDEV_TITLE_SUB { opacity: 0.7; font-size: 0.875rem; }
|
|
453
458
|
/* The ink of the log.
|
|
454
459
|
*
|
|
455
460
|
* It used to be one grey dimmed with opacity per role -- 0.85 for a key,
|
|
@@ -488,7 +493,7 @@ function ensure_dev_style()
|
|
|
488
493
|
/* -------- entries (shared) -------- */
|
|
489
494
|
.TRAFFIC_ENTRY {
|
|
490
495
|
border-left: 3px solid #94a3b8; border-radius: 3px;
|
|
491
|
-
font-family: "DejaVu Sans Mono", monospace, consolas, monaco; font-size:
|
|
496
|
+
font-family: "DejaVu Sans Mono", monospace, consolas, monaco; font-size: 0.9375rem;
|
|
492
497
|
background: rgba(0,0,0,0.02);
|
|
493
498
|
}
|
|
494
499
|
.TRAFFIC_ENTRY { margin: 6px 0; padding: 4px 8px; line-height: 1.55; }
|
|
@@ -502,18 +507,18 @@ function ensure_dev_style()
|
|
|
502
507
|
/* Where the message went through. min-width 0 and flex 0 1 auto so it is the
|
|
503
508
|
part that gives way when the row runs out of width -- the event name and
|
|
504
509
|
the size/time must not be the ones to go. */
|
|
505
|
-
.TRAFFIC_SRC { color: var(--ydev-src); font-size:
|
|
510
|
+
.TRAFFIC_SRC { color: var(--ydev-src); font-size: 0.8125rem; flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
506
511
|
.dir-out .TRAFFIC_ARROW, .dir-out .TRAFFIC_EVENT { color: #2563eb; }
|
|
507
512
|
.dir-in .TRAFFIC_ARROW, .dir-in .TRAFFIC_EVENT { color: #059669; }
|
|
508
513
|
.dir-err .TRAFFIC_ARROW, .dir-err .TRAFFIC_EVENT { color: #dc2626; }
|
|
509
|
-
.TRAFFIC_META { margin-left: auto; color: var(--ydev-dim); font-size:
|
|
514
|
+
.TRAFFIC_META { margin-left: auto; color: var(--ydev-dim); font-size: 0.8125rem; white-space: nowrap; }
|
|
510
515
|
/* The indent of a nested block is NOT a hover effect: it used to be given
|
|
511
516
|
only on .TRAFFIC_ENTRY:hover, so moving the cursor across the log made
|
|
512
517
|
every payload under it jump 16px sideways and reflow. A payload being
|
|
513
518
|
read must not move because the pointer passed over it.
|
|
514
519
|
(No backticks in here: this stylesheet is a template literal.) */
|
|
515
520
|
.TRAFFIC_KW { margin: 2px 0 0 16px; }
|
|
516
|
-
.TRAFFIC_FULL { margin: 4px 0 0 16px; padding: 6px 8px; font-family: monospace; font-size:
|
|
521
|
+
.TRAFFIC_FULL { margin: 4px 0 0 16px; padding: 6px 8px; font-family: monospace; font-size: 0.875rem; line-height: 1.45; white-space: pre-wrap; word-break: break-word; background: rgba(0,0,0,0.04); border-radius: 4px; overflow-x: auto; }
|
|
517
522
|
.TRAFFIC_ROW { display: flex; gap: 6px; align-items: baseline; }
|
|
518
523
|
.TRAFFIC_BULLET { color: var(--ydev-bullet); flex: 0 0 auto; }
|
|
519
524
|
.TRAFFIC_KEY { color: var(--ydev-key); flex: 0 0 auto; }
|
|
@@ -538,17 +543,17 @@ details.TRAFFIC_NEST > summary::-webkit-details-marker { display: none; }
|
|
|
538
543
|
.TRAFFIC_PREV.t-bool { color: var(--ydev-bool); }
|
|
539
544
|
.TRAFFIC_PREV.t-null { color: var(--ydev-bool); font-style: italic; }
|
|
540
545
|
.TRAFFIC_PREV.t-empty { color: var(--ydev-dim); }
|
|
541
|
-
.YDEV_EMPTY { color: var(--ydev-dim); font-size:
|
|
546
|
+
.YDEV_EMPTY { color: var(--ydev-dim); font-size: 0.875rem; padding: 18px 10px; text-align: center; }
|
|
542
547
|
/* -------- mirrored console logs (error/warning/info/debug/msg; the automata trace shows as debug) -------- */
|
|
543
|
-
.YDEV_LOGROW { display: flex; align-items: baseline; gap: 8px; margin: 1px 0; padding: 2px 8px; border-left: 3px solid #94a3b8; border-radius: 3px; font-family: "DejaVu Sans Mono", monospace, consolas, monaco; font-size:
|
|
544
|
-
.YDEV_LOG_LVL { flex: 0 0 auto; text-transform: uppercase; font-size:
|
|
548
|
+
.YDEV_LOGROW { display: flex; align-items: baseline; gap: 8px; margin: 1px 0; padding: 2px 8px; border-left: 3px solid #94a3b8; border-radius: 3px; font-family: "DejaVu Sans Mono", monospace, consolas, monaco; font-size: 0.9375rem; background: rgba(0,0,0,0.015); }
|
|
549
|
+
.YDEV_LOG_LVL { flex: 0 0 auto; text-transform: uppercase; font-size: 0.75rem; font-weight: 700; letter-spacing: 0.04em; color: var(--ydev-dim); min-width: 4.5rem; }
|
|
545
550
|
.YDEV_LOG_TXT { flex: 1 1 auto; min-width: 0; white-space: pre-wrap; word-break: break-word; color: var(--ydev-ink); }
|
|
546
551
|
.YDEV_LOG_error { border-left-color: #dc2626; } .YDEV_LOG_error .YDEV_LOG_LVL { color: #dc2626; }
|
|
547
552
|
.YDEV_LOG_warning { border-left-color: #d97706; } .YDEV_LOG_warning .YDEV_LOG_LVL { color: #d97706; }
|
|
548
553
|
.YDEV_LOG_info { border-left-color: #2563eb; } .YDEV_LOG_info .YDEV_LOG_LVL { color: #2563eb; }
|
|
549
554
|
.YDEV_LOG_msg { border-left-color: #0891b2; } .YDEV_LOG_msg .YDEV_LOG_LVL { color: #0891b2; }
|
|
550
555
|
.YDEV_LOG_debug { border-left-color: #94a3b8; } .YDEV_LOG_debug .YDEV_LOG_LVL { color: #94a3b8; } .YDEV_LOG_debug .YDEV_LOG_TXT { color: var(--ydev-dim); }
|
|
551
|
-
.YDEV_LOG_json { border-left-color: #9333ea; align-items: flex-start; } .YDEV_LOG_json .YDEV_LOG_LVL { color: #9333ea; } .YDEV_LOG_json .YDEV_LOG_TXT { font-size:
|
|
556
|
+
.YDEV_LOG_json { border-left-color: #9333ea; align-items: flex-start; } .YDEV_LOG_json .YDEV_LOG_LVL { color: #9333ea; } .YDEV_LOG_json .YDEV_LOG_TXT { font-size: 0.875rem; line-height: 1.4; color: var(--ydev-dim); }
|
|
552
557
|
/* -------- dark theme -------- */
|
|
553
558
|
:root[data-theme="dark"] .TRAFFIC_FULL { background: rgba(255,255,255,0.05); }
|
|
554
559
|
:root[data-theme="dark"] .YDEV_BAR, :root[data-theme="dark"] .YDEV_STATS { background: rgba(255,255,255,0.04); }
|