@yuneta/gobj-ui 7.23.186 → 7.23.188

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.
@@ -23714,7 +23714,7 @@ function build_ui$6(gobj) {
23714
23714
  [[
23715
23715
  "span",
23716
23716
  { class: "icon" },
23717
- [yui_toolbar_icon("yi-hexagon-nodes")]
23717
+ [yui_toolbar_icon("yi-compass-drafting")]
23718
23718
  ], [
23719
23719
  "span",
23720
23720
  { i18n: "schema" },
@@ -23725,6 +23725,29 @@ function build_ui$6(gobj) {
23725
23725
  (0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_TOGGLE_LANDING_VIEW", {}, gobj);
23726
23726
  } }
23727
23727
  ],
23728
+ [
23729
+ "button",
23730
+ {
23731
+ class: "button TREEDB_SCHEMA_JSON_BTN is-hidden",
23732
+ title: (0, i18next.t)("schema json"),
23733
+ "aria-label": (0, i18next.t)("schema json"),
23734
+ "data-i18n-title": "schema json",
23735
+ "data-i18n-aria-label": "schema json"
23736
+ },
23737
+ [[
23738
+ "span",
23739
+ { class: "icon" },
23740
+ [yui_toolbar_icon("yi-code")]
23741
+ ], [
23742
+ "span",
23743
+ { i18n: "schema json" },
23744
+ "schema json"
23745
+ ]],
23746
+ { click: (evt) => {
23747
+ evt.stopPropagation();
23748
+ (0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_OPEN_SCHEMA_JSON", {}, gobj);
23749
+ } }
23750
+ ],
23728
23751
  [
23729
23752
  "div",
23730
23753
  {
@@ -24168,6 +24191,7 @@ function show_topics_landing(gobj) {
24168
24191
  let $info = $container.querySelector(".TREEDB_TOPIC_INFO");
24169
24192
  let $back = $container.querySelector(".TREEDB_TOPICS_BACK");
24170
24193
  let $toggle = $container.querySelector(".TREEDB_LANDING_TOGGLE");
24194
+ let $schema_json = $container.querySelector(".TREEDB_SCHEMA_JSON_BTN");
24171
24195
  if ($tabs) $tabs.classList.add("is-hidden");
24172
24196
  if ($sub) $sub.classList.add("is-hidden");
24173
24197
  if ($info) $info.classList.add("is-hidden");
@@ -24177,6 +24201,7 @@ function show_topics_landing(gobj) {
24177
24201
  $toggle.classList.remove("is-hidden");
24178
24202
  $toggle.classList.toggle("is-primary", schema_mode);
24179
24203
  }
24204
+ if ($schema_json) $schema_json.classList.toggle("is-hidden", !schema_mode);
24180
24205
  if (schema_mode) {
24181
24206
  if ($landing) $landing.classList.add("is-hidden");
24182
24207
  if ($schema) $schema.classList.remove("is-hidden");
@@ -24246,9 +24271,11 @@ function show_topic_detail(gobj) {
24246
24271
  let $info = $container.querySelector(".TREEDB_TOPIC_INFO");
24247
24272
  let $back = $container.querySelector(".TREEDB_TOPICS_BACK");
24248
24273
  let $toggle = $container.querySelector(".TREEDB_LANDING_TOGGLE");
24274
+ let $schema_json = $container.querySelector(".TREEDB_SCHEMA_JSON_BTN");
24249
24275
  if ($landing) $landing.classList.add("is-hidden");
24250
24276
  if ($schema) $schema.classList.add("is-hidden");
24251
24277
  if ($info) $info.classList.add("is-hidden");
24278
+ if ($schema_json) $schema_json.classList.add("is-hidden");
24252
24279
  if ($toggle) $toggle.classList.add("is-hidden");
24253
24280
  if ($tabs) $tabs.classList.remove("is-hidden");
24254
24281
  if ($sub) $sub.classList.remove("is-hidden");
@@ -24289,8 +24316,10 @@ function show_topic_info(gobj, topic) {
24289
24316
  let $schema = $container.querySelector(".TREEDB_TOPICS_SCHEMA");
24290
24317
  let $back = $container.querySelector(".TREEDB_TOPICS_BACK");
24291
24318
  let $toggle = $container.querySelector(".TREEDB_LANDING_TOGGLE");
24319
+ let $schema_json = $container.querySelector(".TREEDB_SCHEMA_JSON_BTN");
24292
24320
  if ($landing) $landing.classList.add("is-hidden");
24293
24321
  if ($schema) $schema.classList.add("is-hidden");
24322
+ if ($schema_json) $schema_json.classList.add("is-hidden");
24294
24323
  if ($toggle) $toggle.classList.add("is-hidden");
24295
24324
  if ($tabs) $tabs.classList.add("is-hidden");
24296
24325
  if ($sub) $sub.classList.add("is-hidden");
@@ -24565,7 +24594,7 @@ function register_sub_routes$1(gobj) {
24565
24594
  if ((0, _yuneta_gobj_js.is_object)((0, _yuneta_gobj_js.gobj_read_attr)(gobj, "landing_routes"))) nodes.push({
24566
24595
  route: base + "/schema",
24567
24596
  label: "schema",
24568
- icon: "yi-hexagon-nodes",
24597
+ icon: "yi-compass-drafting",
24569
24598
  gclass: "C_YUI_TREEDB_SCHEMA"
24570
24599
  });
24571
24600
  if ((0, _yuneta_gobj_js.is_object)(descs)) for (let topic of Object.keys(descs)) {
@@ -24708,10 +24737,11 @@ function is_mobile$2() {
24708
24737
  * whole service (lazy drill). CHILD model: the viewer publishes
24709
24738
  * EV_EXPAND_PATH to us.
24710
24739
  ************************************************************/
24711
- function open_json_viewer$1(gobj) {
24740
+ function open_json_viewer$1(gobj, opts) {
24712
24741
  let priv = gobj.priv;
24742
+ let schema = !!(opts && opts.schema);
24713
24743
  if (priv.json_win || priv.json_modal) {
24714
- request_print_tranger$1(gobj, "");
24744
+ if (!schema) request_print_tranger$1(gobj, "");
24715
24745
  return;
24716
24746
  }
24717
24747
  if (!(0, _yuneta_gobj_js.gclass_find_by_name)("C_YUI_JSON")) {
@@ -24721,7 +24751,10 @@ function open_json_viewer$1(gobj) {
24721
24751
  }
24722
24752
  let mobile = is_mobile$2();
24723
24753
  let shell = yui_shell_of(gobj);
24724
- let jv = (0, _yuneta_gobj_js.gobj_create_service)(`treedb-topics-json-${(0, _yuneta_gobj_js.clean_name)((0, _yuneta_gobj_js.gobj_name)(gobj))}`, "C_YUI_JSON", { subscriber: gobj }, gobj);
24754
+ let jv = (0, _yuneta_gobj_js.gobj_create_service)(`treedb-topics-json-${(0, _yuneta_gobj_js.clean_name)((0, _yuneta_gobj_js.gobj_name)(gobj))}`, "C_YUI_JSON", {
24755
+ subscriber: gobj,
24756
+ json_data: schema ? (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "descs") : null
24757
+ }, gobj);
24725
24758
  if (!jv) {
24726
24759
  (0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: cannot create the JSON viewer`);
24727
24760
  return;
@@ -24739,7 +24772,7 @@ function open_json_viewer$1(gobj) {
24739
24772
  dialog: true,
24740
24773
  logical_class: "TREEDB_JSON_SHEET",
24741
24774
  title_prefix: priv.treedb_name,
24742
- title: "raw json",
24775
+ title: schema ? "schema json" : "raw json",
24743
24776
  t: i18next.t,
24744
24777
  on_close: () => {
24745
24778
  if ((0, _yuneta_gobj_js.gobj_is_destroying)(gobj)) return;
@@ -24761,8 +24794,8 @@ function open_json_viewer$1(gobj) {
24761
24794
  height: 620,
24762
24795
  logical_class: "TREEDB_JSON_WINDOW",
24763
24796
  title_prefix: priv.treedb_name,
24764
- title: "raw json",
24765
- icon: "yi-eye",
24797
+ title: schema ? "schema json" : "raw json",
24798
+ icon: schema ? "yi-code" : "yi-eye",
24766
24799
  body: $box,
24767
24800
  manager: null,
24768
24801
  on_close: () => {
@@ -24777,7 +24810,7 @@ function open_json_viewer$1(gobj) {
24777
24810
  }
24778
24811
  (0, _yuneta_gobj_js.gobj_start)(priv.json_win);
24779
24812
  }
24780
- request_print_tranger$1(gobj, "");
24813
+ if (!schema) request_print_tranger$1(gobj, "");
24781
24814
  }
24782
24815
  /************************************************************
24783
24816
  * Close the JSON viewer (user dismiss / teardown).
@@ -25371,6 +25404,19 @@ function ac_open_json$1(gobj, event, kw, src) {
25371
25404
  return 0;
25372
25405
  }
25373
25406
  /********************************************
25407
+ * The schema, as the json it is: the `descs` the schema graph is
25408
+ * drawing. Same viewer and same host as the tranger's raw json --
25409
+ * one at a time, so it closes whatever was open first.
25410
+ ********************************************/
25411
+ function ac_open_schema_json(gobj, event, kw, src) {
25412
+ if (!(0, _yuneta_gobj_js.is_object)((0, _yuneta_gobj_js.gobj_read_attr)(gobj, "descs"))) {
25413
+ (0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: schema json with no descs`);
25414
+ return -1;
25415
+ }
25416
+ open_json_viewer$1(gobj, { schema: true });
25417
+ return 0;
25418
+ }
25419
+ /********************************************
25374
25420
  * Open the graph where the reader left it: its last visited
25375
25421
  * route under the graph's base -- `<graph>/<topic>` when a topic
25376
25422
  * was focused there -- or the bare base when the graph was never
@@ -25504,6 +25550,11 @@ function create_gclass$6(gclass_name) {
25504
25550
  ac_open_json$1,
25505
25551
  null
25506
25552
  ],
25553
+ [
25554
+ "EV_OPEN_SCHEMA_JSON",
25555
+ ac_open_schema_json,
25556
+ null
25557
+ ],
25507
25558
  [
25508
25559
  "EV_OPEN_GRAPH",
25509
25560
  ac_open_graph,
@@ -25576,6 +25627,7 @@ function create_gclass$6(gclass_name) {
25576
25627
  ["EV_RECORD_WRITTEN", _yuneta_gobj_js.event_flag_t.EVF_OUTPUT_EVENT | _yuneta_gobj_js.event_flag_t.EVF_NO_WARN_SUBS],
25577
25628
  ["EV_REFRESH_TOPIC", 0],
25578
25629
  ["EV_OPEN_JSON", 0],
25630
+ ["EV_OPEN_SCHEMA_JSON", 0],
25579
25631
  ["EV_OPEN_GRAPH", 0],
25580
25632
  ["EV_EXPAND_PATH", 0],
25581
25633
  ["EV_JSON_CLOSED", 0],
@@ -30347,54 +30399,57 @@ function plan_graph_saves(live, saved) {
30347
30399
  * treedb_node_label.js
30348
30400
  *
30349
30401
  * Pure, testable logic behind the label of a node in the treedb
30350
- * graph: WHAT A RECORD IS CALLED, which is not always what it is
30351
- * keyed by. Kept out of the gclass so it can be unit-tested with
30352
- * no DOM and no G6.
30402
+ * graph: WHAT A RECORD IS CALLED. Kept out of the gclass so it can
30403
+ * be unit-tested with no DOM and no G6.
30353
30404
  *
30354
30405
  * Copyright (c) 2026, ArtGins.
30355
30406
  * All Rights Reserved.
30356
30407
  ***********************************************************************/
30357
- /************************************************************
30358
- * What a node is CALLED, which is not always what it is
30359
- * keyed by.
30360
- *
30361
- * A topic whose id column is flagged `rowid`, `uuid` or
30362
- * `qualified` keys its records by something that is not the
30363
- * name — a counter, a random string, or the name with every
30364
- * ancestor in front of it — and the name a human knows the
30365
- * record by lives in the secondary key the topic declares
30366
- * (`pkey2s`, carried in the desc since SDK > 7.13.0). The
30367
- * `topics` and `cols` topics of treedb_system_schema are the
30368
- * case that forced this: named in `value`, so every card in
30369
- * the graph read "181", "225", "193" while they were keyed by
30370
- * rowid, and reads the whole path now that they are
30371
- * qualified.
30372
- *
30373
- * The pkey stays reachable: it is the card's tooltip.
30374
- *
30375
- * Falls back to the id whenever the schema does not say
30376
- * otherwise — an older node whose desc carries no `pkey2s`
30377
- * included.
30408
+ var SEP = " · ";
30409
+ /************************************************************
30410
+ * What a node is CALLED: **its id, and the secondary keys it
30411
+ * carries**.
30412
+ *
30413
+ * A record is one thing and an INSTANCE of it is another: the
30414
+ * topic keys the record by `id` and the instance by the
30415
+ * columns it declares in `pkey2s`. A card that shows one
30416
+ * without the other is a card that cannot be identified --
30417
+ * and it used to show one INSTEAD of the other, so the yunos
30418
+ * of an agent read `7.23.0-1`, `7.23.0-1`, `7.23.0-1` (the
30419
+ * release, which they share) and never said which yuno each
30420
+ * one was, while a `configurations` card read `1`.
30421
+ *
30422
+ * It came from the opposite case, and that one still works:
30423
+ * the `topics` and `cols` of treedb_system_schema are keyed
30424
+ * by a rowid, so the card said "181" and the name lived in
30425
+ * the pkey2. Now it says both -- `181 · yuno_role` -- which
30426
+ * is what the record is: that name, under that key.
30427
+ *
30428
+ * Rules:
30429
+ * - the id always opens the label;
30430
+ * - every pkey2 the record carries follows it, in the
30431
+ * order the topic declares them, separated by `·`;
30432
+ * - a pkey2 whose value is empty, absent or equal to the
30433
+ * id adds nothing;
30434
+ * - a desc with no `pkey2s` (an older node's schema
30435
+ * included) gives the bare id.
30378
30436
  ************************************************************/
30379
30437
  function node_label(desc, record) {
30380
30438
  let id = record.id;
30381
- let id_col = null;
30382
- if (Array.isArray(desc.cols)) {
30383
- for (let col of desc.cols) if (col && col.id === (desc.pkey || "id")) {
30384
- id_col = col;
30385
- break;
30386
- }
30387
- }
30388
- if (!id_col || !Array.isArray(id_col.flag)) return id;
30389
- if (id_col.flag.indexOf("rowid") < 0 && id_col.flag.indexOf("uuid") < 0 && id_col.flag.indexOf("qualified") < 0) return id;
30390
- let pkey2s = desc.pkey2s;
30439
+ let pkey2s = desc ? desc.pkey2s : null;
30391
30440
  if (typeof pkey2s === "string") pkey2s = pkey2s ? [pkey2s] : [];
30392
- if (!Array.isArray(pkey2s)) return id;
30441
+ if (!Array.isArray(pkey2s) || pkey2s.length === 0) return id;
30442
+ let parts = [];
30393
30443
  for (let name of pkey2s) {
30444
+ if (!name) continue;
30394
30445
  let value = record[name];
30395
- if (typeof value === "string" && value.length > 0) return value;
30446
+ if (typeof value === "number") value = String(value);
30447
+ if (typeof value !== "string" || value.length === 0) continue;
30448
+ if (value === String(id)) continue;
30449
+ parts.push(value);
30396
30450
  }
30397
- return id;
30451
+ if (parts.length === 0) return id;
30452
+ return [id, ...parts].join(SEP);
30398
30453
  }
30399
30454
  //#endregion
30400
30455
  //#region src/treedb_fold_model.js
@@ -58820,7 +58875,7 @@ function build_graph$1(gobj) {
58820
58875
  container: priv.$container,
58821
58876
  animation: false,
58822
58877
  autoResize: false,
58823
- zoomRange: [.2, 4],
58878
+ zoomRange: [.02, 4],
58824
58879
  node: {
58825
58880
  palette: {
58826
58881
  type: "group",
@@ -60076,6 +60131,7 @@ function draw_link(gobj, child_topic, child_id, source_col, fkey, verbose) {
60076
60131
  parent_topic,
60077
60132
  parent_id,
60078
60133
  hook_name,
60134
+ child_topic,
60079
60135
  child_id,
60080
60136
  is_tree
60081
60137
  });
@@ -60582,7 +60638,7 @@ async function graph_fit_selection(gobj, ids) {
60582
60638
  let bw = Math.max(1, maxx - minx);
60583
60639
  let bh = Math.max(1, maxy - miny);
60584
60640
  let zoom = Math.min(vw / bw, vh / bh);
60585
- let range = graph.getZoomRange() || [.2, 4];
60641
+ let range = graph.getZoomRange() || [.02, 4];
60586
60642
  zoom = Math.max(range[0], Math.min(range[1], zoom));
60587
60643
  await graph.zoomTo(zoom);
60588
60644
  await graph.focusElement(ids);
@@ -63319,16 +63375,14 @@ function refresh_html_nodes_theme(gobj, theme) {
63319
63375
  function refresh_default_edges_theme(gobj, theme) {
63320
63376
  let graph = gobj.priv.graph;
63321
63377
  if (!graph) return;
63322
- let dark = theme === "dark";
63323
63378
  let edges = graph.getData().edges || [];
63324
63379
  let updates = [];
63325
63380
  for (let i = 0; i < edges.length; i++) {
63326
63381
  let d = edges[i].data || {};
63327
63382
  if (!d.themed_default) continue;
63328
- let stroke = d.is_tree ? dark ? "#22a7c2" : "#0e7490" : dark ? "#8b94a3" : "#6b7280";
63329
63383
  updates.push({
63330
63384
  id: edges[i].id,
63331
- style: { stroke }
63385
+ style: { stroke: default_edge_stroke(gobj, d, theme) }
63332
63386
  });
63333
63387
  }
63334
63388
  if (updates.length > 0) graph.updateEdgeData(updates);
@@ -63900,21 +63954,54 @@ function apply_edge_properties(gobj, edge_id, lineWidth, stroke, scope) {
63900
63954
  deselect_edge(gobj);
63901
63955
  }
63902
63956
  /************************************************************
63957
+ * The colour a link is DRAWN in: the colour of the two knobs it
63958
+ * joins.
63959
+ *
63960
+ * Both ends of a link wear the CHILD topic's colour -- the
63961
+ * parent's hook port is painted with the colour of whatever may
63962
+ * hang there, and the child's fkey port with its own (see
63963
+ * build_ports) -- so the line between them has one obvious
63964
+ * colour, and a reader follows a link by its hue instead of
63965
+ * tracing a grey thread across the canvas.
63966
+ *
63967
+ * It goes through port_rim(): the FILL of a port says which
63968
+ * topic, and a line on the canvas is a graphical object that
63969
+ * needs 3:1 against it, which that mix clears in both themes
63970
+ * (9.11 dark, 3.80 light) while keeping the hue. So a link is
63971
+ * drawn in exactly the colour of the rim of the two knobs it
63972
+ * ends on.
63973
+ *
63974
+ * The containment/tree relation (parent and child of the same
63975
+ * topic) is no longer marked by a teal of its own -- it is that
63976
+ * topic's colour like any other link, and what still tells it
63977
+ * apart is its WIDTH.
63978
+ *
63979
+ * A topic with no colour, or an edge of a graph with no schema
63980
+ * yet, keeps the neutral grey this used to give everything.
63981
+ ************************************************************/
63982
+ function default_edge_stroke(gobj, d, theme) {
63983
+ let priv = gobj.priv;
63984
+ let desc = (0, _yuneta_gobj_js.is_object)(priv.descs) ? priv.descs[d.child_topic] : null;
63985
+ if (desc && desc.color) return port_rim(desc.color, theme);
63986
+ let dark = theme === "dark";
63987
+ return d.is_tree ? dark ? "#22a7c2" : "#0e7490" : dark ? "#8b94a3" : "#6b7280";
63988
+ }
63989
+ /************************************************************
63903
63990
  * The style an edge INHERITS, before anything saved for the
63904
63991
  * edge itself: its hook's default in the parent topic, else the
63905
63992
  * parent topic's default for every edge, else the library's.
63906
63993
  *
63907
- * The library's: neutral grey, teal for the containment/tree
63908
- * relation (parent and child of the same topic, a
63909
- * self-hierarchy). `themed_default` says the colour is still the
63910
- * library's, so a theme toggle re-themes it and leaves a chosen
63911
- * one alone.
63994
+ * The library's: the colour of the ports it joins (see
63995
+ * default_edge_stroke), and a wider line for the
63996
+ * containment/tree relation. `themed_default` says the colour is
63997
+ * still the library's, so a theme toggle re-themes it and leaves
63998
+ * a chosen one alone.
63912
63999
  ************************************************************/
63913
64000
  function edge_inherited_style_of(gobj, d) {
63914
- let dark = gobj.priv.theme === "dark";
64001
+ let priv = gobj.priv;
63915
64002
  let style = {
63916
64003
  lineWidth: d.is_tree ? 2 : 1.6,
63917
- stroke: d.is_tree ? dark ? "#22a7c2" : "#0e7490" : dark ? "#8b94a3" : "#6b7280",
64004
+ stroke: default_edge_stroke(gobj, d, priv.theme),
63918
64005
  themed_default: true
63919
64006
  };
63920
64007
  let defs = topic_defaults_of(gobj, d.parent_topic);
@@ -71735,7 +71822,7 @@ function render_toolbar(gobj) {
71735
71822
  ]);
71736
71823
  let $right = [];
71737
71824
  if (priv.treedb_id && has_model) {
71738
- $right.push(toolbar_button("SCHEMA_DIAGRAM_BTN", "yi-hexagon-nodes", priv.diagram ? "topics" : "diagram", "EV_TOGGLE_DIAGRAM", false));
71825
+ $right.push(toolbar_button("SCHEMA_DIAGRAM_BTN", "yi-compass-drafting", priv.diagram ? "topics" : "diagram", "EV_TOGGLE_DIAGRAM", false));
71739
71826
  $right.push(toolbar_button("SCHEMA_VALIDATE_BTN", "yi-square-check", "check", "EV_VALIDATE", false));
71740
71827
  $right.push(toolbar_button("SCHEMA_EXPORT_BTN", "yi-download", "export", "EV_EXPORT", false));
71741
71828
  if (!readonly) $right.push(toolbar_button("SCHEMA_IMPORT_BTN", "yi-upload", "import", "EV_IMPORT", false));