@yuneta/gobj-ui 7.23.181 → 7.23.183

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.
@@ -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 (req_id) (0, _yuneta_gobj_js.gobj_send_event)(gobj_topic_form, "EV_PAGE_LOADED", {
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`;
@@ -26821,57 +26850,57 @@ function build_ui$5(gobj) {
26821
26850
  });
26822
26851
  $view_toolbar.appendChild($search_box);
26823
26852
  }
26824
- if (with_refresh_button) {
26825
- let $refresh = (0, _yuneta_gobj_js.createElement2)([
26853
+ if (with_schema_button) {
26854
+ let $schema = (0, _yuneta_gobj_js.createElement2)([
26826
26855
  "button",
26827
26856
  {
26828
- class: "button mr-1",
26829
- title: (0, i18next.t)("refresh"),
26830
- "data-i18n-title": "refresh",
26831
- "aria-label": (0, i18next.t)("refresh"),
26832
- "data-i18n-aria-label": "refresh"
26857
+ class: "TREEDB_TABLE_SCHEMA button mr-1",
26858
+ title: (0, i18next.t)("schema"),
26859
+ "data-i18n-title": "schema",
26860
+ "aria-label": (0, i18next.t)("schema"),
26861
+ "data-i18n-aria-label": "schema"
26833
26862
  },
26834
- [yui_toolbar_icon("yi-arrows-rotate"), [
26863
+ [yui_toolbar_icon("yi-hexagon-nodes"), [
26835
26864
  "span",
26836
26865
  {
26837
26866
  class: "is-hidden-mobile",
26838
- i18n: "refresh",
26867
+ i18n: "schema",
26839
26868
  style: "padding-left:5px;"
26840
26869
  },
26841
- "refresh"
26870
+ "schema"
26842
26871
  ]],
26843
26872
  { "click": (event) => {
26844
26873
  event.stopPropagation();
26845
- (0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_REFRESH", {}, gobj);
26874
+ (0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_SHOW_SCHEMA", {}, gobj);
26846
26875
  } }
26847
26876
  ]);
26848
- $view_toolbar.appendChild($refresh);
26877
+ $view_toolbar.appendChild($schema);
26849
26878
  }
26850
- if (with_schema_button) {
26851
- let $schema = (0, _yuneta_gobj_js.createElement2)([
26879
+ if (with_refresh_button) {
26880
+ let $refresh = (0, _yuneta_gobj_js.createElement2)([
26852
26881
  "button",
26853
26882
  {
26854
- class: "TREEDB_TABLE_SCHEMA button mr-1",
26855
- title: (0, i18next.t)("schema"),
26856
- "data-i18n-title": "schema",
26857
- "aria-label": (0, i18next.t)("schema"),
26858
- "data-i18n-aria-label": "schema"
26883
+ class: "button mr-1",
26884
+ title: (0, i18next.t)("refresh"),
26885
+ "data-i18n-title": "refresh",
26886
+ "aria-label": (0, i18next.t)("refresh"),
26887
+ "data-i18n-aria-label": "refresh"
26859
26888
  },
26860
- [yui_toolbar_icon("yi-hexagon-nodes"), [
26889
+ [yui_toolbar_icon("yi-arrows-rotate"), [
26861
26890
  "span",
26862
26891
  {
26863
26892
  class: "is-hidden-mobile",
26864
- i18n: "schema",
26893
+ i18n: "refresh",
26865
26894
  style: "padding-left:5px;"
26866
26895
  },
26867
- "schema"
26896
+ "refresh"
26868
26897
  ]],
26869
26898
  { "click": (event) => {
26870
26899
  event.stopPropagation();
26871
- (0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_SHOW_SCHEMA", {}, gobj);
26900
+ (0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_REFRESH", {}, gobj);
26872
26901
  } }
26873
26902
  ]);
26874
- $view_toolbar.appendChild($schema);
26903
+ $view_toolbar.appendChild($refresh);
26875
26904
  }
26876
26905
  if (with_columns_button) {
26877
26906
  let $columns = (0, _yuneta_gobj_js.createElement2)([
@@ -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],
@@ -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 (req_id) gobj_send_event(gobj_topic_form, "EV_PAGE_LOADED", {
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`;
@@ -26816,57 +26845,57 @@ function build_ui$5(gobj) {
26816
26845
  });
26817
26846
  $view_toolbar.appendChild($search_box);
26818
26847
  }
