@yuneta/gobj-ui 6.2.0 → 6.3.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/README.md CHANGED
@@ -468,6 +468,24 @@ It needs the descriptor to carry `pkey2s`, which `tranger2_topic_desc()` only
468
468
  clones from **SDK > 7.13.0**. Against an older node the desc has no `pkey2s`, the
469
469
  label falls back to the id, and nothing else changes.
470
470
 
471
+ ### Which backend a view browses: `source_url`
472
+
473
+ `C_YUI_TREEDB_TOPICS` takes an optional **`source_url`** string and prints it in
474
+ its toolbar, between the left buttons and the *raw json* one. A host passes the
475
+ url of the connection the view reads through (`wss://host:port`), and an empty
476
+ value renders nothing.
477
+
478
+ The tab that hosts the view is labelled with the **treedb** name, and a treedb
479
+ name is not unique across backends: two tabs reading `treedb_yuneta_agent` are
480
+ two different machines, and a wrong assumption there is a write on the wrong
481
+ node. The url is what tells them apart, and it does not fit in a tab label —
482
+ a tab wide enough for `wss://artgins.yunetacontrol.com:1996` is a tab bar with
483
+ room for one tab. So the view carries it, where there is a whole row for it.
484
+
485
+ The buttons of that toolbar never shrink. When the row runs out of room, the
486
+ url is what gives way, cut with an ellipsis, and the whole value stays in the
487
+ `title` and the `aria-label`.
488
+
471
489
  ### Read-only treedbs: `readonly`
472
490
 
473
491
  `C_YUI_TREEDB_TOPICS` and `C_YUI_TREEDB_GRAPH` take a **`readonly`** attr; the
