@yuneta/gobj-ui 7.23.161 → 7.23.162
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 +56 -0
- package/dist/gobj-ui.cjs.js +333 -94
- package/dist/gobj-ui.es.js +334 -95
- package/package.json +1 -1
- package/src/c_yui_treedb_topic_with_form.css +30 -0
- package/src/c_yui_treedb_topic_with_form.js +296 -101
- package/src/c_yui_treedb_topics.js +43 -0
- package/src/delete_impact.js +7 -0
- package/src/delete_impact.test.js +8 -0
package/dist/gobj-ui.es.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as gobj_js from "@yuneta/gobj-js";
|
|
2
|
-
import { SDATA, SDATA_END, clean_name, createElement2, createOneHtml, create_template_record, data_type_t, debounce, delete_from_list, duplicate_objects, empty_json, empty_string, escapeHtml, event_flag_t, flat_diff, gclass_create, gclass_find_by_name, gclass_flag_t, getPositionRelativeToBody, gobj_bottom_gobj, gobj_change_state, gobj_command, gobj_create, gobj_create_pure_child, gobj_create_service, gobj_current_state, gobj_destroy, gobj_find_child, gobj_find_service, gobj_full_name, gobj_gclass_name, gobj_is_destroying, gobj_is_playing, gobj_is_pure_child, gobj_is_running, gobj_is_service, gobj_is_volatil, gobj_match_children, gobj_name, gobj_parent, gobj_post_event, gobj_publish_event, gobj_read_attr, gobj_read_bool_attr, gobj_read_integer_attr, gobj_read_pointer_attr, gobj_read_str_attr, gobj_save_persistent_attrs, gobj_send_event, gobj_set_trace_machine_format, gobj_short_name, gobj_start, gobj_start_tree, gobj_stop, gobj_stop_children, gobj_subscribe_event, gobj_unsubscribe_event, gobj_write_attr, gobj_write_bool_attr, gobj_write_integer_attr, gobj_write_str_attr, gobj_yuno, gobj_yuno_name, is_array, is_boolean, is_date, is_gobj, is_null, is_number, is_object, is_string, json2flat, json_deep_copy, json_object_size, json_object_update, json_object_update_missing, json_size, kw_clone_by_keys, kw_flag_t, kw_get_dict, kw_get_dict_value, kw_get_int, kw_get_local_storage_value, kw_get_str, kw_has_key, kw_set_dict_value, kw_set_local_storage_value, kwid_find_one_record,
|
|
2
|
+
import { SDATA, SDATA_END, clean_name, createElement2, createOneHtml, create_template_record, data_type_t, debounce, delete_from_list, duplicate_objects, empty_json, empty_string, escapeHtml, event_flag_t, flat_diff, gclass_create, gclass_find_by_name, gclass_flag_t, getPositionRelativeToBody, gobj_bottom_gobj, gobj_change_state, gobj_command, gobj_create, gobj_create_pure_child, gobj_create_service, gobj_current_state, gobj_destroy, gobj_find_child, gobj_find_service, gobj_full_name, gobj_gclass_name, gobj_is_destroying, gobj_is_playing, gobj_is_pure_child, gobj_is_running, gobj_is_service, gobj_is_volatil, gobj_match_children, gobj_name, gobj_parent, gobj_post_event, gobj_publish_event, gobj_read_attr, gobj_read_bool_attr, gobj_read_integer_attr, gobj_read_pointer_attr, gobj_read_str_attr, gobj_save_persistent_attrs, gobj_send_event, gobj_set_trace_machine_format, gobj_short_name, gobj_start, gobj_start_tree, gobj_stop, gobj_stop_children, gobj_subscribe_event, gobj_unsubscribe_event, gobj_write_attr, gobj_write_bool_attr, gobj_write_integer_attr, gobj_write_str_attr, gobj_yuno, gobj_yuno_name, is_array, is_boolean, is_date, is_gobj, is_null, is_number, is_object, is_string, json2flat, json_deep_copy, json_object_size, json_object_update, json_object_update_missing, json_size, kw_clone_by_keys, kw_flag_t, kw_get_dict, kw_get_dict_value, kw_get_int, kw_get_local_storage_value, kw_get_str, kw_has_key, kw_set_dict_value, kw_set_local_storage_value, kwid_find_one_record, kwid_new_dict, log_error, log_warning, msg_iev_get_stack, parseBoolean, parseSVG, refresh_language, safeSrc, sdata_flag_t, set_console_log_enabled, set_log_callback, sprintf, str_in_list, template_get_field_desc, trace_msg, treedb_decoder_fkey, treedb_encoder_fkey, treedb_get_field_desc, treedb_hook_data_size } from "@yuneta/gobj-js";
|
|
3
3
|
import i18next, { t } from "i18next";
|
|
4
4
|
import TomSelect from "tom-select";
|
|
5
5
|
import { createJSONEditor } from "vanilla-jsoneditor";
|
|
@@ -24678,6 +24678,36 @@ function ac_request_page(gobj, event, kw, src) {
|
|
|
24678
24678
|
return 0;
|
|
24679
24679
|
}
|
|
24680
24680
|
/********************************************
|
|
24681
|
+
* Event from formtable: open the records a hook of one row links --
|
|
24682
|
+
* the CHILD topic's table, filtered to the rows whose fkey names that
|
|
24683
|
+
* row. A hook is the question "which records hang from this one", and
|
|
24684
|
+
* the child's table is where that answer can be read: it pages, it
|
|
24685
|
+
* searches, it opens a record and it exports -- which a list of ids in
|
|
24686
|
+
* a popup could not do past a few dozen of them.
|
|
24687
|
+
* {
|
|
24688
|
+
* topic_name: the child topic
|
|
24689
|
+
* fkey: its fkey column that points back
|
|
24690
|
+
* parent_topic: the topic of the row the hook is on
|
|
24691
|
+
* parent_id: that row's id
|
|
24692
|
+
* hook: the hook column
|
|
24693
|
+
* }
|
|
24694
|
+
********************************************/
|
|
24695
|
+
function ac_open_linked(gobj, event, kw, src) {
|
|
24696
|
+
let child = get_gobj_formtable(gobj, kw.topic_name);
|
|
24697
|
+
if (!child) {
|
|
24698
|
+
log_error(`${gobj_short_name(gobj)}: cannot open '${kw.topic_name}', linked from '${kw.parent_topic}^${kw.parent_id}': that topic is not in this view`);
|
|
24699
|
+
return -1;
|
|
24700
|
+
}
|
|
24701
|
+
select_topic_by_id(gobj, gobj_name(child));
|
|
24702
|
+
gobj_send_event(child, "EV_FILTER_BY_PARENT", {
|
|
24703
|
+
fkey: kw.fkey,
|
|
24704
|
+
parent_topic: kw.parent_topic,
|
|
24705
|
+
parent_id: kw.parent_id,
|
|
24706
|
+
hook: kw.hook
|
|
24707
|
+
}, gobj);
|
|
24708
|
+
return 0;
|
|
24709
|
+
}
|
|
24710
|
+
/********************************************
|
|
24681
24711
|
* Event from formtable: the bytes of one asset a `file` column names,
|
|
24682
24712
|
* for the form's preview or the table's file popup.
|
|
24683
24713
|
*
|
|
@@ -24910,6 +24940,11 @@ function create_gclass$6(gclass_name) {
|
|
|
24910
24940
|
ac_request_asset,
|
|
24911
24941
|
null
|
|
24912
24942
|
],
|
|
24943
|
+
[
|
|
24944
|
+
"EV_OPEN_LINKED",
|
|
24945
|
+
ac_open_linked,
|
|
24946
|
+
null
|
|
24947
|
+
],
|
|
24913
24948
|
[
|
|
24914
24949
|
"EV_DELETE_RECORD",
|
|
24915
24950
|
ac_delete_record,
|
|
@@ -24991,6 +25026,7 @@ function create_gclass$6(gclass_name) {
|
|
|
24991
25026
|
["EV_UPDATE_FIELD", 0],
|
|
24992
25027
|
["EV_REQUEST_PAGE", 0],
|
|
24993
25028
|
["EV_REQUEST_ASSET", 0],
|
|
25029
|
+
["EV_OPEN_LINKED", 0],
|
|
24994
25030
|
["EV_DELETE_RECORD", 0],
|
|
24995
25031
|
["EV_RECORD_WRITTEN", event_flag_t.EVF_OUTPUT_EVENT | event_flag_t.EVF_NO_WARN_SUBS],
|
|
24996
25032
|
["EV_REFRESH_TOPIC", 0],
|
|
@@ -25655,6 +25691,7 @@ function plan_treedb_writes(flags) {
|
|
|
25655
25691
|
* How many things a hook/fkey value holds.
|
|
25656
25692
|
***************************************************************/
|
|
25657
25693
|
function ref_count(value) {
|
|
25694
|
+
if (Array.isArray(value) && value.length === 1 && value[0] && typeof value[0] === "object" && typeof value[0].size === "number") return value[0].size;
|
|
25658
25695
|
if (Array.isArray(value)) return value.length;
|
|
25659
25696
|
if (value && typeof value === "object") return Object.keys(value).length;
|
|
25660
25697
|
if (typeof value === "string" && value.length > 0) return 1;
|
|
@@ -25801,7 +25838,11 @@ var PRIVATE_DATA$5 = {
|
|
|
25801
25838
|
cell_file_modal: null,
|
|
25802
25839
|
cell_file_win: null,
|
|
25803
25840
|
_pending_assets: null,
|
|
25804
|
-
_asset_seq: 0
|
|
25841
|
+
_asset_seq: 0,
|
|
25842
|
+
parent_filter: null,
|
|
25843
|
+
search_term: "",
|
|
25844
|
+
$parent_filter: null,
|
|
25845
|
+
hook_choice_modal: null
|
|
25805
25846
|
};
|
|
25806
25847
|
var __gclass__$5 = null;
|
|
25807
25848
|
function is_mobile$1() {
|
|
@@ -25935,6 +25976,7 @@ function mt_stop$5(gobj) {
|
|
|
25935
25976
|
close_schema_dialog(gobj);
|
|
25936
25977
|
close_cell_json_dialog(gobj);
|
|
25937
25978
|
close_cell_file_dialog(gobj);
|
|
25979
|
+
close_hook_choice(gobj);
|
|
25938
25980
|
drop_pending_assets(gobj);
|
|
25939
25981
|
table__destroy(gobj);
|
|
25940
25982
|
}
|
|
@@ -25946,6 +25988,7 @@ function mt_destroy$5(gobj) {
|
|
|
25946
25988
|
close_schema_dialog(gobj);
|
|
25947
25989
|
close_cell_json_dialog(gobj);
|
|
25948
25990
|
close_cell_file_dialog(gobj);
|
|
25991
|
+
close_hook_choice(gobj);
|
|
25949
25992
|
drop_pending_assets(gobj);
|
|
25950
25993
|
destroy_ui$2(gobj);
|
|
25951
25994
|
}
|
|
@@ -26305,6 +26348,50 @@ function build_ui$5(gobj) {
|
|
|
26305
26348
|
bar.$el.style.flex = "none";
|
|
26306
26349
|
$container.insertBefore(bar.$el, $container.querySelector(`#${table_id}`));
|
|
26307
26350
|
}
|
|
26351
|
+
let $parent_filter = createElement2([
|
|
26352
|
+
"div",
|
|
26353
|
+
{
|
|
26354
|
+
class: "TREEDB_PARENT_FILTER is-hidden",
|
|
26355
|
+
style: "flex:none;"
|
|
26356
|
+
},
|
|
26357
|
+
[
|
|
26358
|
+
[
|
|
26359
|
+
"span",
|
|
26360
|
+
{
|
|
26361
|
+
class: "PARENT_FILTER_LABEL",
|
|
26362
|
+
i18n: "filtered by"
|
|
26363
|
+
},
|
|
26364
|
+
"filtered by"
|
|
26365
|
+
],
|
|
26366
|
+
[
|
|
26367
|
+
"span",
|
|
26368
|
+
{ class: "PARENT_FILTER_TOPIC" },
|
|
26369
|
+
""
|
|
26370
|
+
],
|
|
26371
|
+
[
|
|
26372
|
+
"strong",
|
|
26373
|
+
{ class: "PARENT_FILTER_ID" },
|
|
26374
|
+
""
|
|
26375
|
+
],
|
|
26376
|
+
[
|
|
26377
|
+
"button",
|
|
26378
|
+
{
|
|
26379
|
+
class: "delete PARENT_FILTER_CLEAR",
|
|
26380
|
+
type: "button",
|
|
26381
|
+
title: t("clear filter"),
|
|
26382
|
+
"data-i18n-title": "clear filter",
|
|
26383
|
+
"aria-label": t("clear filter"),
|
|
26384
|
+
"data-i18n-aria-label": "clear filter"
|
|
26385
|
+
},
|
|
26386
|
+
[],
|
|
26387
|
+
{ click: () => {
|
|
26388
|
+
gobj_send_event(gobj, "EV_CLEAR_PARENT_FILTER", {}, gobj);
|
|
26389
|
+
} }
|
|
26390
|
+
]
|
|
26391
|
+
]
|
|
26392
|
+
]);
|
|
26393
|
+
gobj.priv.$parent_filter = $parent_filter;
|
|
26394
|
+
$container.insertBefore($parent_filter, $container.querySelector(`#${table_id}`));
|
|
26308
26395
|
let $toolbar_slot = $container.querySelector(".toolbar_tabulator_table");
|
|
26309
26396
|
if ($table_toolbar instanceof Element) $toolbar_slot.appendChild($table_toolbar);
|
|
26310
26397
|
else $toolbar_slot.appendChild(createElement2(["div", {}]));
|
|
@@ -26797,6 +26884,7 @@ function create_tabulator(gobj) {
|
|
|
26797
26884
|
yui_tabulator_name_filters(tabulator, t);
|
|
26798
26885
|
yui_tabulator_name_row_selects(tabulator, t);
|
|
26799
26886
|
tabulator._ready = true;
|
|
26887
|
+
apply_row_filters(gobj);
|
|
26800
26888
|
update_rowcount();
|
|
26801
26889
|
yui_table_filter_clear(tabulator);
|
|
26802
26890
|
if (tabulator._pendingData !== void 0) {
|
|
@@ -27004,15 +27092,18 @@ function transform__treedb_value_2_table_value(gobj, col, value, row, field) {
|
|
|
27004
27092
|
break;
|
|
27005
27093
|
case "hook":
|
|
27006
27094
|
let items = treedb_hook_data_size(value);
|
|
27007
|
-
if (items > 0)
|
|
27008
|
-
"
|
|
27009
|
-
|
|
27010
|
-
|
|
27011
|
-
|
|
27012
|
-
|
|
27013
|
-
|
|
27014
|
-
|
|
27015
|
-
|
|
27095
|
+
if (items > 0) {
|
|
27096
|
+
let hook_title = String(t("show linked records")).replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
27097
|
+
value = [
|
|
27098
|
+
"<a class=\"hook_cell\" ",
|
|
27099
|
+
`title="${hook_title}" aria-label="${hook_title}" `,
|
|
27100
|
+
`data-row_id="${row.id}" `,
|
|
27101
|
+
`data-col_id="${col.id}" > `,
|
|
27102
|
+
"<span style=\"\" class=\"icon yi-eye\"></span>",
|
|
27103
|
+
`<span>[ <u>${items}</u> ]</span>`,
|
|
27104
|
+
"</a>"
|
|
27105
|
+
].join("");
|
|
27106
|
+
} else value = "";
|
|
27016
27107
|
break;
|
|
27017
27108
|
case "file":
|
|
27018
27109
|
case "fkey":
|
|
@@ -27647,6 +27738,153 @@ function close_cell_file_dialog(gobj) {
|
|
|
27647
27738
|
teardown_cell_file(gobj);
|
|
27648
27739
|
}
|
|
27649
27740
|
/************************************************************
|
|
27741
|
+
* Ask the host to open the rows of `topic_name` whose `fkey`
|
|
27742
|
+
* names this row -- what a hook of this row links.
|
|
27743
|
+
************************************************************/
|
|
27744
|
+
function publish_open_linked(gobj, topic_name, fkey, parent_id, hook) {
|
|
27745
|
+
gobj_publish_event(gobj, "EV_OPEN_LINKED", {
|
|
27746
|
+
topic_name,
|
|
27747
|
+
fkey,
|
|
27748
|
+
parent_topic: gobj_read_str_attr(gobj, "topic_name"),
|
|
27749
|
+
parent_id,
|
|
27750
|
+
hook
|
|
27751
|
+
});
|
|
27752
|
+
}
|
|
27753
|
+
/************************************************************
|
|
27754
|
+
* "Which child topic?" -- for a hook whose children live in
|
|
27755
|
+
* more than one. The standardized dialog, so Escape, Back and
|
|
27756
|
+
* a click outside close it like every other one.
|
|
27757
|
+
************************************************************/
|
|
27758
|
+
function open_hook_choice_dialog(gobj, targets, parent_id, hook) {
|
|
27759
|
+
close_hook_choice(gobj);
|
|
27760
|
+
let priv = gobj.priv;
|
|
27761
|
+
let shell = yui_shell_of(gobj);
|
|
27762
|
+
if (!shell) {
|
|
27763
|
+
log_error(`${gobj_short_name(gobj)}: no shell, cannot ask which topic to open`);
|
|
27764
|
+
return;
|
|
27765
|
+
}
|
|
27766
|
+
priv.hook_choice_modal = yui_shell_show_modal(shell, createElement2([
|
|
27767
|
+
"div",
|
|
27768
|
+
{ class: "TREEDB_HOOK_CHOICE" },
|
|
27769
|
+
targets.map((tg) => {
|
|
27770
|
+
return [
|
|
27771
|
+
"button",
|
|
27772
|
+
{
|
|
27773
|
+
class: "button HOOK_CHOICE_TOPIC",
|
|
27774
|
+
type: "button",
|
|
27775
|
+
title: t(tg.topic_name),
|
|
27776
|
+
"data-i18n-title": tg.topic_name,
|
|
27777
|
+
"aria-label": t(tg.topic_name),
|
|
27778
|
+
"data-i18n-aria-label": tg.topic_name
|
|
27779
|
+
},
|
|
27780
|
+
[[
|
|
27781
|
+
"span",
|
|
27782
|
+
{ i18n: tg.topic_name },
|
|
27783
|
+
tg.topic_name
|
|
27784
|
+
]],
|
|
27785
|
+
{ click: () => {
|
|
27786
|
+
gobj_send_event(gobj, "EV_CHOOSE_LINKED", {
|
|
27787
|
+
topic_name: tg.topic_name,
|
|
27788
|
+
fkey: tg.fkey,
|
|
27789
|
+
parent_id,
|
|
27790
|
+
hook
|
|
27791
|
+
}, gobj);
|
|
27792
|
+
} }
|
|
27793
|
+
];
|
|
27794
|
+
})
|
|
27795
|
+
]), {
|
|
27796
|
+
dialog: true,
|
|
27797
|
+
logical_class: "TREEDB_HOOK_CHOICE_SHEET",
|
|
27798
|
+
title: "choose a topic",
|
|
27799
|
+
t,
|
|
27800
|
+
on_close: function() {
|
|
27801
|
+
priv.hook_choice_modal = null;
|
|
27802
|
+
}
|
|
27803
|
+
});
|
|
27804
|
+
}
|
|
27805
|
+
/************************************************************
|
|
27806
|
+
* Close "which child topic?" if it is open.
|
|
27807
|
+
************************************************************/
|
|
27808
|
+
function close_hook_choice(gobj) {
|
|
27809
|
+
let priv = gobj.priv;
|
|
27810
|
+
if (priv.hook_choice_modal) {
|
|
27811
|
+
let modal = priv.hook_choice_modal;
|
|
27812
|
+
priv.hook_choice_modal = null;
|
|
27813
|
+
modal.close();
|
|
27814
|
+
}
|
|
27815
|
+
}
|
|
27816
|
+
/************************************************************
|
|
27817
|
+
* Does this row's `pf.fkey` name the parent record? The fkey
|
|
27818
|
+
* arrives as one ref, a list of them or a dict keyed by ref,
|
|
27819
|
+
* each in any of the shapes treedb_decoder_fkey() reads. The
|
|
27820
|
+
* topic and the hook are compared when the ref carries them:
|
|
27821
|
+
* one row can hang from the same parent through two hooks.
|
|
27822
|
+
************************************************************/
|
|
27823
|
+
function row_links_to(gobj, data, pf) {
|
|
27824
|
+
let col = get_schema_col(gobj, pf.fkey);
|
|
27825
|
+
let v = data ? data[pf.fkey] : null;
|
|
27826
|
+
if (!col || v === null || v === void 0 || v === "") return false;
|
|
27827
|
+
let refs;
|
|
27828
|
+
if (is_array(v)) refs = v;
|
|
27829
|
+
else if (is_object(v) && v.id === void 0) refs = Object.keys(v);
|
|
27830
|
+
else refs = [v];
|
|
27831
|
+
for (let ref of refs) {
|
|
27832
|
+
if (ref === null || ref === void 0 || ref === "") continue;
|
|
27833
|
+
let fk = treedb_decoder_fkey(col, ref);
|
|
27834
|
+
if (!fk || String(fk.id) !== pf.parent_id) continue;
|
|
27835
|
+
if (fk.topic_name && pf.parent_topic && fk.topic_name !== pf.parent_topic) continue;
|
|
27836
|
+
if (fk.hook_name && pf.hook && fk.hook_name !== pf.hook) continue;
|
|
27837
|
+
return true;
|
|
27838
|
+
}
|
|
27839
|
+
return false;
|
|
27840
|
+
}
|
|
27841
|
+
/************************************************************
|
|
27842
|
+
* The ONE programmatic filter of the table: the parent filter
|
|
27843
|
+
* AND the search term. Kept as state and applied here, because
|
|
27844
|
+
* Tabulator's setFilter() replaces every programmatic filter.
|
|
27845
|
+
* Before `tableBuilt` the state waits; tableBuilt applies it.
|
|
27846
|
+
************************************************************/
|
|
27847
|
+
function apply_row_filters(gobj) {
|
|
27848
|
+
let priv = gobj.priv;
|
|
27849
|
+
let tabulator = gobj_read_attr(gobj, "tabulator");
|
|
27850
|
+
if (!tabulator) {
|
|
27851
|
+
log_error(`${gobj_short_name(gobj)}: no table to filter`);
|
|
27852
|
+
return;
|
|
27853
|
+
}
|
|
27854
|
+
if (!tabulator._ready) return;
|
|
27855
|
+
let term = priv.search_term || "";
|
|
27856
|
+
let pf = priv.parent_filter;
|
|
27857
|
+
if (!term && !pf) {
|
|
27858
|
+
tabulator.clearFilter();
|
|
27859
|
+
return;
|
|
27860
|
+
}
|
|
27861
|
+
tabulator.setFilter(function(data) {
|
|
27862
|
+
if (pf && !row_links_to(gobj, data, pf)) return false;
|
|
27863
|
+
return !term || row_matches(data, term);
|
|
27864
|
+
});
|
|
27865
|
+
}
|
|
27866
|
+
/************************************************************
|
|
27867
|
+
* Show or hide the chip that says the parent filter is on.
|
|
27868
|
+
************************************************************/
|
|
27869
|
+
function render_parent_filter(gobj) {
|
|
27870
|
+
let priv = gobj.priv;
|
|
27871
|
+
let $chip = priv.$parent_filter;
|
|
27872
|
+
if (!$chip) {
|
|
27873
|
+
log_error(`${gobj_short_name(gobj)}: no parent-filter chip to paint`);
|
|
27874
|
+
return;
|
|
27875
|
+
}
|
|
27876
|
+
let pf = priv.parent_filter;
|
|
27877
|
+
if (!pf) {
|
|
27878
|
+
$chip.classList.add("is-hidden");
|
|
27879
|
+
return;
|
|
27880
|
+
}
|
|
27881
|
+
let $topic = $chip.querySelector(".PARENT_FILTER_TOPIC");
|
|
27882
|
+
$topic.setAttribute("data-i18n", pf.parent_topic);
|
|
27883
|
+
$topic.textContent = t(pf.parent_topic);
|
|
27884
|
+
$chip.querySelector(".PARENT_FILTER_ID").textContent = pf.parent_id;
|
|
27885
|
+
$chip.classList.remove("is-hidden");
|
|
27886
|
+
}
|
|
27887
|
+
/************************************************************
|
|
27650
27888
|
* True if the topic's pkey col carries the "rowid" flag.
|
|
27651
27889
|
************************************************************/
|
|
27652
27890
|
function pkey_is_rowid(gobj) {
|
|
@@ -27903,74 +28141,6 @@ function build_fkey_ref(gobj, col, value) {
|
|
|
27903
28141
|
}
|
|
27904
28142
|
return refs;
|
|
27905
28143
|
}
|
|
27906
|
-
/***************************************************************************
|
|
27907
|
-
* TODO con límite máximo o máximo height o con scroll
|
|
27908
|
-
* en un gobj propio para gestionar los datos en "page"s
|
|
27909
|
-
* que los hook no vengan rellenos si son muchos y que se puedan gestionar
|
|
27910
|
-
* con un gobj
|
|
27911
|
-
***************************************************************************/
|
|
27912
|
-
function show_dropdown_popup_menu(gobj, x, y, items, callback) {
|
|
27913
|
-
let $element = createElement2([
|
|
27914
|
-
"div",
|
|
27915
|
-
{ class: "dropdown popup" },
|
|
27916
|
-
[[
|
|
27917
|
-
"div",
|
|
27918
|
-
{
|
|
27919
|
-
class: "dropdown-menu",
|
|
27920
|
-
role: "menu",
|
|
27921
|
-
style: "min-width:4rem; border: 2px solid var(--bulma-border); padding: 0px;"
|
|
27922
|
-
},
|
|
27923
|
-
[[
|
|
27924
|
-
"div",
|
|
27925
|
-
{
|
|
27926
|
-
class: "dropdown-content",
|
|
27927
|
-
style: "padding: 0;"
|
|
27928
|
-
},
|
|
27929
|
-
[]
|
|
27930
|
-
]]
|
|
27931
|
-
]],
|
|
27932
|
-
{ "click": (evt) => {
|
|
27933
|
-
evt.stopPropagation();
|
|
27934
|
-
destroyModal();
|
|
27935
|
-
if (callback) callback(evt);
|
|
27936
|
-
} }
|
|
27937
|
-
]);
|
|
27938
|
-
const destroyModal = () => {
|
|
27939
|
-
$element.classList.remove("is-active");
|
|
27940
|
-
$element.parentNode.removeChild($element);
|
|
27941
|
-
};
|
|
27942
|
-
let $dropdown_content = $element.querySelector(".dropdown-content");
|
|
27943
|
-
let ids = kwid_get_ids(gobj, items);
|
|
27944
|
-
for (let id of ids) {
|
|
27945
|
-
let $item = createElement2([
|
|
27946
|
-
"a",
|
|
27947
|
-
{
|
|
27948
|
-
class: "dropdown-item flex-horizontal-section",
|
|
27949
|
-
"data-value": `${id}`,
|
|
27950
|
-
style: "margin:0px;"
|
|
27951
|
-
},
|
|
27952
|
-
[[
|
|
27953
|
-
"span",
|
|
27954
|
-
{ i18n: `${id}` },
|
|
27955
|
-
`${id}`
|
|
27956
|
-
]],
|
|
27957
|
-
{ "click": (evt) => {
|
|
27958
|
-
evt.stopPropagation();
|
|
27959
|
-
destroyModal();
|
|
27960
|
-
if (callback) callback(evt, this.dataset.value);
|
|
27961
|
-
} }
|
|
27962
|
-
]);
|
|
27963
|
-
$dropdown_content.appendChild($item);
|
|
27964
|
-
}
|
|
27965
|
-
refresh_language($element, t);
|
|
27966
|
-
popup_mount_layer(gobj).appendChild($element);
|
|
27967
|
-
$element.style.position = "absolute";
|
|
27968
|
-
$element.style.top = y + "px";
|
|
27969
|
-
$element.style.left = x + "px";
|
|
27970
|
-
$element.classList.add("is-active");
|
|
27971
|
-
let $with_focus = $element.querySelector(".with-focus");
|
|
27972
|
-
if ($with_focus) $with_focus.focus();
|
|
27973
|
-
}
|
|
27974
28144
|
/***************************************************************
|
|
27975
28145
|
* A read-only topic refuses the write EVENTS too, not only their
|
|
27976
28146
|
* buttons. The buttons are gone, but an event can still arrive: a
|
|
@@ -28410,12 +28580,69 @@ function ac_change_locale(gobj, event, kw, src) {
|
|
|
28410
28580
|
* };
|
|
28411
28581
|
************************************************************/
|
|
28412
28582
|
function ac_show_hook_data$1(gobj, event, kw, src) {
|
|
28413
|
-
let
|
|
28414
|
-
let
|
|
28415
|
-
if (
|
|
28416
|
-
|
|
28417
|
-
|
|
28583
|
+
let col = get_schema_col(gobj, kw.col_id);
|
|
28584
|
+
let hook = col && is_object(col.hook) ? col.hook : null;
|
|
28585
|
+
if (!hook || kw.row_id === void 0 || kw.row_id === null) {
|
|
28586
|
+
log_error(`${gobj_short_name(gobj)}: hook '${kw.col_id}' names no child topic to open`);
|
|
28587
|
+
return -1;
|
|
28588
|
+
}
|
|
28589
|
+
let targets = Object.keys(hook).map((topic) => {
|
|
28590
|
+
return {
|
|
28591
|
+
topic_name: topic,
|
|
28592
|
+
fkey: hook[topic]
|
|
28593
|
+
};
|
|
28594
|
+
});
|
|
28595
|
+
if (targets.length === 1) {
|
|
28596
|
+
publish_open_linked(gobj, targets[0].topic_name, targets[0].fkey, String(kw.row_id), kw.col_id);
|
|
28597
|
+
return 0;
|
|
28598
|
+
}
|
|
28599
|
+
open_hook_choice_dialog(gobj, targets, String(kw.row_id), kw.col_id);
|
|
28600
|
+
return 0;
|
|
28601
|
+
}
|
|
28602
|
+
/************************************************************
|
|
28603
|
+
* A hook with several child topics: pick one.
|
|
28604
|
+
* {topic_name, fkey, parent_id, hook}
|
|
28605
|
+
************************************************************/
|
|
28606
|
+
function ac_choose_linked(gobj, event, kw, src) {
|
|
28607
|
+
close_hook_choice(gobj);
|
|
28608
|
+
publish_open_linked(gobj, kw.topic_name, kw.fkey, kw.parent_id, kw.hook);
|
|
28609
|
+
return 0;
|
|
28610
|
+
}
|
|
28611
|
+
/************************************************************
|
|
28612
|
+
* Show only the rows linked to one record of another topic.
|
|
28613
|
+
* Sent by the host when a hook of that record was clicked.
|
|
28614
|
+
* {fkey, parent_topic, parent_id, hook}
|
|
28615
|
+
*
|
|
28616
|
+
* Over the rows the table HOLDS: with `with_remote_paging` that
|
|
28617
|
+
* is one page, which is one of the reasons that flag stays off.
|
|
28618
|
+
************************************************************/
|
|
28619
|
+
function ac_filter_by_parent(gobj, event, kw, src) {
|
|
28620
|
+
let priv = gobj.priv;
|
|
28621
|
+
if (!kw || !kw.fkey || kw.parent_id === void 0 || kw.parent_id === null) {
|
|
28622
|
+
log_error(`${gobj_short_name(gobj)}: a parent filter with no fkey or no parent`);
|
|
28623
|
+
return -1;
|
|
28624
|
+
}
|
|
28625
|
+
if (!get_schema_col(gobj, kw.fkey)) {
|
|
28626
|
+
log_error(`${gobj_short_name(gobj)}: parent filter on '${kw.fkey}', which is not a column of '${gobj_read_str_attr(gobj, "topic_name")}'`);
|
|
28627
|
+
return -1;
|
|
28418
28628
|
}
|
|
28629
|
+
priv.parent_filter = {
|
|
28630
|
+
fkey: kw.fkey,
|
|
28631
|
+
parent_topic: kw.parent_topic || "",
|
|
28632
|
+
parent_id: String(kw.parent_id),
|
|
28633
|
+
hook: kw.hook || ""
|
|
28634
|
+
};
|
|
28635
|
+
render_parent_filter(gobj);
|
|
28636
|
+
apply_row_filters(gobj);
|
|
28637
|
+
return 0;
|
|
28638
|
+
}
|
|
28639
|
+
/************************************************************
|
|
28640
|
+
* The ✕ of the parent filter: back to the whole topic.
|
|
28641
|
+
************************************************************/
|
|
28642
|
+
function ac_clear_parent_filter(gobj, event, kw, src) {
|
|
28643
|
+
gobj.priv.parent_filter = null;
|
|
28644
|
+
render_parent_filter(gobj);
|
|
28645
|
+
apply_row_filters(gobj);
|
|
28419
28646
|
return 0;
|
|
28420
28647
|
}
|
|
28421
28648
|
/************************************************************
|
|
@@ -28726,19 +28953,12 @@ function ac_page_timeout(gobj, event, kw, src) {
|
|
|
28726
28953
|
* cleared search box does not silently undo them.
|
|
28727
28954
|
************************************************************/
|
|
28728
28955
|
function ac_search(gobj, event, kw, src) {
|
|
28729
|
-
|
|
28730
|
-
if (!tabulator) {
|
|
28956
|
+
if (!gobj_read_attr(gobj, "tabulator")) {
|
|
28731
28957
|
log_error(`${gobj_short_name(gobj)}: no table to search`);
|
|
28732
28958
|
return -1;
|
|
28733
28959
|
}
|
|
28734
|
-
|
|
28735
|
-
|
|
28736
|
-
tabulator.clearFilter();
|
|
28737
|
-
return 0;
|
|
28738
|
-
}
|
|
28739
|
-
tabulator.setFilter(function(data) {
|
|
28740
|
-
return row_matches(data, term);
|
|
28741
|
-
});
|
|
28960
|
+
gobj.priv.search_term = (kw && kw.text || "").toLowerCase();
|
|
28961
|
+
apply_row_filters(gobj);
|
|
28742
28962
|
return 0;
|
|
28743
28963
|
}
|
|
28744
28964
|
/************************************************************
|
|
@@ -28986,6 +29206,21 @@ function create_gclass$5(gclass_name) {
|
|
|
28986
29206
|
ac_show_hook_data$1,
|
|
28987
29207
|
null
|
|
28988
29208
|
],
|
|
29209
|
+
[
|
|
29210
|
+
"EV_CHOOSE_LINKED",
|
|
29211
|
+
ac_choose_linked,
|
|
29212
|
+
null
|
|
29213
|
+
],
|
|
29214
|
+
[
|
|
29215
|
+
"EV_FILTER_BY_PARENT",
|
|
29216
|
+
ac_filter_by_parent,
|
|
29217
|
+
null
|
|
29218
|
+
],
|
|
29219
|
+
[
|
|
29220
|
+
"EV_CLEAR_PARENT_FILTER",
|
|
29221
|
+
ac_clear_parent_filter,
|
|
29222
|
+
null
|
|
29223
|
+
],
|
|
28989
29224
|
[
|
|
28990
29225
|
"EV_SHOW_CELL_JSON",
|
|
28991
29226
|
ac_show_cell_json,
|
|
@@ -29104,7 +29339,11 @@ function create_gclass$5(gclass_name) {
|
|
|
29104
29339
|
["EV_CLEAR_SELECTION", 0],
|
|
29105
29340
|
["EV_SELECT_ROWS", event_flag_t.EVF_OUTPUT_EVENT],
|
|
29106
29341
|
["EV_UNSELECT_ROWS", event_flag_t.EVF_OUTPUT_EVENT],
|
|
29107
|
-
["EV_SHOW_HOOK_DATA",
|
|
29342
|
+
["EV_SHOW_HOOK_DATA", 0],
|
|
29343
|
+
["EV_CHOOSE_LINKED", 0],
|
|
29344
|
+
["EV_FILTER_BY_PARENT", 0],
|
|
29345
|
+
["EV_CLEAR_PARENT_FILTER", 0],
|
|
29346
|
+
["EV_OPEN_LINKED", event_flag_t.EVF_OUTPUT_EVENT],
|
|
29108
29347
|
["EV_SHOW_CELL_JSON", 0],
|
|
29109
29348
|
["EV_SHOW_CELL_FILE", 0],
|
|
29110
29349
|
["EV_ASSET_LOADED", 0],
|
package/package.json
CHANGED
|
@@ -208,3 +208,33 @@
|
|
|
208
208
|
font-family: monospace;
|
|
209
209
|
overflow-wrap: anywhere;
|
|
210
210
|
}
|
|
211
|
+
|
|
212
|
+
/*
|
|
213
|
+
* The table is showing only the rows linked to one record, because a
|
|
214
|
+
* hook was clicked (EV_FILTER_BY_PARENT). Said above the table, with
|
|
215
|
+
* the way out beside it: a filter nobody can see is a table that looks
|
|
216
|
+
* like it lost rows.
|
|
217
|
+
*/
|
|
218
|
+
.TREEDB_PARENT_FILTER {
|
|
219
|
+
display: flex;
|
|
220
|
+
align-items: center;
|
|
221
|
+
gap: 0.4rem;
|
|
222
|
+
flex-wrap: wrap;
|
|
223
|
+
padding: 0.35rem 0.75rem;
|
|
224
|
+
border-bottom: 1px solid var(--bulma-border, #dbdbdb);
|
|
225
|
+
background: var(--bulma-scheme-main-bis, transparent);
|
|
226
|
+
}
|
|
227
|
+
.TREEDB_PARENT_FILTER .PARENT_FILTER_ID {
|
|
228
|
+
font-family: monospace;
|
|
229
|
+
overflow-wrap: anywhere;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/*
|
|
233
|
+
* A hook whose children live in more than one topic: which one to open.
|
|
234
|
+
*/
|
|
235
|
+
.TREEDB_HOOK_CHOICE {
|
|
236
|
+
display: flex;
|
|
237
|
+
flex-direction: column;
|
|
238
|
+
gap: 0.5rem;
|
|
239
|
+
padding: 0.75rem;
|
|
240
|
+
}
|