26819
- if (with_refresh_button) {
26820
- let $refresh = createElement2([
26848
+ if (with_schema_button) {
26849
+ let $schema = createElement2([
26821
26850
  "button",
26822
26851
  {
26823
- class: "button mr-1",
26824
- title: t("refresh"),
26825
- "data-i18n-title": "refresh",
26826
- "aria-label": t("refresh"),
26827
- "data-i18n-aria-label": "refresh"
26852
+ class: "TREEDB_TABLE_SCHEMA button mr-1",
26853
+ title: t("schema"),
26854
+ "data-i18n-title": "schema",
26855
+ "aria-label": t("schema"),
26856
+ "data-i18n-aria-label": "schema"
26828
26857
  },
26829
- [yui_toolbar_icon("yi-arrows-rotate"), [
26858
+ [yui_toolbar_icon("yi-hexagon-nodes"), [
26830
26859
  "span",
26831
26860
  {
26832
26861
  class: "is-hidden-mobile",
26833
- i18n: "refresh",
26862
+ i18n: "schema",
26834
26863
  style: "padding-left:5px;"
26835
26864
  },
26836
- "refresh"
26865
+ "schema"
26837
26866
  ]],
26838
26867
  { "click": (event) => {
26839
26868
  event.stopPropagation();
26840
- gobj_send_event(gobj, "EV_REFRESH", {}, gobj);
26869
+ gobj_send_event(gobj, "EV_SHOW_SCHEMA", {}, gobj);
26841
26870
  } }
26842
26871
  ]);
26843
- $view_toolbar.appendChild($refresh);
26872
+ $view_toolbar.appendChild($schema);
26844
26873
  }
26845
- if (with_schema_button) {
26846
- let $schema = createElement2([
26874
+ if (with_refresh_button) {
26875
+ let $refresh = createElement2([
26847
26876
  "button",
26848
26877
  {
26849
- class: "TREEDB_TABLE_SCHEMA button mr-1",
26850
- title: t("schema"),
26851
- "data-i18n-title": "schema",
26852
- "aria-label": t("schema"),
26853
- "data-i18n-aria-label": "schema"
26878
+ class: "button mr-1",
26879
+ title: t("refresh"),
26880
+ "data-i18n-title": "refresh",
26881
+ "aria-label": t("refresh"),
26882
+ "data-i18n-aria-label": "refresh"
26854
26883
  },
26855
- [yui_toolbar_icon("yi-hexagon-nodes"), [
26884
+ [yui_toolbar_icon("yi-arrows-rotate"), [
26856
26885
  "span",
26857
26886
  {
26858
26887
  class: "is-hidden-mobile",
26859
- i18n: "schema",
26888
+ i18n: "refresh",
26860
26889
  style: "padding-left:5px;"
26861
26890
  },
26862
- "schema"
26891
+ "refresh"
26863
26892
  ]],
26864
26893
  { "click": (event) => {
26865
26894
  event.stopPropagation();
26866
- gobj_send_event(gobj, "EV_SHOW_SCHEMA", {}, gobj);
26895
+ gobj_send_event(gobj, "EV_REFRESH", {}, gobj);
26867
26896
  } }
26868
26897
  ]);
26869
- $view_toolbar.appendChild($schema);
26898
+ $view_toolbar.appendChild($refresh);
26870
26899
  }
26871
26900
  if (with_columns_button) {
26872
26901
  let $columns = createElement2([
@@ -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],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuneta/gobj-ui",
3
- "version": "7.23.181",
3
+ "version": "7.23.183",
4
4
  "type": "module",
5
5
  "main": "dist/gobj-ui.cjs.js",
6
6
  "module": "dist/gobj-ui.es.js",
@@ -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) {
@@ -795,23 +802,6 @@ function build_ui(gobj)
795
802
  $view_toolbar.appendChild($search_box);
796
803
  }
797
804
 
798
- if(with_refresh_button) {
799
- let $refresh = createElement2(
800
- ['button', {class: 'button mr-1',
801
- title: t('refresh'), 'data-i18n-title': 'refresh',
802
- 'aria-label': t('refresh'), 'data-i18n-aria-label': 'refresh'}, [
803
- yui_toolbar_icon('yi-arrows-rotate'),
804
- ['span', {class: 'is-hidden-mobile', i18n: 'refresh', style: 'padding-left:5px;'}, 'refresh']
805
- ], {
806
- 'click': (event) => {
807
- event.stopPropagation();
808
- gobj_send_event(gobj, "EV_REFRESH", {}, gobj);
809
- }
810
- }]
811
- );
812
- $view_toolbar.appendChild($refresh);
813
- }
814
-
815
805
  if(with_schema_button) {
816
806
  /* What the columns of this topic ARE: types, flags, fkeys. The
817
807
  * table shows the data; this shows the contract the data answers
@@ -833,6 +823,28 @@ function build_ui(gobj)
833
823
  $view_toolbar.appendChild($schema);
834
824
  }
835
825
 
826
+ /* The ORDER is a contract shared with every table toolbar of the
827
+ * ecosystem: what is particular to this view first (search, schema),
828
+ * then the common block ALWAYS as Refresh, Columns, (Raw JSON,) Export, then Close
829
+ * when there is one. A button that moves from view to view has to be
830
+ * looked for every time. */
831
+ if(with_refresh_button) {
832
+ let $refresh = createElement2(
833
+ ['button', {class: 'button mr-1',
834
+ title: t('refresh'), 'data-i18n-title': 'refresh',
835
+ 'aria-label': t('refresh'), 'data-i18n-aria-label': 'refresh'}, [
836
+ yui_toolbar_icon('yi-arrows-rotate'),
837
+ ['span', {class: 'is-hidden-mobile', i18n: 'refresh', style: 'padding-left:5px;'}, 'refresh']
838
+ ], {
839
+ 'click': (event) => {
840
+ event.stopPropagation();
841
+ gobj_send_event(gobj, "EV_REFRESH", {}, gobj);
842
+ }
843
+ }]
844
+ );
845
+ $view_toolbar.appendChild($refresh);
846
+ }
847
+
836
848
  if(with_columns_button) {
837
849
  /* A topic with a dozen columns is wider than the screen, and until
838
850
  * now the reader could not decide WHICH of them to keep: the table
@@ -854,6 +866,27 @@ function build_ui(gobj)
854
866
  $view_toolbar.appendChild($columns);
855
867
  }
856
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
+
857
890
  if(with_export_button) {
858
891
  /* What the TABLE holds, filters and column choice applied — not the
859
892
  * topic. A server-side dump of every node is not something this view
@@ -4971,6 +5004,142 @@ function ac_export_table(gobj, event, kw, src)
4971
5004
  return 0;
4972
5005
  }
4973
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
+
4974
5143
  /************************************************************
4975
5144
  * {
4976
5145
  * href: href
@@ -5070,6 +5239,8 @@ function create_gclass(gclass_name)
5070
5239
  ["EV_EDIT_RECORD", ac_edit_record, null],
5071
5240
  ["EV_TOGGLE_COLUMN", ac_toggle_column, null],
5072
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],
5073
5244
  ["EV_SHOW", ac_show, null],
5074
5245
  ["EV_HIDE", ac_hide, null]
5075
5246
  ]]
@@ -5125,6 +5296,9 @@ function create_gclass(gclass_name)
5125
5296
  ["EV_EDIT_RECORD", 0],
5126
5297
  ["EV_TOGGLE_COLUMN", 0],
5127
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],
5128
5302
 
5129
5303
  ["EV_CREATE_RECORD", event_flag_t.EVF_OUTPUT_EVENT],
5130
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
- if(req_id) {
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],