@@ -14413,6 +14413,7 @@ var attrs_table$6 = [
14413
14413
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_JSON, "card_action_routes", 0, null, "Per-card hash-route templates {info, table, graph} with a {topic} placeholder (host-supplied, route-agnostic). Present ⇒ cards show 3 icon actions; absent ⇒ a single card that opens the table."),
14414
14414
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_JSON, "landing_routes", 0, null, "Host-supplied hashes for the two landing sub-views {cards, schema}; the toggle navigates to them so the landing is URL-addressable (ROUTING.md). Absent ⇒ toggle flips in-view only (legacy)."),
14415
14415
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "base_route", 0, "", "This view's base route (host-supplied); used to declare its sub-routes (topics / info / schema) to the site map (ROUTING.md contributor)."),
14416
+ (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "source_url", 0, "", "The backend this view browses (host-supplied, typically the wss url of the connection), shown in the toolbar. A tab label names the TREEDB, and the same treedb name lives on more than one node, so the node has to be readable somewhere -- and a tab is too narrow to carry a url. Empty ⇒ nothing is shown."),
14416
14417
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_POINTER, "$container", 0, null, "Root HTML element, show/hide managed by external routing"),
14417
14418
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_POINTER, "$current_item", 0, null, "Currently selected item"),
14418
14419
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "last_selection", 0, null, "Last href selection"),
@@ -14518,6 +14519,7 @@ function cmd_get_topic_data$1(gobj, cmd, kw, src) {
14518
14519
  * Build UI
14519
14520
  ************************************************************/
14520
14521
  function build_ui$6(gobj) {
14522
+ let source_url = (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "source_url") || "";
14521
14523
  let $container = (0, _yuneta_gobj_js.createElement2)([
14522
14524
  "div",
14523
14525
  {
@@ -14581,6 +14583,23 @@ function build_ui$6(gobj) {
14581
14583
  (0, _yuneta_gobj_js.gobj_send_event)(gobj, "EV_TOGGLE_LANDING_VIEW", {}, gobj);
14582
14584
  } }
14583
14585
  ],
14586
+ [
14587
+ "div",
14588
+ {
14589
+ class: source_url ? "TREEDB_TOPICS_SOURCE" : "TREEDB_TOPICS_SOURCE is-hidden",
14590
+ title: source_url,
14591
+ "aria-label": source_url
14592
+ },
14593
+ [[
14594
+ "span",
14595
+ { class: "icon" },
14596
+ [["i", { class: "yi-cloudversify" }]]
14597
+ ], [
14598
+ "span",
14599
+ { class: "TREEDB_TOPICS_SOURCE_URL" },
14600
+ source_url
14601
+ ]]
14602
+ ],
14584
14603
  [
14585
14604
  "button",
14586
14605
  {
@@ -14408,6 +14408,7 @@ var attrs_table$6 = [
14408
14408
  SDATA(data_type_t.DTP_JSON, "card_action_routes", 0, null, "Per-card hash-route templates {info, table, graph} with a {topic} placeholder (host-supplied, route-agnostic). Present ⇒ cards show 3 icon actions; absent ⇒ a single card that opens the table."),
14409
14409
  SDATA(data_type_t.DTP_JSON, "landing_routes", 0, null, "Host-supplied hashes for the two landing sub-views {cards, schema}; the toggle navigates to them so the landing is URL-addressable (ROUTING.md). Absent ⇒ toggle flips in-view only (legacy)."),
14410
14410
  SDATA(data_type_t.DTP_STRING, "base_route", 0, "", "This view's base route (host-supplied); used to declare its sub-routes (topics / info / schema) to the site map (ROUTING.md contributor)."),
14411
+ SDATA(data_type_t.DTP_STRING, "source_url", 0, "", "The backend this view browses (host-supplied, typically the wss url of the connection), shown in the toolbar. A tab label names the TREEDB, and the same treedb name lives on more than one node, so the node has to be readable somewhere -- and a tab is too narrow to carry a url. Empty ⇒ nothing is shown."),
14411
14412
  SDATA(data_type_t.DTP_POINTER, "$container", 0, null, "Root HTML element, show/hide managed by external routing"),
14412
14413
  SDATA(data_type_t.DTP_POINTER, "$current_item", 0, null, "Currently selected item"),
14413
14414
  SDATA(data_type_t.DTP_STRING, "last_selection", 0, null, "Last href selection"),
@@ -14513,6 +14514,7 @@ function cmd_get_topic_data$1(gobj, cmd, kw, src) {
14513
14514
  * Build UI
14514
14515
  ************************************************************/
14515
14516
  function build_ui$6(gobj) {
14517
+ let source_url = gobj_read_str_attr(gobj, "source_url") || "";
14516
14518
  let $container = createElement2([
14517
14519
  "div",
14518
14520
  {
@@ -14576,6 +14578,23 @@ function build_ui$6(gobj) {
14576
14578
  gobj_send_event(gobj, "EV_TOGGLE_LANDING_VIEW", {}, gobj);
14577
14579
  } }
14578
14580
  ],
14581
+ [
14582
+ "div",
14583
+ {
14584
+ class: source_url ? "TREEDB_TOPICS_SOURCE" : "TREEDB_TOPICS_SOURCE is-hidden",
14585
+ title: source_url,
14586
+ "aria-label": source_url
14587
+ },
14588
+ [[
14589
+ "span",
14590
+ { class: "icon" },
14591
+ [["i", { class: "yi-cloudversify" }]]
14592
+ ], [
14593
+ "span",
14594
+ { class: "TREEDB_TOPICS_SOURCE_URL" },
14595
+ source_url
14596
+ ]]
14597
+ ],
14579
14598
  [
14580
14599
  "button",
14581
14600
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuneta/gobj-ui",
3
- "version": "6.2.0",
3
+ "version": "6.3.0",
4
4
  "type": "module",
5
5
  "main": "dist/gobj-ui.cjs.js",
6
6
  "module": "dist/gobj-ui.es.js",
package/src/c_yui_node.js CHANGED
@@ -632,6 +632,27 @@ function clear_navs(gobj)
632
632
  * "index" — I am the tip: the projection is the page.
633
633
  * "chrome" — a child is showing: the projection is its chrome.
634
634
  ************************************************************/
635
+ /************************************************************
636
+ * WHERE A CHILD'S NAV ITEM POINTS.
637
+ *
638
+ * One function, because two things read it and they must not
639
+ * disagree: the item's own href, and the `active_route` the nav
640
+ * is told to highlight — C_YUI_NAV matches by EXACT route, so an
641
+ * item pointing at a remembered position while the active route
642
+ * stayed canonical is an item that is never marked active.
643
+ ************************************************************/
644
+ function child_nav_route(gobj, id)
645
+ {
646
+ let my_route = route_of(gobj);
647
+ let base = my_route === "/" ? "" : my_route;
648
+ let route = `${base}/${id}`;
649
+
650
+ if(!gobj_read_bool_attr(gobj, "remember_position")) {
651
+ return route;
652
+ }
653
+ return nav_route_with_tail(route, gobj.priv.remembered[id]);
654
+ }
655
+
635
656
  function render_projection(gobj, mode, $where, active_route, active_id, zones_only)
636
657
  {
637
658
  let priv = gobj.priv;
@@ -662,11 +683,7 @@ function render_projection(gobj, mode, $where, active_route, active_id, zones_on
662
683
  * contract either way: what the item carries is a real position,
663
684
  * so clicking it is a navigation and not a restore that would then
664
685
  * have to argue with the url. */
665
- let remember = gobj_read_bool_attr(gobj, "remember_position");
666
- let items = child_nav_items(specs, (id) => {
667
- let route = `${base}/${id}`;
668
- return remember ? nav_route_with_tail(route, priv.remembered[id]) : route;
669
- });
686
+ let items = child_nav_items(specs, (id) => child_nav_route(gobj, id));
670
687
 
671
688
  let i = 0;
672
689
  for(let render of renders) {
@@ -892,7 +909,10 @@ function render_child(gobj, child)
892
909
  * level. `chrome_depth` is how a node caps that for its corner
893
910
  * of the tree (see resolve_chrome_depth). */
894
911
  if(chrome_visible(priv.distance, priv.chrome_depth)) {
895
- render_projection(gobj, "chrome", priv.$chrome, route_of(child),
912
+ /* The SAME route the item carries, or the nav has nothing to
913
+ * match: it highlights by exact route. */
914
+ render_projection(gobj, "chrome", priv.$chrome,
915
+ child_nav_route(gobj, gobj_read_attr(child, "node_id")),
896
916
  gobj_read_attr(child, "node_id"));
897
917
  }
898
918
  render_path(gobj, priv.$chrome);
@@ -71,3 +71,31 @@
71
71
  background: transparent;
72
72
  padding: 0;
73
73
  }
74
+
75
+ /* The backend url in the toolbar, between the left buttons and the
76
+ * json button (which keeps itself flush right with margin-left:auto).
77
+ * The buttons never shrink: when the row runs out of room it is the
78
+ * url that gives way, one character at a time, down to its icon. */
79
+ .TREEDB_TOPICS_TOOLBAR > .button {
80
+ flex: none;
81
+ }
82
+ .TREEDB_TOPICS_SOURCE {
83
+ display: flex;
84
+ align-items: center;
85
+ gap: 0.25rem;
86
+ flex: 0 1 auto;
87
+ min-width: 0;
88
+ margin-left: 0.5rem;
89
+ font-size: 0.75rem;
90
+ color: var(--bulma-text-weak, #7a7a7a);
91
+ }
92
+ .TREEDB_TOPICS_SOURCE .icon {
93
+ flex: none;
94
+ }
95
+ /* One line, cut with an ellipsis. The whole url stays in the title. */
96
+ .TREEDB_TOPICS_SOURCE .TREEDB_TOPICS_SOURCE_URL {
97
+ min-width: 0;
98
+ overflow: hidden;
99
+ text-overflow: ellipsis;
100
+ white-space: nowrap;
101
+ }
@@ -81,6 +81,7 @@ SDATA(data_type_t.DTP_BOOLEAN, "readonly", 0, false, "The whole treed
81
81
  SDATA(data_type_t.DTP_JSON, "card_action_routes",0, null, "Per-card hash-route templates {info, table, graph} with a {topic} placeholder (host-supplied, route-agnostic). Present ⇒ cards show 3 icon actions; absent ⇒ a single card that opens the table."),
82
82
  SDATA(data_type_t.DTP_JSON, "landing_routes", 0, null, "Host-supplied hashes for the two landing sub-views {cards, schema}; the toggle navigates to them so the landing is URL-addressable (ROUTING.md). Absent ⇒ toggle flips in-view only (legacy)."),
83
83
  SDATA(data_type_t.DTP_STRING, "base_route", 0, "", "This view's base route (host-supplied); used to declare its sub-routes (topics / info / schema) to the site map (ROUTING.md contributor)."),
84
+ SDATA(data_type_t.DTP_STRING, "source_url", 0, "", "The backend this view browses (host-supplied, typically the wss url of the connection), shown in the toolbar. A tab label names the TREEDB, and the same treedb name lives on more than one node, so the node has to be readable somewhere -- and a tab is too narrow to carry a url. Empty ⇒ nothing is shown."),
84
85
  SDATA(data_type_t.DTP_POINTER, "$container", 0, null, "Root HTML element, show/hide managed by external routing"),
85
86
  SDATA(data_type_t.DTP_POINTER, "$current_item", 0, null, "Currently selected item"),
86
87
  SDATA(data_type_t.DTP_STRING, "last_selection", 0, null, "Last href selection"),
@@ -245,6 +246,8 @@ function cmd_get_topic_data(gobj, cmd, kw, src)
245
246
  ************************************************************/
246
247
  function build_ui(gobj)
247
248
  {
249
+ let source_url = gobj_read_str_attr(gobj, "source_url") || "";
250
+
248
251
  /*----------------------------------------------*
249
252
  * Layout Schema
250
253
  *----------------------------------------------*/
@@ -287,6 +290,19 @@ function build_ui(gobj)
287
290
  gobj_send_event(gobj, "EV_TOGGLE_LANDING_VIEW", {}, gobj);
288
291
  }
289
292
  }],
293
+ /* The backend this view browses. The tab that hosts this
294
+ * view is labelled with the TREEDB name, and the same
295
+ * treedb name lives on more than one node — two tabs
296
+ * reading `treedb_yuneta_agent` are two different
297
+ * machines. A tab label cannot carry a url without
298
+ * becoming unreadable, so the url is here, where there is
299
+ * room for it. Hidden when the host supplies none. */
300
+ ['div', {class: source_url?
301
+ 'TREEDB_TOPICS_SOURCE' : 'TREEDB_TOPICS_SOURCE is-hidden',
302
+ title: source_url, 'aria-label': source_url}, [
303
+ ['span', {class: 'icon'}, [['i', {class: 'yi-cloudversify'}]]],
304
+ ['span', {class: 'TREEDB_TOPICS_SOURCE_URL'}, source_url]
305
+ ]],
290
306
  /* Inspect the treedb's raw tranger json (whole service,
291
307
  * print-tranger, lazy drill). Last + margin-left:auto:
292
308
  * flush right, away from the back arrow it sat next to. */