@yuneta/gobj-ui 7.23.140 → 7.23.142
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 +123 -37
- package/dist/gobj-ui.cjs.js +412 -140
- package/dist/gobj-ui.es.js +412 -140
- package/package.json +2 -2
- package/src/c_g6_nodes_tree.js +98 -59
- package/src/c_yui_schema_editor.js +16 -0
- package/src/c_yui_treedb_graph.js +153 -23
- package/src/schema_import.js +2 -1
- package/src/schema_model.js +2 -1
- package/src/schema_to_c.js +1 -1
- package/src/schema_validate.js +20 -0
- package/src/schema_validate.test.js +44 -0
- package/src/treedb_fold_model.js +185 -21
- package/src/treedb_fold_model.test.js +120 -5
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -13111,7 +13111,7 @@ function ac_find_nodes$3(gobj, event, kw, src) {
|
|
|
13111
13111
|
/************************************************************
|
|
13112
13112
|
* EV_EXPAND_ALL
|
|
13113
13113
|
************************************************************/
|
|
13114
|
-
function ac_expand_all$
|
|
13114
|
+
function ac_expand_all$2(gobj, event, kw, src) {
|
|
13115
13115
|
let priv = gobj.priv;
|
|
13116
13116
|
if (priv.collapsed.size === 0) return 0;
|
|
13117
13117
|
priv.collapsed.clear();
|
|
@@ -13123,7 +13123,7 @@ function ac_expand_all$4(gobj, event, kw, src) {
|
|
|
13123
13123
|
/************************************************************
|
|
13124
13124
|
* EV_COLLAPSE_ALL — fold every card but the root.
|
|
13125
13125
|
************************************************************/
|
|
13126
|
-
function ac_collapse_all$
|
|
13126
|
+
function ac_collapse_all$2(gobj, event, kw, src) {
|
|
13127
13127
|
let priv = gobj.priv;
|
|
13128
13128
|
let json_data = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "json_data");
|
|
13129
13129
|
if (!json_data) return 0;
|
|
@@ -13423,12 +13423,12 @@ function create_gclass$13(gclass_name) {
|
|
|
13423
13423
|
],
|
|
13424
13424
|
[
|
|
13425
13425
|
"EV_EXPAND_ALL",
|
|
13426
|
-
ac_expand_all$
|
|
13426
|
+
ac_expand_all$2,
|
|
13427
13427
|
null
|
|
13428
13428
|
],
|
|
13429
13429
|
[
|
|
13430
13430
|
"EV_COLLAPSE_ALL",
|
|
13431
|
-
ac_collapse_all$
|
|
13431
|
+
ac_collapse_all$2,
|
|
13432
13432
|
null
|
|
13433
13433
|
],
|
|
13434
13434
|
[
|
|
@@ -14500,7 +14500,7 @@ function ac_search$2(gobj, event, kw, src) {
|
|
|
14500
14500
|
/************************************************************
|
|
14501
14501
|
* EV_EXPAND_ALL — expand every already-loaded container
|
|
14502
14502
|
************************************************************/
|
|
14503
|
-
function ac_expand_all$
|
|
14503
|
+
function ac_expand_all$1(gobj, event, kw, src) {
|
|
14504
14504
|
let priv = gobj.priv;
|
|
14505
14505
|
if (priv.root === null || priv.root === void 0) return 0;
|
|
14506
14506
|
let paths = [];
|
|
@@ -14518,7 +14518,7 @@ function ac_expand_all$3(gobj, event, kw, src) {
|
|
|
14518
14518
|
/************************************************************
|
|
14519
14519
|
* EV_COLLAPSE_ALL
|
|
14520
14520
|
************************************************************/
|
|
14521
|
-
function ac_collapse_all$
|
|
14521
|
+
function ac_collapse_all$1(gobj, event, kw, src) {
|
|
14522
14522
|
gobj.priv.expanded.clear();
|
|
14523
14523
|
render_view$1(gobj);
|
|
14524
14524
|
return 0;
|
|
@@ -14703,12 +14703,12 @@ function create_gclass$12(gclass_name) {
|
|
|
14703
14703
|
],
|
|
14704
14704
|
[
|
|
14705
14705
|
"EV_EXPAND_ALL",
|
|
14706
|
-
ac_expand_all$
|
|
14706
|
+
ac_expand_all$1,
|
|
14707
14707
|
null
|
|
14708
14708
|
],
|
|
14709
14709
|
[
|
|
14710
14710
|
"EV_COLLAPSE_ALL",
|
|
14711
|
-
ac_collapse_all$
|
|
14711
|
+
ac_collapse_all$1,
|
|
14712
14712
|
null
|
|
14713
14713
|
],
|
|
14714
14714
|
[
|
|
@@ -19730,7 +19730,7 @@ function ac_toggle_collapse(gobj, event, kw, src) {
|
|
|
19730
19730
|
/************************************************************
|
|
19731
19731
|
* Force every node visible (overrides threshold).
|
|
19732
19732
|
************************************************************/
|
|
19733
|
-
function ac_expand_all
|
|
19733
|
+
function ac_expand_all(gobj, event, kw, src) {
|
|
19734
19734
|
let priv = gobj.priv;
|
|
19735
19735
|
if (!priv.collapse_state) priv.collapse_state = {};
|
|
19736
19736
|
if (priv.node_by_id) for (let id of Object.keys(priv.node_by_id)) {
|
|
@@ -19743,7 +19743,7 @@ function ac_expand_all$2(gobj, event, kw, src) {
|
|
|
19743
19743
|
/************************************************************
|
|
19744
19744
|
* Collapse every node that has children.
|
|
19745
19745
|
************************************************************/
|
|
19746
|
-
function ac_collapse_all
|
|
19746
|
+
function ac_collapse_all(gobj, event, kw, src) {
|
|
19747
19747
|
let priv = gobj.priv;
|
|
19748
19748
|
if (!priv.collapse_state) priv.collapse_state = {};
|
|
19749
19749
|
if (priv.node_by_id) for (let id of Object.keys(priv.node_by_id)) {
|
|
@@ -20095,12 +20095,12 @@ function create_gclass$9(gclass_name) {
|
|
|
20095
20095
|
],
|
|
20096
20096
|
[
|
|
20097
20097
|
"EV_EXPAND_ALL",
|
|
20098
|
-
ac_expand_all
|
|
20098
|
+
ac_expand_all,
|
|
20099
20099
|
null
|
|
20100
20100
|
],
|
|
20101
20101
|
[
|
|
20102
20102
|
"EV_COLLAPSE_ALL",
|
|
20103
|
-
ac_collapse_all
|
|
20103
|
+
ac_collapse_all,
|
|
20104
20104
|
null
|
|
20105
20105
|
],
|
|
20106
20106
|
[
|
|
@@ -27675,7 +27675,9 @@ function fold_build_model(descs, records, opts) {
|
|
|
27675
27675
|
opts = (0, _yuneta_gobj_js.is_object)(opts) ? opts : {};
|
|
27676
27676
|
let hidden = new Set((0, _yuneta_gobj_js.is_array)(opts.hidden_topics) ? opts.hidden_topics : []);
|
|
27677
27677
|
let loose_shown = new Set((0, _yuneta_gobj_js.is_array)(opts.loose_topics) ? opts.loose_topics : []);
|
|
27678
|
-
let main_topic = opts.main_topic ||
|
|
27678
|
+
let main_topic = opts.main_topic || "";
|
|
27679
|
+
if (main_topic && !fold_is_hierarchical(descs, main_topic)) main_topic = "";
|
|
27680
|
+
if (!main_topic) main_topic = fold_main_topic(descs);
|
|
27679
27681
|
if (main_topic && (!descs[main_topic] || hidden.has(main_topic))) main_topic = "";
|
|
27680
27682
|
let linked = fold_linked_topics(descs, main_topic);
|
|
27681
27683
|
let totals = {};
|
|
@@ -27739,7 +27741,7 @@ function fold_build_model(descs, records, opts) {
|
|
|
27739
27741
|
for (let k of reach_from(nodes, [node.key])) reached.add(k);
|
|
27740
27742
|
}
|
|
27741
27743
|
for (let topic_name of topics) if (roots[topic_name].length > 0) groups.set(fold_root_group_key(topic_name), roots[topic_name]);
|
|
27742
|
-
|
|
27744
|
+
let model = {
|
|
27743
27745
|
nodes,
|
|
27744
27746
|
groups,
|
|
27745
27747
|
topics,
|
|
@@ -27748,32 +27750,97 @@ function fold_build_model(descs, records, opts) {
|
|
|
27748
27750
|
main_topic,
|
|
27749
27751
|
linked,
|
|
27750
27752
|
loose,
|
|
27751
|
-
loose_shown
|
|
27753
|
+
loose_shown,
|
|
27754
|
+
level_of: null,
|
|
27755
|
+
levels: 0
|
|
27752
27756
|
};
|
|
27757
|
+
count_levels(model);
|
|
27758
|
+
return model;
|
|
27753
27759
|
}
|
|
27754
27760
|
/************************************************************
|
|
27755
|
-
* The
|
|
27756
|
-
*
|
|
27757
|
-
*
|
|
27758
|
-
*
|
|
27759
|
-
*
|
|
27761
|
+
* The LEVELS of the main tree: the roots of the main topic --
|
|
27762
|
+
* and of the topics hung from it, whose roots are the loose
|
|
27763
|
+
* records the reader asked for -- are level 1, their children
|
|
27764
|
+
* level 2, and so on down every hook of every topic that is not
|
|
27765
|
+
* hidden. A node reached by two paths takes the shallowest.
|
|
27766
|
+
*
|
|
27767
|
+
* With no main topic every topic is a tree of its own and all
|
|
27768
|
+
* of them count. A topic the schema does not tie to the main
|
|
27769
|
+
* one is a separate tree, and has no level: the stepper of the
|
|
27770
|
+
* toolbar speaks for the main tree and nothing else, those
|
|
27771
|
+
* trees are opened by their own pills.
|
|
27772
|
+
************************************************************/
|
|
27773
|
+
function count_levels(model) {
|
|
27774
|
+
let level_of = /* @__PURE__ */ new Map();
|
|
27775
|
+
let queue = [];
|
|
27776
|
+
let deepest = 0;
|
|
27777
|
+
for (let topic_name of model.topics) {
|
|
27778
|
+
if (model.main_topic && !model.linked.has(topic_name)) continue;
|
|
27779
|
+
let roots = model.groups.get(fold_root_group_key(topic_name)) || [];
|
|
27780
|
+
for (let key of roots) if (!level_of.has(key)) {
|
|
27781
|
+
level_of.set(key, 1);
|
|
27782
|
+
queue.push(key);
|
|
27783
|
+
}
|
|
27784
|
+
}
|
|
27785
|
+
let head = 0;
|
|
27786
|
+
while (head < queue.length) {
|
|
27787
|
+
let key = queue[head++];
|
|
27788
|
+
let lv = level_of.get(key);
|
|
27789
|
+
if (lv > deepest) deepest = lv;
|
|
27790
|
+
let node = model.nodes.get(key);
|
|
27791
|
+
if (!node) continue;
|
|
27792
|
+
for (let hook of Object.keys(node.hooks)) for (let child of node.hooks[hook]) if (!level_of.has(child)) {
|
|
27793
|
+
level_of.set(child, lv + 1);
|
|
27794
|
+
queue.push(child);
|
|
27795
|
+
}
|
|
27796
|
+
}
|
|
27797
|
+
model.level_of = level_of;
|
|
27798
|
+
model.levels = deepest;
|
|
27799
|
+
}
|
|
27800
|
+
/************************************************************
|
|
27801
|
+
* A HIERARCHICAL topic: one hooked to ITSELF -- places inside
|
|
27802
|
+
* places, groups inside groups, roles inside roles. It is the
|
|
27803
|
+
* only kind of topic a tree can hang from: a topic that only
|
|
27804
|
+
* reaches OTHER topics is a list with children, and making it
|
|
27805
|
+
* the trunk drew the agent's treedb from `yunos` instead of
|
|
27806
|
+
* `realms`.
|
|
27807
|
+
*
|
|
27808
|
+
* (Not the engine's `entity` tier, which is any topic with
|
|
27809
|
+
* hooks AND fkeys: that one sizes a card and says nothing about
|
|
27810
|
+
* where a tree starts.)
|
|
27811
|
+
************************************************************/
|
|
27812
|
+
function fold_is_hierarchical(descs, topic_name) {
|
|
27813
|
+
if (!(0, _yuneta_gobj_js.is_object)(descs) || !descs[topic_name]) return false;
|
|
27814
|
+
return hook_targets(descs, topic_name).has(topic_name);
|
|
27815
|
+
}
|
|
27816
|
+
/************************************************************
|
|
27817
|
+
* The topic the tree hangs from. Only a HIERARCHICAL topic can
|
|
27818
|
+
* be it, and in this order:
|
|
27819
|
+
*
|
|
27820
|
+
* the one the schema MARKS (`main_topic: true` on the topic,
|
|
27821
|
+
* sent by the backend in its desc since SDK 7.19; the first
|
|
27822
|
+
* one in schema order if a schema marks two);
|
|
27823
|
+
* else the one whose hooks reach the most OTHER topics,
|
|
27824
|
+
* schema order breaking a tie.
|
|
27825
|
+
*
|
|
27826
|
+
* "" when no topic is hooked to itself: there is no trunk, and
|
|
27827
|
+
* every topic is a tree of its own. (A pick by the reader comes
|
|
27828
|
+
* first of all, and is fold_build_model's business.)
|
|
27760
27829
|
************************************************************/
|
|
27761
27830
|
function fold_main_topic(descs) {
|
|
27762
27831
|
descs = (0, _yuneta_gobj_js.is_object)(descs) ? descs : {};
|
|
27832
|
+
let candidates = Object.keys(descs).filter((topic_name) => {
|
|
27833
|
+
return topic_name.substring(0, 2) !== "__" && fold_is_hierarchical(descs, topic_name);
|
|
27834
|
+
});
|
|
27835
|
+
for (let topic_name of candidates) if (descs[topic_name].main_topic === true) return topic_name;
|
|
27763
27836
|
let best = "";
|
|
27764
|
-
let best_score =
|
|
27765
|
-
let
|
|
27766
|
-
for (let topic_name of Object.keys(descs)) {
|
|
27767
|
-
if (topic_name.substring(0, 2) === "__") continue;
|
|
27837
|
+
let best_score = -1;
|
|
27838
|
+
for (let topic_name of candidates) {
|
|
27768
27839
|
let reach = hook_targets(descs, topic_name);
|
|
27769
|
-
let self = reach.has(topic_name);
|
|
27770
27840
|
reach.delete(topic_name);
|
|
27771
|
-
|
|
27772
|
-
if (score === 0) continue;
|
|
27773
|
-
if (score > best_score || score === best_score && self && !best_self) {
|
|
27841
|
+
if (reach.size > best_score) {
|
|
27774
27842
|
best = topic_name;
|
|
27775
|
-
best_score =
|
|
27776
|
-
best_self = self;
|
|
27843
|
+
best_score = reach.size;
|
|
27777
27844
|
}
|
|
27778
27845
|
}
|
|
27779
27846
|
return best;
|
|
@@ -27875,14 +27942,6 @@ function fold_show_more(model, state, group_key) {
|
|
|
27875
27942
|
return n;
|
|
27876
27943
|
}
|
|
27877
27944
|
/************************************************************
|
|
27878
|
-
* Every group open on ALL its children. This is the reader
|
|
27879
|
-
* asking for the whole thing; the pages are for the other way in.
|
|
27880
|
-
************************************************************/
|
|
27881
|
-
function fold_expand_all(model, state) {
|
|
27882
|
-
state.shown.clear();
|
|
27883
|
-
for (let [group_key, list] of model.groups) if (list.length > 0) state.shown.set(group_key, list.length);
|
|
27884
|
-
}
|
|
27885
|
-
/************************************************************
|
|
27886
27945
|
* The roots and nothing else -- the first page of each topic's
|
|
27887
27946
|
* roots, the way the graph looks before anything is opened.
|
|
27888
27947
|
************************************************************/
|
|
@@ -27894,40 +27953,51 @@ function fold_collapse_all(model, state) {
|
|
|
27894
27953
|
}
|
|
27895
27954
|
}
|
|
27896
27955
|
/************************************************************
|
|
27897
|
-
*
|
|
27898
|
-
*
|
|
27899
|
-
*
|
|
27900
|
-
*
|
|
27956
|
+
* The toolbar's STEPPER over the levels of the main tree (see
|
|
27957
|
+
* count_levels): level N shows the roots and N-1 levels under
|
|
27958
|
+
* them. A level is a floor of what is open, not a picture that
|
|
27959
|
+
* replaces it:
|
|
27960
|
+
*
|
|
27961
|
+
* opening to N opens, on its first page, every hook of
|
|
27962
|
+
* every node above level N that is folded;
|
|
27963
|
+
* what the reader opened, and every page
|
|
27964
|
+
* already shown, stays
|
|
27965
|
+
* closing to N folds every hook of every node at level N
|
|
27966
|
+
* or below, and touches nothing above it
|
|
27967
|
+
*
|
|
27968
|
+
* A separate tree (a topic not tied to the main one) has no
|
|
27969
|
+
* level, so neither ever touches it.
|
|
27901
27970
|
************************************************************/
|
|
27902
|
-
function
|
|
27903
|
-
|
|
27904
|
-
|
|
27905
|
-
|
|
27906
|
-
|
|
27907
|
-
|
|
27908
|
-
|
|
27909
|
-
|
|
27910
|
-
|
|
27911
|
-
|
|
27912
|
-
}
|
|
27913
|
-
}
|
|
27914
|
-
while (queue.length) {
|
|
27915
|
-
let key = queue.shift();
|
|
27916
|
-
let lv = level.get(key);
|
|
27917
|
-
if (lv >= depth) continue;
|
|
27971
|
+
function fold_level_clamp(model, level) {
|
|
27972
|
+
let top = model.levels > 0 ? model.levels : 1;
|
|
27973
|
+
level = Math.floor(Number(level)) || 1;
|
|
27974
|
+
if (level < 1) return 1;
|
|
27975
|
+
if (level > top) return top;
|
|
27976
|
+
return level;
|
|
27977
|
+
}
|
|
27978
|
+
function fold_open_levels(model, state, level) {
|
|
27979
|
+
for (let [key, lv] of model.level_of) {
|
|
27980
|
+
if (lv >= level) continue;
|
|
27918
27981
|
let node = model.nodes.get(key);
|
|
27919
27982
|
if (!node) continue;
|
|
27920
27983
|
for (let hook of Object.keys(node.hooks)) {
|
|
27921
|
-
let
|
|
27922
|
-
if (
|
|
27923
|
-
state.shown.set(fold_group_key(key, hook), state.page_size);
|
|
27924
|
-
for (let child of children) if (!level.has(child)) {
|
|
27925
|
-
level.set(child, lv + 1);
|
|
27926
|
-
queue.push(child);
|
|
27927
|
-
}
|
|
27984
|
+
let group_key = fold_group_key(key, hook);
|
|
27985
|
+
if (node.hooks[hook].length > 0 && !fold_is_open(state, group_key)) state.shown.set(group_key, state.page_size);
|
|
27928
27986
|
}
|
|
27929
27987
|
}
|
|
27930
27988
|
}
|
|
27989
|
+
function fold_close_levels(model, state, level) {
|
|
27990
|
+
for (let [key, lv] of model.level_of) {
|
|
27991
|
+
if (lv < level) continue;
|
|
27992
|
+
let node = model.nodes.get(key);
|
|
27993
|
+
if (!node) continue;
|
|
27994
|
+
for (let hook of Object.keys(node.hooks)) state.shown.delete(fold_group_key(key, hook));
|
|
27995
|
+
}
|
|
27996
|
+
}
|
|
27997
|
+
function fold_expand_to_level(model, state, level) {
|
|
27998
|
+
fold_collapse_all(model, state);
|
|
27999
|
+
fold_open_levels(model, state, fold_level_clamp(model, level));
|
|
28000
|
+
}
|
|
27931
28001
|
/************************************************************
|
|
27932
28002
|
* The set of node keys on screen, from the roots down through
|
|
27933
28003
|
* every open group -- and only through open groups whose parent
|
|
@@ -55170,8 +55240,9 @@ function ensure_brush_select_owned() {
|
|
|
55170
55240
|
* The graph opens FOLDED, like a JSON viewer.
|
|
55171
55241
|
*
|
|
55172
55242
|
* Every record of every topic is fetched, but only the ones on
|
|
55173
|
-
* screen become G6 nodes: the roots,
|
|
55174
|
-
*
|
|
55243
|
+
* screen become G6 nodes: the roots, and the MAIN tree open to
|
|
55244
|
+
* the reader's level (`fold_level`, `expand_depth` until they
|
|
55245
|
+
* step it), one page (`fold_page_size`) of children per hook. Each
|
|
55175
55246
|
* card carries a pill per hook that has children -- `▸ devices
|
|
55176
55247
|
* 142` -- which opens or folds that hook; an open hook with more
|
|
55177
55248
|
* children than its page ends in a `+N` chip that opens the next
|
|
@@ -55255,13 +55326,13 @@ var NODE_MODES$1 = [
|
|
|
55255
55326
|
"shape"
|
|
55256
55327
|
];
|
|
55257
55328
|
var PILL_SIZE = {
|
|
55258
|
-
|
|
55329
|
+
entity: [200, 30],
|
|
55259
55330
|
extended: [180, 28],
|
|
55260
55331
|
child: [160, 26]
|
|
55261
55332
|
};
|
|
55262
55333
|
var PORT_R_PILL = 6;
|
|
55263
55334
|
var SHAPE_SIZE = {
|
|
55264
|
-
|
|
55335
|
+
entity: 32,
|
|
55265
55336
|
extended: 28,
|
|
55266
55337
|
child: 22
|
|
55267
55338
|
};
|
|
@@ -55349,7 +55420,8 @@ var attrs_table$4 = [
|
|
|
55349
55420
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_LIST, "layout_names", _yuneta_gobj_js.sdata_flag_t.SDF_RD, JSON.stringify(Object.keys(_layouts)), "Available layout names (read-only, for parent to query)"),
|
|
55350
55421
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "hook_port_position", 0, "bottom", "Hook port position"),
|
|
55351
55422
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "fkey_port_position", 0, "top", "Fkey port position"),
|
|
55352
|
-
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_INTEGER, "expand_depth", 0,
|
|
55423
|
+
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_INTEGER, "expand_depth", 0, 1, "Levels open when a treedb loads, until the reader steps (`fold_level`): 1 = the roots alone (the default), 2 = the roots and their children. Every open hook shows its first page"),
|
|
55424
|
+
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_INTEGER, "fold_level", 0, 0, "The level of the MAIN tree the toolbar's stepper stands on: 1 = its roots, N = N-1 levels under them; 0 = `expand_depth`. The host persists it and sends EV_SET_FOLD_LEVEL; it is published back in EV_LEGEND_STATE (`fold`) with the levels the tree has"),
|
|
55353
55425
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_INTEGER, "fold_page_size", 0, 24, "Children of one hook shown per page; the `+N` chip after the page opens the next one"),
|
|
55354
55426
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_LIST, "hidden_topics", 0, "[]", "Topics left out of the tree: no card, no pill counts them, no edge reaches them"),
|
|
55355
55427
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "main_topic", 0, "", "The topic the tree hangs from; empty = deduced (the one whose hooks reach the most others). Its parentless records are the roots; a parentless record of a topic linked to it is LOOSE and shown only on request"),
|
|
@@ -55440,7 +55512,8 @@ var PRIVATE_DATA$4 = {
|
|
|
55440
55512
|
_layout_asked: "",
|
|
55441
55513
|
_nodes_total: 0,
|
|
55442
55514
|
_nodes_placed: 0,
|
|
55443
|
-
expand_depth:
|
|
55515
|
+
expand_depth: 1,
|
|
55516
|
+
fold_level: 0,
|
|
55444
55517
|
fold_page_size: 24,
|
|
55445
55518
|
hidden_topics: null,
|
|
55446
55519
|
main_topic: "",
|
|
@@ -56163,7 +56236,12 @@ function configure_behaviour(gobj) {
|
|
|
56163
56236
|
graph_write_behaviors(gobj, behaviors);
|
|
56164
56237
|
}
|
|
56165
56238
|
/************************************************************
|
|
56166
|
-
* Count hooks and fkeys in topic desc, classify node type
|
|
56239
|
+
* Count hooks and fkeys in topic desc, classify node type:
|
|
56240
|
+
* `child` (no hooks), `extended` (hooks, no fkeys), `entity`
|
|
56241
|
+
* (both). It sizes the card and nothing else. It used to be
|
|
56242
|
+
* called `hierarchical`, and that word means something else now:
|
|
56243
|
+
* a topic hooked to ITSELF, the only kind a tree can hang from
|
|
56244
|
+
* (treedb_fold_model).
|
|
56167
56245
|
************************************************************/
|
|
56168
56246
|
function calculate_hooks_fkeys_counter(desc) {
|
|
56169
56247
|
let cols = desc.cols;
|
|
@@ -56180,7 +56258,7 @@ function calculate_hooks_fkeys_counter(desc) {
|
|
|
56180
56258
|
}
|
|
56181
56259
|
if (desc.hooks_counter === 0) desc.node_treedb_type = "child";
|
|
56182
56260
|
else if (desc.fkeys_counter === 0) desc.node_treedb_type = "extended";
|
|
56183
|
-
else desc.node_treedb_type = "
|
|
56261
|
+
else desc.node_treedb_type = "entity";
|
|
56184
56262
|
}
|
|
56185
56263
|
/************************************************************
|
|
56186
56264
|
* Build ports for a topic desc
|
|
@@ -56553,7 +56631,7 @@ function dress_ports(gobj, style, ports, geometry, topic_defaults, r_default, fi
|
|
|
56553
56631
|
************************************************************/
|
|
56554
56632
|
function pill_shape_of(gobj, desc, record, geometry) {
|
|
56555
56633
|
let priv = gobj.priv;
|
|
56556
|
-
let size = PILL_SIZE[desc.node_treedb_type] || PILL_SIZE.
|
|
56634
|
+
let size = PILL_SIZE[desc.node_treedb_type] || PILL_SIZE.entity;
|
|
56557
56635
|
let ports = build_ports(gobj, desc);
|
|
56558
56636
|
let paint = node_paint_of(gobj, desc, geometry);
|
|
56559
56637
|
let style = {
|
|
@@ -56602,7 +56680,7 @@ function figure_shape_of(gobj, desc, record, geometry, flags) {
|
|
|
56602
56680
|
let dark = priv.theme === "dark";
|
|
56603
56681
|
let f = flags || {};
|
|
56604
56682
|
let tier = desc.node_treedb_type;
|
|
56605
|
-
let side = SHAPE_SIZE[tier] || SHAPE_SIZE.
|
|
56683
|
+
let side = SHAPE_SIZE[tier] || SHAPE_SIZE.entity;
|
|
56606
56684
|
let labels = (0, _yuneta_gobj_js.gobj_read_bool_attr)(gobj, "node_labels");
|
|
56607
56685
|
let figure = node_figure_of(gobj, desc, geometry || {});
|
|
56608
56686
|
let paint = node_paint_of(gobj, desc, geometry);
|
|
@@ -59668,7 +59746,7 @@ function show_node_detail_popover(gobj, node_id) {
|
|
|
59668
59746
|
clamp_popover_position(gobj, popover);
|
|
59669
59747
|
}
|
|
59670
59748
|
/************************************************************
|
|
59671
|
-
* Re-render every HTML (
|
|
59749
|
+
* Re-render every HTML (entity) node so its card adopts
|
|
59672
59750
|
* the given theme: entity cards and leaf chips (baked innerHTML,
|
|
59673
59751
|
* not re-themed by setTheme()) are regenerated; structural
|
|
59674
59752
|
* junction diamonds get their neutral fill/stroke re-themed.
|
|
@@ -59787,7 +59865,7 @@ function refresh_minimap(gobj) {
|
|
|
59787
59865
|
}
|
|
59788
59866
|
/************************************************************
|
|
59789
59867
|
* The innerHTML of ONE node, in the given theme and highlight state.
|
|
59790
|
-
* The three treedb tiers (
|
|
59868
|
+
* The three treedb tiers (entity / extended / child) each have
|
|
59791
59869
|
* their own card, and both the theme refresh and the highlight need the
|
|
59792
59870
|
* same three-way choice — it lived inline in the theme refresh and is
|
|
59793
59871
|
* shared now. Returns null for a node that carries no desc.
|
|
@@ -59804,7 +59882,7 @@ function node_innerHTML_of(nd, theme, highlight, selected, anchored, pills_html)
|
|
|
59804
59882
|
switch (desc.node_treedb_type) {
|
|
59805
59883
|
case "child": return build_chip_innerHTML(fill, theme, record.icon, label, record.id, highlight, selected, anchored);
|
|
59806
59884
|
case "extended": return build_node_innerHTML(fill, theme, record.icon, label, desc.topic_name, true, record.id, highlight, selected, anchored, pills_html);
|
|
59807
|
-
case "
|
|
59885
|
+
case "entity": return build_node_innerHTML(fill, theme, record.icon, label, desc.topic_name, false, record.id, highlight, selected, anchored, pills_html);
|
|
59808
59886
|
}
|
|
59809
59887
|
return null;
|
|
59810
59888
|
}
|
|
@@ -60001,7 +60079,7 @@ function build_chip_innerHTML(color, theme, icon, label, key, highlight, selecte
|
|
|
60001
60079
|
`;
|
|
60002
60080
|
}
|
|
60003
60081
|
/************************************************************
|
|
60004
|
-
* Build innerHTML for
|
|
60082
|
+
* Build innerHTML for entity (HTML) nodes.
|
|
60005
60083
|
*
|
|
60006
60084
|
* Card style modelled on the documentation schema graphs
|
|
60007
60085
|
* (docs gen_treedb_graphs.py): rounded card, soft tint of the
|
|
@@ -61319,13 +61397,19 @@ function publish_legend_state(gobj, visible) {
|
|
|
61319
61397
|
loose: loose.length,
|
|
61320
61398
|
loose_shown: model.loose_shown.has(topic_name),
|
|
61321
61399
|
hidden: model.hidden.has(topic_name),
|
|
61322
|
-
linked: model.linked.has(topic_name)
|
|
61400
|
+
linked: model.linked.has(topic_name),
|
|
61401
|
+
hierarchical: fold_is_hierarchical(priv.descs, topic_name)
|
|
61323
61402
|
});
|
|
61324
61403
|
}
|
|
61325
61404
|
(0, _yuneta_gobj_js.gobj_publish_event)(gobj, "EV_LEGEND_STATE", {
|
|
61326
61405
|
main_topic: model.main_topic,
|
|
61327
|
-
main_chosen: !!(0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "main_topic"),
|
|
61328
|
-
topics
|
|
61406
|
+
main_chosen: !!model.main_topic && (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "main_topic") === model.main_topic,
|
|
61407
|
+
topics,
|
|
61408
|
+
fold: {
|
|
61409
|
+
topic: model.main_topic,
|
|
61410
|
+
level: current_fold_level(gobj),
|
|
61411
|
+
levels: model.levels
|
|
61412
|
+
}
|
|
61329
61413
|
});
|
|
61330
61414
|
}
|
|
61331
61415
|
async function reconcile_fold_apply(gobj, opts, visible) {
|
|
@@ -61630,7 +61714,7 @@ function ac_load_data(gobj, event, kw, src) {
|
|
|
61630
61714
|
}
|
|
61631
61715
|
if (all_loaded && priv.graph) {
|
|
61632
61716
|
rebuild_fold_model(gobj);
|
|
61633
|
-
|
|
61717
|
+
fold_expand_to_level(priv._fold_model, priv._fold_state, current_fold_level(gobj));
|
|
61634
61718
|
count_placed_records(gobj);
|
|
61635
61719
|
let auto_laid = false;
|
|
61636
61720
|
try {
|
|
@@ -62034,19 +62118,46 @@ function ac_show_more(gobj, event, kw, src) {
|
|
|
62034
62118
|
return 0;
|
|
62035
62119
|
}
|
|
62036
62120
|
/************************************************************
|
|
62037
|
-
* The
|
|
62038
|
-
*
|
|
62039
|
-
* the
|
|
62121
|
+
* The level of the main tree the toolbar's stepper stands on:
|
|
62122
|
+
* `fold_level` once the reader has stepped, `expand_depth`
|
|
62123
|
+
* until then, clamped to the levels the tree has.
|
|
62040
62124
|
************************************************************/
|
|
62041
|
-
function
|
|
62125
|
+
function current_fold_level(gobj) {
|
|
62042
62126
|
let priv = gobj.priv;
|
|
62043
|
-
|
|
62044
|
-
|
|
62127
|
+
let level = (0, _yuneta_gobj_js.gobj_read_integer_attr)(gobj, "fold_level");
|
|
62128
|
+
if (!(level > 0)) level = (0, _yuneta_gobj_js.gobj_read_integer_attr)(gobj, "expand_depth");
|
|
62129
|
+
if (!priv._fold_model) return level;
|
|
62130
|
+
return fold_level_clamp(priv._fold_model, level);
|
|
62131
|
+
}
|
|
62132
|
+
/************************************************************
|
|
62133
|
+
* The toolbar's stepper: one level more or one less of the
|
|
62134
|
+
* MAIN tree (the host owns the number and persists it; this
|
|
62135
|
+
* applies it). Deeper opens the hooks above the new level,
|
|
62136
|
+
* shallower folds from it down -- a level is a floor, not a
|
|
62137
|
+
* picture, so what the reader opened by its pill stays (see
|
|
62138
|
+
* treedb_fold_model). Replaces expand all / collapse all
|
|
62139
|
+
* (7.23.141): the whole treedb at once was the pile, and
|
|
62140
|
+
* closing threw away everything the reader had opened.
|
|
62141
|
+
************************************************************/
|
|
62142
|
+
function ac_set_fold_level(gobj, event, kw, src) {
|
|
62143
|
+
let priv = gobj.priv;
|
|
62144
|
+
let level = Number(kw && kw.level);
|
|
62145
|
+
if (!(level > 0)) {
|
|
62146
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: fold level '${kw && kw.level}' is not a level`);
|
|
62045
62147
|
return -1;
|
|
62046
62148
|
}
|
|
62149
|
+
if (!priv._fold_model) {
|
|
62150
|
+
(0, _yuneta_gobj_js.gobj_write_attr)(gobj, "fold_level", level);
|
|
62151
|
+
return 0;
|
|
62152
|
+
}
|
|
62153
|
+
let from = current_fold_level(gobj);
|
|
62154
|
+
level = fold_level_clamp(priv._fold_model, level);
|
|
62155
|
+
(0, _yuneta_gobj_js.gobj_write_attr)(gobj, "fold_level", level);
|
|
62156
|
+
if (level === from) return 0;
|
|
62047
62157
|
let keep = fold_keep_node(gobj);
|
|
62048
62158
|
let vp = yui_graph_viewport_of(priv.graph, keep);
|
|
62049
|
-
|
|
62159
|
+
if (level > from) fold_open_levels(priv._fold_model, priv._fold_state, level);
|
|
62160
|
+
else fold_close_levels(priv._fold_model, priv._fold_state, level);
|
|
62050
62161
|
reconcile_fold(gobj, {
|
|
62051
62162
|
keep,
|
|
62052
62163
|
keep_vp: vp
|
|
@@ -62074,29 +62185,11 @@ function fold_keep_node(gobj) {
|
|
|
62074
62185
|
return "";
|
|
62075
62186
|
}
|
|
62076
62187
|
/************************************************************
|
|
62077
|
-
* The roots alone.
|
|
62078
|
-
************************************************************/
|
|
62079
|
-
function ac_collapse_all$1(gobj, event, kw, src) {
|
|
62080
|
-
let priv = gobj.priv;
|
|
62081
|
-
if (!priv._fold_model) {
|
|
62082
|
-
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: collapse all with no tree loaded`);
|
|
62083
|
-
return -1;
|
|
62084
|
-
}
|
|
62085
|
-
let keep = fold_keep_node(gobj);
|
|
62086
|
-
let vp = yui_graph_viewport_of(priv.graph, keep);
|
|
62087
|
-
fold_collapse_all(priv._fold_model, priv._fold_state);
|
|
62088
|
-
reconcile_fold(gobj, {
|
|
62089
|
-
keep,
|
|
62090
|
-
keep_vp: vp
|
|
62091
|
-
});
|
|
62092
|
-
return 0;
|
|
62093
|
-
}
|
|
62094
|
-
/************************************************************
|
|
62095
62188
|
* The legend's three settings, from the host, which persists
|
|
62096
62189
|
* them. Each rebuilds the tree; the fold state is kept -- it is
|
|
62097
62190
|
* keyed by group, and a group that is gone is never read -- except
|
|
62098
62191
|
* for a new MAIN topic, whose roots are other roots: the tree
|
|
62099
|
-
* opens again at
|
|
62192
|
+
* opens again at the reader's level, now counted from them.
|
|
62100
62193
|
************************************************************/
|
|
62101
62194
|
function ac_set_hidden_topics(gobj, event, kw, src) {
|
|
62102
62195
|
let priv = gobj.priv;
|
|
@@ -62114,7 +62207,7 @@ function ac_set_main_topic(gobj, event, kw, src) {
|
|
|
62114
62207
|
let keep = fold_keep_node(gobj);
|
|
62115
62208
|
let vp = yui_graph_viewport_of(priv.graph, keep);
|
|
62116
62209
|
rebuild_fold_model(gobj);
|
|
62117
|
-
|
|
62210
|
+
fold_expand_to_level(priv._fold_model, priv._fold_state, current_fold_level(gobj));
|
|
62118
62211
|
reconcile_fold(gobj, {
|
|
62119
62212
|
relayout: true,
|
|
62120
62213
|
keep,
|
|
@@ -62675,13 +62768,8 @@ function create_gclass$4(gclass_name) {
|
|
|
62675
62768
|
null
|
|
62676
62769
|
],
|
|
62677
62770
|
[
|
|
62678
|
-
"
|
|
62679
|
-
|
|
62680
|
-
null
|
|
62681
|
-
],
|
|
62682
|
-
[
|
|
62683
|
-
"EV_COLLAPSE_ALL",
|
|
62684
|
-
ac_collapse_all$1,
|
|
62771
|
+
"EV_SET_FOLD_LEVEL",
|
|
62772
|
+
ac_set_fold_level,
|
|
62685
62773
|
null
|
|
62686
62774
|
],
|
|
62687
62775
|
[
|
|
@@ -62824,8 +62912,7 @@ function create_gclass$4(gclass_name) {
|
|
|
62824
62912
|
["EV_CAMERA_CHANGED", _yuneta_gobj_js.event_flag_t.EVF_OUTPUT_EVENT | _yuneta_gobj_js.event_flag_t.EVF_NO_WARN_SUBS],
|
|
62825
62913
|
["EV_TOGGLE_FOLD", 0],
|
|
62826
62914
|
["EV_SHOW_MORE", 0],
|
|
62827
|
-
["
|
|
62828
|
-
["EV_COLLAPSE_ALL", 0],
|
|
62915
|
+
["EV_SET_FOLD_LEVEL", 0],
|
|
62829
62916
|
["EV_SET_HIDDEN_TOPICS", 0],
|
|
62830
62917
|
["EV_SET_MAIN_TOPIC", 0],
|
|
62831
62918
|
["EV_SET_LOOSE_TOPICS", 0],
|
|
@@ -62892,7 +62979,7 @@ var attrs_table$3 = [
|
|
|
62892
62979
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_POINTER, "subscriber", 0, null, "Subscriber of output events"),
|
|
62893
62980
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_LIST, "operation_modes", 0, "[\"reading\", \"operation\", \"writing\", \"edition\"]", "Available **permission** or behaviour modes. These operation modes are required to be accomplish by the graph handler (G6 child). TODO permissions must match treedb permissions."),
|
|
62894
62981
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_BOOLEAN, "with_treedb_tables", 0, false, "Include treedb tables"),
|
|
62895
|
-
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_INTEGER, "expand_depth", 0,
|
|
62982
|
+
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_INTEGER, "expand_depth", 0, 1, "Levels of the treedb open when it loads, until the reader steps (`fold_level`): 1 = the roots alone (the default), 2 = the roots and their children. Forwarded to the G6 child"),
|
|
62896
62983
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_INTEGER, "fold_page_size", 0, 24, "Children of one hook shown per page in the graph; a `+N` chip opens the next page. Forwarded to the G6 child"),
|
|
62897
62984
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_INTEGER, "minimap_min_nodes", 0, 30, "Show the minimap from this many nodes on (0 = never). Forwarded to the G6 child"),
|
|
62898
62985
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_BOOLEAN, "with_gridline", 0, true, "Draw the grid under the graph. Forwarded to the G6 child"),
|
|
@@ -62909,6 +62996,7 @@ var attrs_table$3 = [
|
|
|
62909
62996
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "node_mode", _yuneta_gobj_js.sdata_flag_t.SDF_PERSIST, "expanded", "How the records are drawn: `expanded` = the cards with their pills and ports, `compact` = one-line pills with the name, `shape` = coloured figures, the topology alone. User preference"),
|
|
62910
62997
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_BOOLEAN, "node_labels", _yuneta_gobj_js.sdata_flag_t.SDF_PERSIST, true, "A `shape` node says its name under its figure. User preference"),
|
|
62911
62998
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_DICT, "camera", _yuneta_gobj_js.sdata_flag_t.SDF_PERSIST, "{}", "Where the reader left the viewport: {zoom, x, y}. Handed to the engine on creation and written back when a move settles, so the graph opens where it was left. User preference, per treedb"),
|
|
62999
|
+
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_INTEGER, "fold_level", _yuneta_gobj_js.sdata_flag_t.SDF_PERSIST, 0, "The level of the MAIN tree the toolbar's stepper stands on: 1 = the main topic's roots, N = N-1 levels under them; 0 = never stepped, `expand_depth`. Handed to the engine on creation, so the graph opens at the level it was left. User preference, per treedb"),
|
|
62912
63000
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_POINTER, "gobj_remote_yuno", 0, null, "Remote Yuno to request data"),
|
|
62913
63001
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_STRING, "treedb_name", 0, null, "Remote service treedb name"),
|
|
62914
63002
|
(0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_DICT, "descs", 0, null, "Descriptions of topics obtained"),
|
|
@@ -62984,6 +63072,7 @@ function mt_create$3(gobj) {
|
|
|
62984
63072
|
hook_port_position: "bottom",
|
|
62985
63073
|
fkey_port_position: "top",
|
|
62986
63074
|
expand_depth: (0, _yuneta_gobj_js.gobj_read_integer_attr)(gobj, "expand_depth"),
|
|
63075
|
+
fold_level: (0, _yuneta_gobj_js.gobj_read_integer_attr)(gobj, "fold_level"),
|
|
62987
63076
|
fold_page_size: (0, _yuneta_gobj_js.gobj_read_integer_attr)(gobj, "fold_page_size"),
|
|
62988
63077
|
minimap_min_nodes: (0, _yuneta_gobj_js.gobj_read_integer_attr)(gobj, "minimap_min_nodes"),
|
|
62989
63078
|
with_gridline: (0, _yuneta_gobj_js.gobj_read_bool_attr)(gobj, "with_gridline"),
|
|
@@ -63291,6 +63380,127 @@ function refresh_node_shape_buttons(gobj, $root) {
|
|
|
63291
63380
|
$labels.disabled = mode !== "shape";
|
|
63292
63381
|
}
|
|
63293
63382
|
}
|
|
63383
|
+
/************************************************************
|
|
63384
|
+
* The fold STEPPER: one level less, where the tree stands, one
|
|
63385
|
+
* level more.
|
|
63386
|
+
*
|
|
63387
|
+
* It replaces the fold pair (7.23.141). `expand all` opened every
|
|
63388
|
+
* hook of the treedb -- the pile, on purpose, which on a treedb
|
|
63389
|
+
* of thousands is a pile nobody reads -- and `collapse all` threw
|
|
63390
|
+
* away everything the reader had opened. The stepper walks the
|
|
63391
|
+
* MAIN tree a level at a time, the way the frontend view opens
|
|
63392
|
+
* one level per press: `+` opens the next level under the main
|
|
63393
|
+
* topic's roots, through every topic that is not hidden; `-`
|
|
63394
|
+
* folds the deepest one. Pages and pills the reader opened stay.
|
|
63395
|
+
*
|
|
63396
|
+
* The readout says what the two buttons act on, which no chevron
|
|
63397
|
+
* can: the main topic -- its swatch and its name, which is DATA
|
|
63398
|
+
* and never translated -- and `level/levels`. On a phone the name
|
|
63399
|
+
* goes and the numbers stay. The level is the reader's, per
|
|
63400
|
+
* treedb: persisted (`fold_level`) and handed to the engine on
|
|
63401
|
+
* creation, so a reload opens where it was left.
|
|
63402
|
+
*
|
|
63403
|
+
* Both buttons are born disabled: nothing can be stepped until
|
|
63404
|
+
* the engine has said how deep the tree goes (EV_LEGEND_STATE).
|
|
63405
|
+
************************************************************/
|
|
63406
|
+
function fold_level_items(gobj, wide) {
|
|
63407
|
+
let step_button = (cls, icon, key, event_name) => {
|
|
63408
|
+
return [
|
|
63409
|
+
"button",
|
|
63410
|
+
{
|
|
63411
|
+
class: `${cls} button`,
|
|
63412
|
+
type: "button",
|
|
63413
|
+
style: {
|
|
63414
|
+
height: wide,
|
|
63415
|
+
width: "2.5em"
|
|
63416
|
+
},
|
|
63417
|
+
disabled: true,
|
|
63418
|
+
title: (0, i18next.t)(key),
|
|
63419
|
+
"data-i18n-title": key,
|
|
63420
|
+
"aria-label": (0, i18next.t)(key),
|
|
63421
|
+
"data-i18n-aria-label": key
|
|
63422
|
+
},
|
|
63423
|
+
yui_toolbar_icon(icon),
|
|
63424
|
+
{ click: (evt) => {
|
|
63425
|
+
evt.stopPropagation();
|
|
63426
|
+
(0, _yuneta_gobj_js.gobj_send_event)(gobj, event_name, {}, gobj);
|
|
63427
|
+
} }
|
|
63428
|
+
];
|
|
63429
|
+
};
|
|
63430
|
+
return [[
|
|
63431
|
+
"div",
|
|
63432
|
+
{
|
|
63433
|
+
class: "GRAPH_FOLD_STEPPER buttons has-addons",
|
|
63434
|
+
style: "margin:0; flex:0 0 auto; flex-wrap:nowrap; align-items:stretch;"
|
|
63435
|
+
},
|
|
63436
|
+
[
|
|
63437
|
+
step_button("GRAPH_FOLD_COLLAPSE", "yi-chevron-right", "collapse one level", "EV_COLLAPSE_LEVEL"),
|
|
63438
|
+
[
|
|
63439
|
+
"div",
|
|
63440
|
+
{
|
|
63441
|
+
class: "GRAPH_FOLD_LEVEL button",
|
|
63442
|
+
style: {
|
|
63443
|
+
height: wide,
|
|
63444
|
+
cursor: "default",
|
|
63445
|
+
gap: ".35rem"
|
|
63446
|
+
},
|
|
63447
|
+
role: "status",
|
|
63448
|
+
title: (0, i18next.t)("fold level"),
|
|
63449
|
+
"data-i18n-title": "fold level"
|
|
63450
|
+
},
|
|
63451
|
+
[
|
|
63452
|
+
["span", {
|
|
63453
|
+
class: "GRAPH_FOLD_SWATCH",
|
|
63454
|
+
style: "display:none; width:.8rem; height:.8rem; border-radius:3px; flex:0 0 auto; border:1px solid rgba(0,0,0,.25);"
|
|
63455
|
+
}],
|
|
63456
|
+
["span", {
|
|
63457
|
+
class: "GRAPH_FOLD_TOPIC is-hidden-mobile",
|
|
63458
|
+
style: "max-width:10em; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-weight:600;"
|
|
63459
|
+
}],
|
|
63460
|
+
[
|
|
63461
|
+
"span",
|
|
63462
|
+
{
|
|
63463
|
+
class: "GRAPH_FOLD_WORD",
|
|
63464
|
+
i18n: "level"
|
|
63465
|
+
},
|
|
63466
|
+
"level"
|
|
63467
|
+
],
|
|
63468
|
+
[
|
|
63469
|
+
"span",
|
|
63470
|
+
{
|
|
63471
|
+
class: "GRAPH_FOLD_COUNT",
|
|
63472
|
+
style: "font-variant-numeric:tabular-nums;"
|
|
63473
|
+
},
|
|
63474
|
+
"–"
|
|
63475
|
+
]
|
|
63476
|
+
]
|
|
63477
|
+
],
|
|
63478
|
+
step_button("GRAPH_FOLD_EXPAND", "yi-chevron-down", "expand one level", "EV_EXPAND_LEVEL")
|
|
63479
|
+
]
|
|
63480
|
+
]];
|
|
63481
|
+
}
|
|
63482
|
+
function refresh_fold_level(gobj) {
|
|
63483
|
+
let priv = gobj.priv;
|
|
63484
|
+
let $container = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "$container");
|
|
63485
|
+
if (!$container) return;
|
|
63486
|
+
let $readout = $container.querySelector(".GRAPH_FOLD_LEVEL");
|
|
63487
|
+
if (!$readout) return;
|
|
63488
|
+
let state = priv._legend_state || {};
|
|
63489
|
+
let fold = state.fold || {};
|
|
63490
|
+
let levels = fold.levels > 0 ? fold.levels : 0;
|
|
63491
|
+
let level = fold.level > 0 ? fold.level : 0;
|
|
63492
|
+
let topic = fold.topic || "";
|
|
63493
|
+
let entry = ((0, _yuneta_gobj_js.is_array)(state.topics) ? state.topics : []).find((e) => e.topic === topic);
|
|
63494
|
+
let $swatch = $readout.querySelector(".GRAPH_FOLD_SWATCH");
|
|
63495
|
+
$swatch.style.display = topic ? "inline-block" : "none";
|
|
63496
|
+
$swatch.style.background = entry && entry.color || "#94a3b8";
|
|
63497
|
+
$readout.querySelector(".GRAPH_FOLD_TOPIC").textContent = topic;
|
|
63498
|
+
$readout.querySelector(".GRAPH_FOLD_COUNT").textContent = levels ? `${level}/${levels}` : "–";
|
|
63499
|
+
let $collapse = $container.querySelector(".GRAPH_FOLD_COLLAPSE");
|
|
63500
|
+
let $expand = $container.querySelector(".GRAPH_FOLD_EXPAND");
|
|
63501
|
+
if ($collapse) $collapse.disabled = !(levels && level > 1);
|
|
63502
|
+
if ($expand) $expand.disabled = !(levels && level < levels);
|
|
63503
|
+
}
|
|
63294
63504
|
function make_toolbar(gobj) {
|
|
63295
63505
|
let priv = gobj.priv;
|
|
63296
63506
|
let modes = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "operation_modes");
|
|
@@ -63357,7 +63567,7 @@ function make_toolbar(gobj) {
|
|
|
63357
63567
|
} }
|
|
63358
63568
|
]
|
|
63359
63569
|
];
|
|
63360
|
-
let center_items = [...
|
|
63570
|
+
let center_items = [...fold_level_items(gobj, (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "wide")), ...node_shape_items(gobj, (0, _yuneta_gobj_js.gobj_read_str_attr)(gobj, "wide"))];
|
|
63361
63571
|
let backend_items = [[
|
|
63362
63572
|
"button",
|
|
63363
63573
|
{
|
|
@@ -64420,6 +64630,7 @@ function refresh_legend(gobj) {
|
|
|
64420
64630
|
let topics = state.topics.slice().sort((a, b) => {
|
|
64421
64631
|
return String(a.topic).localeCompare(String(b.topic));
|
|
64422
64632
|
});
|
|
64633
|
+
let hierarchical_count = topics.filter((e) => e.hierarchical && !e.hidden).length;
|
|
64423
64634
|
for (let entry of topics) {
|
|
64424
64635
|
let topic_name = entry.topic;
|
|
64425
64636
|
let is_main = topic_name === state.main_topic;
|
|
@@ -64514,7 +64725,7 @@ function refresh_legend(gobj) {
|
|
|
64514
64725
|
"★"
|
|
64515
64726
|
]]
|
|
64516
64727
|
]);
|
|
64517
|
-
else if (!hidden) extras.push([
|
|
64728
|
+
else if (!hidden && entry.hierarchical && hierarchical_count > 1) extras.push([
|
|
64518
64729
|
"button",
|
|
64519
64730
|
{
|
|
64520
64731
|
class: "GRAPH_LEGEND_STAR button",
|
|
@@ -64613,6 +64824,7 @@ function ac_legend_state(gobj, event, kw, src) {
|
|
|
64613
64824
|
let priv = gobj.priv;
|
|
64614
64825
|
priv._legend_state = kw || null;
|
|
64615
64826
|
refresh_legend(gobj);
|
|
64827
|
+
refresh_fold_level(gobj);
|
|
64616
64828
|
return 0;
|
|
64617
64829
|
}
|
|
64618
64830
|
/************************************************************
|
|
@@ -64725,17 +64937,33 @@ function ac_find_nodes(gobj, event, kw, src) {
|
|
|
64725
64937
|
return 0;
|
|
64726
64938
|
}
|
|
64727
64939
|
/************************************************************
|
|
64728
|
-
*
|
|
64729
|
-
*
|
|
64940
|
+
* One press of the fold stepper (EV_EXPAND_LEVEL /
|
|
64941
|
+
* EV_COLLAPSE_LEVEL): the level moves by one, is SAVED (the
|
|
64942
|
+
* reader's, per treedb) and reaches the G6 child, which owns
|
|
64943
|
+
* the tree.
|
|
64944
|
+
*
|
|
64945
|
+
* The readout moves at once, not when the engine speaks again:
|
|
64946
|
+
* a reconcile is asynchronous, and a second press that came
|
|
64947
|
+
* before it would step from the level already left -- two
|
|
64948
|
+
* presses, one level.
|
|
64730
64949
|
************************************************************/
|
|
64731
|
-
function
|
|
64732
|
-
let priv = gobj.priv;
|
|
64733
|
-
if (priv.gobj_nodes_tree) (0, _yuneta_gobj_js.gobj_send_event)(priv.gobj_nodes_tree, "EV_EXPAND_ALL", {}, gobj);
|
|
64734
|
-
return 0;
|
|
64735
|
-
}
|
|
64736
|
-
function ac_collapse_all(gobj, event, kw, src) {
|
|
64950
|
+
function ac_fold_level_step(gobj, event, kw, src) {
|
|
64737
64951
|
let priv = gobj.priv;
|
|
64738
|
-
|
|
64952
|
+
let fold = priv._legend_state && priv._legend_state.fold;
|
|
64953
|
+
if (!fold || !(fold.levels > 0)) {
|
|
64954
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: ${event} with no tree to step through`);
|
|
64955
|
+
return -1;
|
|
64956
|
+
}
|
|
64957
|
+
let level = fold.level + (event === "EV_EXPAND_LEVEL" ? 1 : -1);
|
|
64958
|
+
if (level < 1 || level > fold.levels) {
|
|
64959
|
+
(0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: ${event}: level ${level} out of 1..${fold.levels}`);
|
|
64960
|
+
return -1;
|
|
64961
|
+
}
|
|
64962
|
+
(0, _yuneta_gobj_js.gobj_write_attr)(gobj, "fold_level", level);
|
|
64963
|
+
(0, _yuneta_gobj_js.gobj_save_persistent_attrs)(gobj, "fold_level");
|
|
64964
|
+
fold.level = level;
|
|
64965
|
+
refresh_fold_level(gobj);
|
|
64966
|
+
if (priv.gobj_nodes_tree) (0, _yuneta_gobj_js.gobj_send_event)(priv.gobj_nodes_tree, "EV_SET_FOLD_LEVEL", { level }, gobj);
|
|
64739
64967
|
return 0;
|
|
64740
64968
|
}
|
|
64741
64969
|
/************************************************************
|
|
@@ -64972,13 +65200,13 @@ function create_gclass$3(gclass_name) {
|
|
|
64972
65200
|
null
|
|
64973
65201
|
],
|
|
64974
65202
|
[
|
|
64975
|
-
"
|
|
64976
|
-
|
|
65203
|
+
"EV_EXPAND_LEVEL",
|
|
65204
|
+
ac_fold_level_step,
|
|
64977
65205
|
null
|
|
64978
65206
|
],
|
|
64979
65207
|
[
|
|
64980
|
-
"
|
|
64981
|
-
|
|
65208
|
+
"EV_COLLAPSE_LEVEL",
|
|
65209
|
+
ac_fold_level_step,
|
|
64982
65210
|
null
|
|
64983
65211
|
],
|
|
64984
65212
|
[
|
|
@@ -65063,8 +65291,8 @@ function create_gclass$3(gclass_name) {
|
|
|
65063
65291
|
["EV_SET_OPERATION_MODE", 0],
|
|
65064
65292
|
["EV_SET_FOCUS_TOPIC", 0],
|
|
65065
65293
|
["EV_FIND_NODES", 0],
|
|
65066
|
-
["
|
|
65067
|
-
["
|
|
65294
|
+
["EV_EXPAND_LEVEL", 0],
|
|
65295
|
+
["EV_COLLAPSE_LEVEL", 0],
|
|
65068
65296
|
["EV_SET_NODE_MODE", 0],
|
|
65069
65297
|
["EV_TOGGLE_NODE_LABELS", 0],
|
|
65070
65298
|
["EV_FIND_RESULT", 0],
|
|
@@ -65846,7 +66074,7 @@ function sort_by_order(list) {
|
|
|
65846
66074
|
* schema_version, c_schema_version, system_schema_version,
|
|
65847
66075
|
* topics: [{
|
|
65848
66076
|
* id, name, order, record,
|
|
65849
|
-
* pkey, topic_version, system_topic,
|
|
66077
|
+
* pkey, topic_version, system_topic, main_topic,
|
|
65850
66078
|
* cols: [{id, name, order, record}]
|
|
65851
66079
|
* }]
|
|
65852
66080
|
* }],
|
|
@@ -65895,6 +66123,7 @@ function build_schema_model(records) {
|
|
|
65895
66123
|
tkey: record.tkey || "",
|
|
65896
66124
|
topic_version: record.topic_version,
|
|
65897
66125
|
system_topic: !!record.system_topic,
|
|
66126
|
+
main_topic: !!record.main_topic,
|
|
65898
66127
|
cols: []
|
|
65899
66128
|
};
|
|
65900
66129
|
by_topic_id[entry.id] = entry;
|
|
@@ -66191,6 +66420,12 @@ function validate_schema(treedb, options) {
|
|
|
66191
66420
|
if (is_fkey && FKEY_TYPES.indexOf(type) < 0) add("error", "fkey has a bad type", topic.name, col.name, type);
|
|
66192
66421
|
}
|
|
66193
66422
|
}
|
|
66423
|
+
let marked = treedb.topics.filter((topic) => topic.main_topic);
|
|
66424
|
+
if (marked.length > 1) add("error", "more than one main topic", marked[1].name, "", marked.map((topic) => topic.name).join(", "));
|
|
66425
|
+
for (let topic of marked) if (!topic.cols.some((col) => {
|
|
66426
|
+
let hook = col_hook(col.record);
|
|
66427
|
+
return col_flags(col.record).indexOf("hook") >= 0 && !!hook && Object.prototype.hasOwnProperty.call(hook, topic.name);
|
|
66428
|
+
})) add("error", "main topic not hooked to itself", topic.name, "", "");
|
|
66194
66429
|
let hooked = {};
|
|
66195
66430
|
for (let topic of treedb.topics) for (let col of topic.cols) {
|
|
66196
66431
|
let hook = col_hook(col.record);
|
|
@@ -66382,7 +66617,8 @@ var TOPIC_KEY_ORDER = [
|
|
|
66382
66617
|
"system_flag",
|
|
66383
66618
|
"tkey",
|
|
66384
66619
|
"topic_version",
|
|
66385
|
-
"system_topic"
|
|
66620
|
+
"system_topic",
|
|
66621
|
+
"main_topic"
|
|
66386
66622
|
];
|
|
66387
66623
|
var COL_KEY_ORDER = [
|
|
66388
66624
|
"header",
|
|
@@ -66640,7 +66876,8 @@ var TOPIC_FIELDS = [
|
|
|
66640
66876
|
"system_flag",
|
|
66641
66877
|
"tkey",
|
|
66642
66878
|
"topic_version",
|
|
66643
|
-
"system_topic"
|
|
66879
|
+
"system_topic",
|
|
66880
|
+
"main_topic"
|
|
66644
66881
|
];
|
|
66645
66882
|
var COL_FIELDS = [
|
|
66646
66883
|
"header",
|
|
@@ -68257,6 +68494,20 @@ function render_topics(gobj, $body) {
|
|
|
68257
68494
|
{},
|
|
68258
68495
|
""
|
|
68259
68496
|
],
|
|
68497
|
+
topic.main_topic ? [
|
|
68498
|
+
"span",
|
|
68499
|
+
{
|
|
68500
|
+
class: "SCHEMA_TOPIC_MAIN ml-2",
|
|
68501
|
+
style: "color:#d4a017;",
|
|
68502
|
+
title: (0, i18next.t)("main topic"),
|
|
68503
|
+
"data-i18n-title": "main topic"
|
|
68504
|
+
},
|
|
68505
|
+
"★"
|
|
68506
|
+
] : [
|
|
68507
|
+
"span",
|
|
68508
|
+
{},
|
|
68509
|
+
""
|
|
68510
|
+
],
|
|
68260
68511
|
ambiguous ? [
|
|
68261
68512
|
"div",
|
|
68262
68513
|
{ class: "SCHEMA_TOPIC_ID is-size-7 yui-text-quiet" },
|
|
@@ -69251,6 +69502,26 @@ function open_topic_form(gobj, treedb, topic) {
|
|
|
69251
69502
|
]]
|
|
69252
69503
|
]]
|
|
69253
69504
|
],
|
|
69505
|
+
[
|
|
69506
|
+
"div",
|
|
69507
|
+
{ class: "SCHEMA_TOPIC_FORM_MAIN field mb-3" },
|
|
69508
|
+
[[
|
|
69509
|
+
"label",
|
|
69510
|
+
{ class: "checkbox" },
|
|
69511
|
+
[["input", el_attrs({
|
|
69512
|
+
type: "checkbox",
|
|
69513
|
+
"data-name": "main_topic",
|
|
69514
|
+
checked: record.main_topic ? "checked" : void 0
|
|
69515
|
+
})], [
|
|
69516
|
+
"span",
|
|
69517
|
+
{
|
|
69518
|
+
class: "ml-1",
|
|
69519
|
+
i18n: "main topic"
|
|
69520
|
+
},
|
|
69521
|
+
(0, i18next.t)("main topic")
|
|
69522
|
+
]]
|
|
69523
|
+
]]
|
|
69524
|
+
],
|
|
69254
69525
|
[
|
|
69255
69526
|
"div",
|
|
69256
69527
|
{
|
|
@@ -70043,6 +70314,7 @@ function topic_record(gobj, treedb, topic, values) {
|
|
|
70043
70314
|
record.tkey = values.tkey || "";
|
|
70044
70315
|
record.topic_version = values.topic_version === "" ? 1 : Number(values.topic_version);
|
|
70045
70316
|
record.system_topic = !!values.system_topic;
|
|
70317
|
+
record.main_topic = !!values.main_topic;
|
|
70046
70318
|
return record;
|
|
70047
70319
|
}
|
|
70048
70320
|
/***************************
|