@yuneta/gobj-ui 5.11.1 → 5.12.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuneta/gobj-ui",
3
- "version": "5.11.1",
3
+ "version": "5.12.0",
4
4
  "type": "module",
5
5
  "main": "dist/gobj-ui.cjs.js",
6
6
  "module": "dist/gobj-ui.es.js",
@@ -30,7 +30,7 @@
30
30
  "@rollup/plugin-terser": "^1.0.0",
31
31
  "@vitest/coverage-v8": "^4.1.10",
32
32
  "@yuneta/gobj-js": "^7.8.7",
33
- "vite": "^8.1.5",
33
+ "vite": "^8.2.1",
34
34
  "vitest": "^4.1.10"
35
35
  },
36
36
  "peerDependencies": {
package/src/c_yui_json.js CHANGED
@@ -37,6 +37,7 @@ import {
37
37
  data_type_t,
38
38
  event_flag_t,
39
39
  gclass_create,
40
+ gclass_find_by_name,
40
41
  log_error,
41
42
  gobj_read_pointer_attr,
42
43
  gobj_parent,
@@ -936,6 +937,13 @@ function create_gclass(gclass_name)
936
937
  ***************************************************************/
937
938
  function register_c_yui_json()
938
939
  {
940
+ /* Idempotent: C_YUI_TREEDB_TOPIC_WITH_FORM auto-registers this
941
+ * gclass for its schema dialog, so an app that also registers it
942
+ * explicitly (order-independent) must not trip
943
+ * "GClass ALREADY created". */
944
+ if(gclass_find_by_name(GCLASS_NAME, false)) {
945
+ return 0;
946
+ }
939
947
  return create_gclass(GCLASS_NAME);
940
948
  }
941
949
 
@@ -69,6 +69,7 @@ import {
69
69
  } from "./c_yui_shell.js";
70
70
 
71
71
  import {register_c_yui_form} from "./c_yui_form.js";
72
+ import {register_c_yui_json} from "./c_yui_json.js";
72
73
  import {attach_clear} from "./yui_inputs.js";
73
74
 
74
75
  import {yui_tabulator_lang, yui_tabulator_relocalize} from "./yui_tabulator_i18n.js";
@@ -103,6 +104,7 @@ SDATA(data_type_t.DTP_BOOLEAN, "with_copy_button", 0, true, "Button tool
103
104
  SDATA(data_type_t.DTP_BOOLEAN, "with_paste_button", 0, true, "Button toolbar PASTE"),
104
105
  SDATA(data_type_t.DTP_BOOLEAN, "with_refresh_button", 0, true, "Button toolbar REFRESH"),
105
106
  SDATA(data_type_t.DTP_BOOLEAN, "with_search_button", 0, true, "Button toolbar SEARCH"),
107
+ SDATA(data_type_t.DTP_BOOLEAN, "with_schema_button", 0, true, "Button toolbar SCHEMA (show the topic's desc)"),
106
108
  SDATA(data_type_t.DTP_BOOLEAN, "with_in_row_edit_icons", 0, true, "Add a last column with internal EDIT/DELETE icon"),
107
109
 
108
110
  SDATA(data_type_t.DTP_BOOLEAN, "editable", 0, false, "Edit state"),
@@ -143,6 +145,8 @@ let PRIVATE_DATA = {
143
145
  tabulator: null,
144
146
  form: null, // hosted C_YUI_FORM child (while dialog open)
145
147
  form_modal: null, // { close } handle of the adaptive dialog
148
+ schema_gobj: null, // hosted C_YUI_JSON child (while schema open)
149
+ schema_modal: null, // { close } handle of the schema dialog
146
150
  };
147
151
 
148
152
  let __gclass__ = null;
@@ -221,6 +225,7 @@ function mt_stop(gobj)
221
225
  gobj_unsubscribe_event(shell, "EV_LANGUAGE_CHANGED", {}, gobj);
222
226
  }
223
227
  close_form_dialog(gobj);
228
+ close_schema_dialog(gobj);
224
229
  table__destroy(gobj);
225
230
  }
226
231
 
@@ -234,6 +239,7 @@ function mt_destroy(gobj)
234
239
  * it unhooks the Escape handler (shell chain or document
235
240
  * listener) and removes the dialog DOM. */
236
241
  close_form_dialog(gobj);
242
+ close_schema_dialog(gobj);
237
243
  destroy_ui(gobj);
238
244
  }
239
245
 
@@ -477,6 +483,7 @@ function build_ui(gobj)
477
483
 
478
484
  let with_refresh_button = gobj_read_bool_attr(gobj, "with_refresh_button");
479
485
  let with_search_button = gobj_read_bool_attr(gobj, "with_search_button");
486
+ let with_schema_button = gobj_read_bool_attr(gobj, "with_schema_button");
480
487
 
481
488
  if(with_search_button) {
482
489
  let search_id = `${toolbar_id}_search`;
@@ -543,6 +550,27 @@ function build_ui(gobj)
543
550
  $view_toolbar.appendChild($refresh);
544
551
  }
545
552
 
553
+ if(with_schema_button) {
554
+ /* What the columns of this topic ARE: types, flags, fkeys. The
555
+ * table shows the data; this shows the contract the data answers
556
+ * to, which is what you need when a value is refused or a link
557
+ * does not appear. */
558
+ let $schema = createElement2(
559
+ ['button', {class: 'TREEDB_TABLE_SCHEMA button mr-1',
560
+ title: t('schema'), 'data-i18n-title': 'schema',
561
+ 'aria-label': t('schema'), 'data-i18n-aria-label': 'schema'}, [
562
+ ['i', {class: 'yi-hexagon-nodes'}],
563
+ ['span', {class: 'is-hidden-mobile', i18n: 'schema', style: 'padding-left:5px;'}, 'schema']
564
+ ], {
565
+ 'click': (event) => {
566
+ event.stopPropagation();
567
+ gobj_send_event(gobj, "EV_SHOW_SCHEMA", {}, gobj);
568
+ }
569
+ }]
570
+ );
571
+ $view_toolbar.appendChild($schema);
572
+ }
573
+
546
574
  /*----------------------------------------------*
547
575
  * Layout Schema
548
576
  *----------------------------------------------*/
@@ -1328,6 +1356,112 @@ function close_form_dialog(gobj)
1328
1356
  teardown_form_child(gobj);
1329
1357
  }
1330
1358
 
1359
+ /************************************************************
1360
+ * Show the topic's SCHEMA: its `desc` — pkey, cols, types,
1361
+ * flags and fkey targets — in the standardized adaptive
1362
+ * dialog, rendered by a C_YUI_JSON child. A viewer and not a
1363
+ * <pre> dump because a forty-column topic is only readable
1364
+ * collapsed and searchable.
1365
+ *
1366
+ * Read-only and offline: the desc is already in this gobj,
1367
+ * so no command is issued and nothing can be edited here.
1368
+ ************************************************************/
1369
+ function open_schema_dialog(gobj)
1370
+ {
1371
+ close_schema_dialog(gobj); // only one at a time
1372
+
1373
+ let priv = gobj.priv;
1374
+
1375
+ let desc = gobj_read_attr(gobj, "desc");
1376
+ if(!desc) {
1377
+ log_error(`${gobj_short_name(gobj)}: no desc, no schema to show`);
1378
+ return;
1379
+ }
1380
+
1381
+ let shell = yui_shell_of(gobj);
1382
+ if(!shell) {
1383
+ log_error(`${gobj_short_name(gobj)}: no shell, cannot open the schema view`);
1384
+ return;
1385
+ }
1386
+
1387
+ let json_view = gobj_create_pure_child(
1388
+ "schema_" + clean_name(gobj_name(gobj)),
1389
+ "C_YUI_JSON",
1390
+ {
1391
+ /* No `title`: the dialog header already titles it. The
1392
+ * viewer's own would land inside the dialog, doubling it. */
1393
+ },
1394
+ gobj
1395
+ );
1396
+ if(!json_view) {
1397
+ log_error(`${gobj_short_name(gobj)}: cannot create the schema viewer`);
1398
+ return;
1399
+ }
1400
+ priv.schema_gobj = json_view;
1401
+ gobj_start(json_view);
1402
+
1403
+ let $box = gobj_read_attr(json_view, "$container");
1404
+ if(!$box) {
1405
+ log_error(`${gobj_short_name(gobj)}: the schema viewer built no $container`);
1406
+ teardown_schema_child(gobj);
1407
+ return;
1408
+ }
1409
+
1410
+ /* Title split in two halves: the topic name is DATA (never
1411
+ * translated) and "schema" is the kind (carries its i18n key), so
1412
+ * the header re-translates on a language switch. */
1413
+ priv.schema_modal = yui_shell_show_modal(shell, $box, {
1414
+ dialog: true,
1415
+ logical_class: "TREEDB_SCHEMA_SHEET",
1416
+ title_prefix: gobj_read_str_attr(gobj, "topic_name"),
1417
+ title: "schema",
1418
+ t: t,
1419
+ on_close: function() {
1420
+ teardown_schema_child(gobj);
1421
+ }
1422
+ });
1423
+
1424
+ /* EV_SET_JSON and not the `json_data` attr: the attr renders the
1425
+ * tree but leaves the viewer in ST_IDLE, where a click to expand a
1426
+ * node is an event nobody handles. */
1427
+ gobj_send_event(json_view, "EV_SET_JSON", {json: desc}, gobj);
1428
+ }
1429
+
1430
+ /************************************************************
1431
+ * Destroy the hosted C_YUI_JSON child. Called from the
1432
+ * schema modal's on_close — the shell has already removed
1433
+ * the dialog DOM and retired its Escape / history entries.
1434
+ ************************************************************/
1435
+ function teardown_schema_child(gobj)
1436
+ {
1437
+ let priv = gobj.priv;
1438
+ if(priv.schema_gobj) {
1439
+ if(gobj_is_running(priv.schema_gobj)) {
1440
+ gobj_stop(priv.schema_gobj);
1441
+ }
1442
+ gobj_destroy(priv.schema_gobj);
1443
+ priv.schema_gobj = null;
1444
+ }
1445
+ priv.schema_modal = null;
1446
+ }
1447
+
1448
+ /************************************************************
1449
+ * Close the schema dialog (teardown, or a second open).
1450
+ * Closing the modal runs its on_close, which tears the
1451
+ * viewer child down.
1452
+ ************************************************************/
1453
+ function close_schema_dialog(gobj)
1454
+ {
1455
+ let priv = gobj.priv;
1456
+ if(priv.schema_modal) {
1457
+ let modal = priv.schema_modal;
1458
+ priv.schema_modal = null;
1459
+ modal.close(); // -> on_close -> teardown_schema_child
1460
+ return;
1461
+ }
1462
+ teardown_schema_child(gobj);
1463
+ }
1464
+
1331
1465
  /************************************************************
1332
1466
  * True if the topic's pkey col carries the "rowid" flag.
1333
1467
  ************************************************************/
@@ -2284,6 +2418,16 @@ function ac_refresh(gobj, event, kw, src)
2284
2418
  return 0;
2285
2419
  }
2286
2420
 
2421
+ /************************************************************
2422
+ * Show the schema (desc) of this topic
2423
+ ************************************************************/
2424
+ function ac_show_schema(gobj, event, kw, src)
2425
+ {
2426
+ open_schema_dialog(gobj);
2427
+
2428
+ return 0;
2429
+ }
2430
+
2287
2431
  /************************************************************
2288
2432
  * {
2289
2433
  * href: href
@@ -2358,6 +2502,7 @@ function create_gclass(gclass_name)
2358
2502
  ["EV_SHOW_HOOK_DATA", ac_show_hook_data, null],
2359
2503
  ["EV_CHANGE_LOCALE", ac_change_locale, null],
2360
2504
  ["EV_REFRESH", ac_refresh, null],
2505
+ ["EV_SHOW_SCHEMA", ac_show_schema, null],
2361
2506
  ["EV_SHOW", ac_show, null],
2362
2507
  ["EV_HIDE", ac_hide, null]
2363
2508
  ]]
@@ -2384,6 +2529,7 @@ function create_gclass(gclass_name)
2384
2529
  ["EV_SHOW_HOOK_DATA", event_flag_t.EVF_OUTPUT_EVENT],
2385
2530
  ["EV_CHANGE_LOCALE", 0],
2386
2531
  ["EV_REFRESH", 0],
2532
+ ["EV_SHOW_SCHEMA", 0],
2387
2533
 
2388
2534
  ["EV_CREATE_RECORD", event_flag_t.EVF_OUTPUT_EVENT],
2389
2535
  ["EV_UPDATE_RECORD", event_flag_t.EVF_OUTPUT_EVENT],
@@ -2425,6 +2571,10 @@ function register_c_yui_treedb_topic_with_form()
2425
2571
  if(!gclass_find_by_name("C_YUI_FORM", false)) {
2426
2572
  register_c_yui_form();
2427
2573
  }
2574
+ /* same for the schema dialog's C_YUI_JSON viewer */
2575
+ if(!gclass_find_by_name("C_YUI_JSON", false)) {
2576
+ register_c_yui_json();
2577
+ }
2428
2578
  return create_gclass(GCLASS_NAME);
2429
2579
  }
2430
2580