@xuda.io/runtime-bundle 1.0.1250 → 1.0.1252

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.
@@ -2675,27 +2675,40 @@ func.common.get_data_from_websocket = async function (SESSION_ID, serviceP, data
2675
2675
  });
2676
2676
  };
2677
2677
 
2678
- func.common.sha256 = async function (inputString) {
2679
- // 1. Create a hash buffer from the input string using SHA-256.
2680
- // This part remains the same as it provides a strong, unique cryptographic starting point.
2681
- const buffer = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(inputString));
2682
-
2683
- // 2. Interpret the first 8 bytes (64 bits) of the hash as one big number.
2684
- const view = new DataView(buffer);
2685
- const bigInt = view.getBigUint64(0, false); // `false` for big-endian
2686
-
2687
- // 3. Convert the BigInt to a Base36 string.
2688
- // The .toString(36) method handles the conversion to an alphanumeric representation (0-9, a-z).
2689
- const base36Hash = bigInt.toString(36);
2690
-
2691
- // 4. Take the first 10 characters. If it's shorter, it will just return the whole string.
2692
- // For a 64-bit integer, the Base36 representation will be about 13 characters long,
2693
- // so slicing is a reliable way to get a fixed length.
2694
- const shortHash = base36Hash.slice(0, 10);
2695
-
2696
- // 5. Pad the start in the unlikely case the hash is shorter than 10 characters.
2697
- // This ensures the output is always exactly 10 characters long.
2698
- return shortHash.padStart(10, '0');
2678
+ // func.common.sha256 = async function (inputString) {
2679
+ // // 1. Create a hash buffer from the input string using SHA-256.
2680
+ // // This part remains the same as it provides a strong, unique cryptographic starting point.
2681
+ // const buffer = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(inputString));
2682
+
2683
+ // // 2. Interpret the first 8 bytes (64 bits) of the hash as one big number.
2684
+ // const view = new DataView(buffer);
2685
+ // const bigInt = view.getBigUint64(0, false); // `false` for big-endian
2686
+
2687
+ // // 3. Convert the BigInt to a Base36 string.
2688
+ // // The .toString(36) method handles the conversion to an alphanumeric representation (0-9, a-z).
2689
+ // const base36Hash = bigInt.toString(36);
2690
+
2691
+ // // 4. Take the first 10 characters. If it's shorter, it will just return the whole string.
2692
+ // // For a 64-bit integer, the Base36 representation will be about 13 characters long,
2693
+ // // so slicing is a reliable way to get a fixed length.
2694
+ // const shortHash = base36Hash.slice(0, 10);
2695
+
2696
+ // // 5. Pad the start in the unlikely case the hash is shorter than 10 characters.
2697
+ // // This ensures the output is always exactly 10 characters long.
2698
+ // return shortHash.padStart(10, '0');
2699
+ // };
2700
+
2701
+ func.common.fastHash = function (inputString) {
2702
+ let hash = 0x811c9dc5; // FNV offset basis
2703
+
2704
+ for (let i = 0; i < inputString.length; i++) {
2705
+ hash ^= inputString.charCodeAt(i);
2706
+ // FNV prime multiplication with 32-bit overflow
2707
+ hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
2708
+ }
2709
+
2710
+ // Convert to base36 and pad to 10 characters
2711
+ return ((hash >>> 0).toString(36) + '0000000000').slice(0, 10);
2699
2712
  };
2700
2713
 
2701
2714
  glb.new_xu_render = false;
@@ -12963,353 +12976,1451 @@ func.UI.screen.screen_loading_done = async function (SESSION_ID, paramsP, $div,
12963
12976
  return $div;
12964
12977
  };
12965
12978
 
12966
- func.UI.screen.render_ui_tree = async function (SESSION_ID, $container, nodeP, parent_infoP, paramsP, jobNoP, is_skeleton, keyP, refreshed_ds, parent_nodeP, check_existP, $root_container) {
12967
- if (!is_skeleton) {
12968
- var _session = SESSION_OBJ[SESSION_ID];
12969
- var _ds = _session.DS_GLB[paramsP.dsSessionP];
12970
- }
12971
- var prop;
12972
- try {
12973
- prop = nodeP.attributes;
12974
- } catch (error) {
12975
- // debugger;
12976
- }
12979
+ // func.UI.screen.render_ui_tree = async function (SESSION_ID, $container, nodeP, parent_infoP, paramsP, jobNoP, is_skeleton, keyP, refreshed_ds, parent_nodeP, check_existP, $root_container) {
12980
+ // if (!is_skeleton) {
12981
+ // var _session = SESSION_OBJ[SESSION_ID];
12982
+ // var _ds = _session.DS_GLB[paramsP.dsSessionP];
12983
+ // }
12984
+ // var prop;
12985
+ // try {
12986
+ // prop = nodeP.attributes;
12987
+ // } catch (error) {
12988
+ // // debugger;
12989
+ // }
12977
12990
 
12978
- ///////////
12979
- var is_mobile = glb.MOBILE_ARR.includes(paramsP.screenInfo.properties?.menuType) ? true : false;
12991
+ // ///////////
12992
+ // var is_mobile = glb.MOBILE_ARR.includes(paramsP.screenInfo.properties?.menuType) ? true : false;
12980
12993
 
12981
- const get_element_info = function () {
12982
- var ret = {};
12983
- let currentRecordId = _ds?.currentRecordId || '';
12994
+ // const get_element_info = function () {
12995
+ // var ret = {};
12996
+ // let currentRecordId = _ds?.currentRecordId || '';
12984
12997
 
12985
- let $div = func.UI.utils.find_in_element_data('xuData', $container.parent(), 'nodeid', nodeP.id);
12998
+ // let $div = func.UI.utils.find_in_element_data('xuData', $container.parent(), 'nodeid', nodeP.id);
12986
12999
 
12987
- $.each($div, function (key, val) {
12988
- if ($(val)?.data().xuData?.recordid === currentRecordId && $(val)?.data().xuData?.key === keyP && $(val)?.prop('tagName') !== 'XURENDER') {
12989
- ret = {
12990
- div: $div,
12991
- };
12992
- }
12993
- });
13000
+ // $.each($div, function (key, val) {
13001
+ // if ($(val)?.data().xuData?.recordid === currentRecordId && $(val)?.data().xuData?.key === keyP && $(val)?.prop('tagName') !== 'XURENDER') {
13002
+ // ret = {
13003
+ // div: $div,
13004
+ // };
13005
+ // }
13006
+ // });
12994
13007
 
12995
- return ret;
12996
- };
13008
+ // return ret;
13009
+ // };
12997
13010
 
12998
- const init = async function () {
12999
- var ret = true;
13000
- if (!nodeP) ret = false;
13001
- return ret;
13002
- };
13003
- const debug = function (is_errorP, error_descP) {
13004
- func.utils.debug.log(SESSION_ID, paramsP.prog_id + '_' + nodeP.id_org + '_ui_prop', {
13005
- module: 'gui',
13006
- action: 'init',
13007
- prop: nodeP.id,
13008
- details: error_descP,
13009
- result: null,
13010
- error: is_errorP,
13011
- source: _ds?.tree_obj?.menuName || '',
13012
- fields: null,
13013
- type: null,
13014
- prog_id: paramsP.prog_id,
13015
- dsSession: null,
13016
- });
13017
- };
13011
+ // const init = async function () {
13012
+ // var ret = true;
13013
+ // if (!nodeP) ret = false;
13014
+ // return ret;
13015
+ // };
13016
+ // const debug = function (is_errorP, error_descP) {
13017
+ // func.utils.debug.log(SESSION_ID, paramsP.prog_id + '_' + nodeP.id_org + '_ui_prop', {
13018
+ // module: 'gui',
13019
+ // action: 'init',
13020
+ // prop: nodeP.id,
13021
+ // details: error_descP,
13022
+ // result: null,
13023
+ // error: is_errorP,
13024
+ // source: _ds?.tree_obj?.menuName || '',
13025
+ // fields: null,
13026
+ // type: null,
13027
+ // prog_id: paramsP.prog_id,
13028
+ // dsSession: null,
13029
+ // });
13030
+ // };
13018
13031
 
13019
- const open_modal = async function ($div) {
13020
- const modal_id = 'app_modal-' + paramsP.dsSessionP.toString();
13021
- var xu_modal_controller = document.querySelector('xu-modal-controller');
13022
- if (!xu_modal_controller) {
13023
- func.UI.component.create_app_modal_component(SESSION_ID, modal_id);
13024
- xu_modal_controller = document.querySelector('xu-modal-controller');
13025
- }
13032
+ // const open_modal = async function ($div) {
13033
+ // const modal_id = 'app_modal-' + paramsP.dsSessionP.toString();
13034
+ // var xu_modal_controller = document.querySelector('xu-modal-controller');
13035
+ // if (!xu_modal_controller) {
13036
+ // func.UI.component.create_app_modal_component(SESSION_ID, modal_id);
13037
+ // xu_modal_controller = document.querySelector('xu-modal-controller');
13038
+ // }
13026
13039
 
13027
- var controller_params = $(xu_modal_controller).data('xuControllerParams');
13040
+ // var controller_params = $(xu_modal_controller).data('xuControllerParams');
13028
13041
 
13029
- if (!controller_params) {
13030
- controller_params = {};
13031
- }
13042
+ // if (!controller_params) {
13043
+ // controller_params = {};
13044
+ // }
13032
13045
 
13033
- var params = {
13034
- menuTitle: paramsP.screenInfo.properties?.menuTitle,
13035
- screenId: paramsP.screenId,
13036
- $dialogDiv: $div.children(),
13037
- $container: $container,
13038
- dsSession: paramsP.dsSessionP,
13039
- };
13046
+ // var params = {
13047
+ // menuTitle: paramsP.screenInfo.properties?.menuTitle,
13048
+ // screenId: paramsP.screenId,
13049
+ // $dialogDiv: $div.children(),
13050
+ // $container: $container,
13051
+ // dsSession: paramsP.dsSessionP,
13052
+ // };
13040
13053
 
13041
- controller_params[modal_id] = params;
13054
+ // controller_params[modal_id] = params;
13042
13055
 
13043
- $(xu_modal_controller).data('xuControllerParams', controller_params);
13044
- const modalController = await new UI_FRAMEWORK_PLUGIN.modal();
13056
+ // $(xu_modal_controller).data('xuControllerParams', controller_params);
13057
+ // const modalController = await new UI_FRAMEWORK_PLUGIN.modal();
13045
13058
 
13046
- if (!APP_MODAL_OBJ[modal_id]) {
13047
- const modal = await modalController.create(SESSION_ID, modal_id, paramsP.screenInfo, close_modal);
13048
- APP_MODAL_OBJ[modal_id] = modal;
13049
- } else {
13050
- $(modal_id).empty();
13051
- }
13052
- await modalController.init(SESSION_ID, modal_id);
13059
+ // if (!APP_MODAL_OBJ[modal_id]) {
13060
+ // const modal = await modalController.create(SESSION_ID, modal_id, paramsP.screenInfo, close_modal);
13061
+ // APP_MODAL_OBJ[modal_id] = modal;
13062
+ // } else {
13063
+ // $(modal_id).empty();
13064
+ // }
13065
+ // await modalController.init(SESSION_ID, modal_id);
13053
13066
 
13054
- return $div;
13055
- };
13067
+ // return $div;
13068
+ // };
13056
13069
 
13057
- const close_modal = async function (modal_id) {
13058
- delete APP_MODAL_OBJ[modal_id];
13059
- const xu_modal_controller = document.querySelector('xu-modal-controller');
13060
- var params = $(xu_modal_controller).data().xuControllerParams[modal_id];
13061
- if (params && params.$container) {
13062
- await func.UI.screen.validate_exit_events(SESSION_ID, params.$container.data().xuData.paramsP, null);
13063
- func.datasource.clean_all(SESSION_ID, params.dsSession);
13064
- }
13065
- };
13070
+ // const close_modal = async function (modal_id) {
13071
+ // delete APP_MODAL_OBJ[modal_id];
13072
+ // const xu_modal_controller = document.querySelector('xu-modal-controller');
13073
+ // var params = $(xu_modal_controller).data().xuControllerParams[modal_id];
13074
+ // if (params && params.$container) {
13075
+ // await func.UI.screen.validate_exit_events(SESSION_ID, params.$container.data().xuData.paramsP, null);
13076
+ // func.datasource.clean_all(SESSION_ID, params.dsSession);
13077
+ // }
13078
+ // };
13066
13079
 
13067
- const close_all_modals = function () {
13068
- $.each(APP_MODAL_OBJ, function (key, val) {
13069
- if (val) {
13070
- // close_modal(key);
13071
- UI_FRAMEWORK_PLUGIN.modal.close(key);
13072
- }
13073
- });
13074
- };
13080
+ // const close_all_modals = function () {
13081
+ // $.each(APP_MODAL_OBJ, function (key, val) {
13082
+ // if (val) {
13083
+ // // close_modal(key);
13084
+ // UI_FRAMEWORK_PLUGIN.modal.close(key);
13085
+ // }
13086
+ // });
13087
+ // };
13075
13088
 
13076
- const open_popover = async function ($div) {
13077
- const xu_popover_controller = func.UI.component.create_app_popover_component(SESSION_ID);
13089
+ // const open_popover = async function ($div) {
13090
+ // const xu_popover_controller = func.UI.component.create_app_popover_component(SESSION_ID);
13078
13091
 
13079
- $(xu_popover_controller).data('xuControllerParams', {
13080
- menuTitle: paramsP.screenInfo.properties?.menuTitle,
13081
- screenId: paramsP.screenId,
13082
- $dialogDiv: $div.children(),
13083
- $container: $container,
13084
- });
13085
- const popover = new UI_FRAMEWORK_PLUGIN.popover(
13086
- SESSION_ID,
13087
- // ELEMENT_CLICK_EVENT,
13088
- // props
13089
- );
13090
- await popover.open(SESSION_ID);
13091
- CURRENT_APP_POPOVER = popover;
13092
+ // $(xu_popover_controller).data('xuControllerParams', {
13093
+ // menuTitle: paramsP.screenInfo.properties?.menuTitle,
13094
+ // screenId: paramsP.screenId,
13095
+ // $dialogDiv: $div.children(),
13096
+ // $container: $container,
13097
+ // });
13098
+ // const popover = new UI_FRAMEWORK_PLUGIN.popover(
13099
+ // SESSION_ID,
13100
+ // // ELEMENT_CLICK_EVENT,
13101
+ // // props
13102
+ // );
13103
+ // await popover.open(SESSION_ID);
13104
+ // CURRENT_APP_POPOVER = popover;
13105
+
13106
+ // return;
13107
+ // popoverController
13108
+ // .create({
13109
+ // component: 'xu-popover-content-' + SESSION_ID,
13110
+ // event: ELEMENT_CLICK_EVENT,
13111
+ // translucent: true,
13112
+ // })
13113
+ // .then((modal) => {
13114
+ // modal.present().then(() => {
13115
+ // CURRENT_APP_POPOVER = modal;
13092
13116
 
13093
- return;
13094
- popoverController
13095
- .create({
13096
- component: 'xu-popover-content-' + SESSION_ID,
13097
- event: ELEMENT_CLICK_EVENT,
13098
- translucent: true,
13099
- })
13100
- .then((modal) => {
13101
- modal.present().then(() => {
13102
- CURRENT_APP_POPOVER = modal;
13117
+ // if (callbackP) callbackP($div);
13118
+ // });
13119
+ // });
13120
+ // };
13121
+ // const iterate_child = async function ($divP, nodeP, parent_infoP, $root_container, before_record_function) {
13122
+ // if (!is_mobile && nodeP.busy) return;
13123
+ // nodeP.busy = true;
13124
+ // const done = async function ($divP) {
13125
+ // setTimeout(function () {
13126
+ // nodeP.busy = false;
13127
+ // }, 1000);
13128
+
13129
+ // return $divP;
13130
+ // };
13131
+ // if (!nodeP || !nodeP.children) {
13132
+ // return await done($divP);
13133
+ // }
13103
13134
 
13104
- if (callbackP) callbackP($div);
13105
- });
13106
- });
13107
- };
13108
- const iterate_child = async function ($divP, nodeP, parent_infoP, $root_container, before_record_function) {
13109
- if (!is_mobile && nodeP.busy) return;
13110
- nodeP.busy = true;
13111
- const done = async function ($divP) {
13112
- setTimeout(function () {
13113
- nodeP.busy = false;
13114
- }, 1000);
13135
+ // if (before_record_function) {
13136
+ // await before_record_function();
13137
+ // }
13138
+ // if (nodeP?.children?.length) {
13139
+ // let node_promises = [];
13140
+ // for (const [key, val] of Object.entries(nodeP.children)) {
13141
+ // node_promises.push(
13142
+ // new Promise(async (resolve, reject) => {
13143
+ // const ret = await func.UI.screen.render_ui_tree(SESSION_ID, $divP, nodeP.children[key], parent_infoP, paramsP, jobNoP, is_skeleton, Number(key), null, nodeP, null, $root_container);
13144
+
13145
+ // resolve();
13146
+ // }),
13147
+ // );
13148
+ // }
13149
+ // await Promise.all(node_promises);
13150
+ // }
13151
+ // return await done($divP);
13152
+ // };
13115
13153
 
13116
- return $divP;
13117
- };
13118
- if (!nodeP || !nodeP.children) {
13119
- return await done($divP);
13120
- }
13154
+ // // const iterate_child = async function ($divP, nodeP, parent_infoP, $root_container, before_record_function) {
13155
+ // // if (!is_mobile && nodeP.busy) return;
13156
+ // // nodeP.busy = true;
13157
+ // // const done = async function ($divP) {
13158
+ // // setTimeout(function () {
13159
+ // // nodeP.busy = false;
13160
+ // // }, 1000);
13121
13161
 
13122
- if (before_record_function) {
13123
- await before_record_function();
13124
- }
13125
- if (nodeP?.children?.length) {
13126
- let node_promises = [];
13127
- for (const [key, val] of Object.entries(nodeP.children)) {
13128
- node_promises.push(
13129
- new Promise(async (resolve, reject) => {
13130
- const ret = await func.UI.screen.render_ui_tree(SESSION_ID, $divP, nodeP.children[key], parent_infoP, paramsP, jobNoP, is_skeleton, Number(key), null, nodeP, null, $root_container);
13162
+ // // return $divP;
13163
+ // // };
13164
+ // // if (!nodeP || !nodeP.children) {
13165
+ // // return await done($divP);
13166
+ // // }
13167
+
13168
+ // // if (before_record_function) {
13169
+ // // await before_record_function();
13170
+ // // }
13171
+ // // if (nodeP?.children?.length) {
13172
+ // // for await (const [key, val] of Object.entries(nodeP.children)) {
13173
+ // // const ret = await func.UI.screen.render_ui_tree(SESSION_ID, $divP, nodeP.children[key], parent_infoP, paramsP, jobNoP, is_skeleton, Number(key), null, nodeP, null, $root_container);
13174
+ // // }
13175
+ // // }
13176
+ // // return await done($divP);
13177
+ // // };
13131
13178
 
13132
- resolve();
13133
- }),
13134
- );
13135
- }
13136
- await Promise.all(node_promises);
13137
- }
13138
- return await done($divP);
13139
- };
13179
+ // const _$ = function ($elm) {
13180
+ // try {
13181
+ // const id = $elm.attr('xu-ui-id');
13182
+ // if (!id || !glb.DEBUG_MODE) return $elm;
13183
+ // const $el = $(`[xu-ui-id="${id}"]`);
13140
13184
 
13141
- // const iterate_child = async function ($divP, nodeP, parent_infoP, $root_container, before_record_function) {
13142
- // if (!is_mobile && nodeP.busy) return;
13143
- // nodeP.busy = true;
13144
- // const done = async function ($divP) {
13145
- // setTimeout(function () {
13146
- // nodeP.busy = false;
13147
- // }, 1000);
13148
-
13149
- // return $divP;
13150
- // };
13151
- // if (!nodeP || !nodeP.children) {
13152
- // return await done($divP);
13153
- // }
13185
+ // if ($el.length > 1) {
13186
+ // console.warn('Multiple elements for xu-ui-id: ' + id, $el);
13187
+ // }
13154
13188
 
13155
- // if (before_record_function) {
13156
- // await before_record_function();
13157
- // }
13158
- // if (nodeP?.children?.length) {
13159
- // for await (const [key, val] of Object.entries(nodeP.children)) {
13160
- // const ret = await func.UI.screen.render_ui_tree(SESSION_ID, $divP, nodeP.children[key], parent_infoP, paramsP, jobNoP, is_skeleton, Number(key), null, nodeP, null, $root_container);
13161
- // }
13162
- // }
13163
- // return await done($divP);
13164
- // };
13189
+ // return $($el[0]);
13190
+ // } catch (e) {
13191
+ // console.error(e);
13192
+ // }
13193
+ // };
13165
13194
 
13166
- const _$ = function ($elm) {
13167
- try {
13168
- const id = $elm.attr('xu-ui-id');
13169
- if (!id || !glb.DEBUG_MODE) return $elm;
13170
- const $el = $(`[xu-ui-id="${id}"]`);
13195
+ // const hover_in = function ($div, e) {
13196
+ // if (is_skeleton || (e && (EXP_BUSY || UI_WORKER_OBJ.jobs.length))) return;
13197
+ // CLIENT_ACTIVITY_TS = Date.now();
13198
+ // if (_$($container)?.data()?.xuData?.debug_info) _$($container).data().xuData.debug_info.hover_item = $div.attr('xu-ui-id');
13199
+ // if (!_ds) return;
13200
+ // ///////// SET Attributes///////////
13201
+ // let attributes = {};
13202
+ // $.each($div[0].attributes, function (index, attr) {
13203
+ // attributes[attr.name] = attr.value;
13204
+ // });
13171
13205
 
13172
- if ($el.length > 1) {
13173
- console.warn('Multiple elements for xu-ui-id: ' + id, $el);
13174
- }
13206
+ // _session.DS_GLB[0].data_system.SYS_OBJ_WIN_ELEMENT_HOVERED_ATTRIBUTES = attributes;
13207
+ // //////////////////////////////////
13208
+ // if (!$div.data()?.xuData) return;
13209
+ // const _iterate_info = $div.data().xuData.iterate_info;
13210
+ // if (_iterate_info) {
13211
+ // if (_iterate_info.is_key_dynamic_field) {
13212
+ // _ds.dynamic_fields[_iterate_info.iterator_key].value = _iterate_info._key;
13213
+ // } else {
13214
+ // try {
13215
+ // const row_idx = func.common.find_ROWID_idx(_ds, _ds.currentRecordId);
13216
+ // _ds.data_feed.rows[row_idx][_iterate_info.iterator_key] = _iterate_info._key;
13217
+ // } catch (err) {
13218
+ // console.error(err);
13219
+ // }
13220
+ // }
13175
13221
 
13176
- return $($el[0]);
13177
- } catch (e) {
13178
- console.error(e);
13179
- }
13180
- };
13222
+ // if (_iterate_info.is_val_dynamic_field) {
13223
+ // _ds.dynamic_fields[_iterate_info.iterator_val].value = _iterate_info._val;
13224
+ // } else {
13225
+ // try {
13226
+ // const row_idx = func.common.find_ROWID_idx(_ds, _ds.currentRecordId);
13227
+ // _ds.data_feed.rows[row_idx][_iterate_info.iterator_val] = _iterate_info._val;
13228
+ // } catch (err) {
13229
+ // console.error(err);
13230
+ // }
13231
+ // }
13232
+ // }
13181
13233
 
13182
- const hover_in = function ($div, e) {
13183
- if (is_skeleton || (e && (EXP_BUSY || UI_WORKER_OBJ.jobs.length))) return;
13184
- CLIENT_ACTIVITY_TS = Date.now();
13185
- if (_$($container)?.data()?.xuData?.debug_info) _$($container).data().xuData.debug_info.hover_item = $div.attr('xu-ui-id');
13186
- if (!_ds) return;
13187
- ///////// SET Attributes///////////
13188
- let attributes = {};
13189
- $.each($div[0].attributes, function (index, attr) {
13190
- attributes[attr.name] = attr.value;
13191
- });
13234
+ // if ($div && _$($div) && _ds && paramsP.renderType === 'grid') {
13235
+ // func.UI.worker.add_to_queue(SESSION_ID, 'gui event', 'update_datasource', { currentRecordId: _$($div).data().xuData.currentRecordId }, null, null, paramsP.dsSessionP);
13236
+ // }
13192
13237
 
13193
- _session.DS_GLB[0].data_system.SYS_OBJ_WIN_ELEMENT_HOVERED_ATTRIBUTES = attributes;
13194
- //////////////////////////////////
13195
- if (!$div.data()?.xuData) return;
13196
- const _iterate_info = $div.data().xuData.iterate_info;
13197
- if (_iterate_info) {
13198
- if (_iterate_info.is_key_dynamic_field) {
13199
- _ds.dynamic_fields[_iterate_info.iterator_key].value = _iterate_info._key;
13200
- } else {
13201
- try {
13202
- const row_idx = func.common.find_ROWID_idx(_ds, _ds.currentRecordId);
13203
- _ds.data_feed.rows[row_idx][_iterate_info.iterator_key] = _iterate_info._key;
13204
- } catch (err) {
13205
- console.error(err);
13206
- }
13207
- }
13238
+ // const set_value = function (field_id, value) {
13239
+ // var currentRecordId = _$($div).data().xuData.currentRecordId;
13208
13240
 
13209
- if (_iterate_info.is_val_dynamic_field) {
13210
- _ds.dynamic_fields[_iterate_info.iterator_val].value = _iterate_info._val;
13211
- } else {
13212
- try {
13213
- const row_idx = func.common.find_ROWID_idx(_ds, _ds.currentRecordId);
13214
- _ds.data_feed.rows[row_idx][_iterate_info.iterator_val] = _iterate_info._val;
13215
- } catch (err) {
13216
- console.error(err);
13217
- }
13218
- }
13219
- }
13241
+ // func.UI.worker.add_to_queue(
13242
+ // SESSION_ID,
13243
+ // 'gui event',
13244
+ // 'update_datasource',
13245
+ // {
13246
+ // currentRecordId,
13247
+ // field_id,
13248
+ // field_value: value,
13249
+ // },
13250
+ // null,
13251
+ // null,
13252
+ // paramsP.dsSessionP,
13253
+ // );
13254
+ // };
13220
13255
 
13221
- if ($div && _$($div) && _ds && paramsP.renderType === 'grid') {
13222
- func.UI.worker.add_to_queue(SESSION_ID, 'gui event', 'update_datasource', { currentRecordId: _$($div).data().xuData.currentRecordId }, null, null, paramsP.dsSessionP);
13223
- }
13256
+ // if ($div?.data()?.iterate_info) {
13257
+ // var data = $div.data().xuData.iterate_info;
13258
+ // if (data.iterator_key) {
13259
+ // set_value(data.iterator_key, data._key);
13260
+ // }
13261
+ // if (data.iterator_val) {
13262
+ // set_value(data.iterator_val, data._val);
13263
+ // }
13264
+ // }
13265
+ // };
13266
+ // const hover_out = function () {
13267
+ // if (is_skeleton) return;
13224
13268
 
13225
- const set_value = function (field_id, value) {
13226
- var currentRecordId = _$($div).data().xuData.currentRecordId;
13269
+ // CLIENT_ACTIVITY_TS = Date.now();
13270
+ // if (_$($container)?.data()?.xuData?.debug_info) {
13271
+ // _$($container).data().xuData.debug_info.hover_item = null;
13272
+ // }
13273
+ // if (_ds?.data_system) {
13274
+ // SESSION_OBJ[SESSION_ID].DS_GLB[0].data_system.SYS_OBJ_WIN_ELEMENT_HOVERED_ATTRIBUTES = {};
13275
+ // }
13276
+ // };
13277
+ // const render_screen_type = async function ($div) {
13278
+ // const set_call_screen_properties_values = async function (ui_framework) {
13279
+ // params.properties = {};
13280
+ // const get_values = async function (property) {
13281
+ // var property_value = paramsP?.screenInfo?.properties?.[property] || paramsP?.screenInfo?.properties?.frameworkProperties?.[property];
13282
+ // if (paramsP?.call_screen_propertiesP) {
13283
+ // if (paramsP.call_screen_propertiesP?.[property]) {
13284
+ // property_value = paramsP.call_screen_propertiesP[property];
13285
+ // }
13286
+ // if (paramsP.call_screen_propertiesP[`xu-exp:${property}`]) {
13287
+ // property_value = (await func.expression.get(SESSION_ID, paramsP.call_screen_propertiesP[`xu-exp:${property}`], paramsP.dsSessionP, property)).result;
13288
+ // }
13289
+ // }
13290
+ // return property_value;
13291
+ // };
13292
+ // params.properties['name'] = await get_values('menuTitle');
13293
+ // if (await ui_framework?.properties()) {
13294
+ // for await (const [key, val] of Object.entries(await ui_framework.properties())) {
13295
+ // params.properties[key] = await get_values(key);
13296
+ // }
13297
+ // }
13298
+ // };
13227
13299
 
13228
- func.UI.worker.add_to_queue(
13229
- SESSION_ID,
13230
- 'gui event',
13231
- 'update_datasource',
13232
- {
13233
- currentRecordId,
13234
- field_id,
13235
- field_value: value,
13236
- },
13237
- null,
13238
- null,
13239
- paramsP.dsSessionP,
13240
- );
13241
- };
13300
+ // var $div_content = $div.children();
13242
13301
 
13243
- if ($div?.data()?.iterate_info) {
13244
- var data = $div.data().xuData.iterate_info;
13245
- if (data.iterator_key) {
13246
- set_value(data.iterator_key, data._key);
13247
- }
13248
- if (data.iterator_val) {
13249
- set_value(data.iterator_val, data._val);
13250
- }
13251
- }
13252
- };
13253
- const hover_out = function () {
13254
- if (is_skeleton) return;
13302
+ // $.each($div_content, function (key, val) {
13303
+ // if (!$(val)?.data()?.xuData?.parent_container) {
13304
+ // return true;
13305
+ // }
13306
+ // $(val).data().xuData.parent_container = $div.data().xuData.parent_container;
13307
+ // });
13255
13308
 
13256
- CLIENT_ACTIVITY_TS = Date.now();
13257
- if (_$($container)?.data()?.xuData?.debug_info) {
13258
- _$($container).data().xuData.debug_info.hover_item = null;
13259
- }
13260
- if (_ds?.data_system) {
13261
- SESSION_OBJ[SESSION_ID].DS_GLB[0].data_system.SYS_OBJ_WIN_ELEMENT_HOVERED_ATTRIBUTES = {};
13262
- }
13263
- };
13264
- const render_screen_type = async function ($div) {
13265
- const set_call_screen_properties_values = async function (ui_framework) {
13266
- params.properties = {};
13267
- const get_values = async function (property) {
13268
- var property_value = paramsP?.screenInfo?.properties?.[property] || paramsP?.screenInfo?.properties?.frameworkProperties?.[property];
13269
- if (paramsP?.call_screen_propertiesP) {
13270
- if (paramsP.call_screen_propertiesP?.[property]) {
13271
- property_value = paramsP.call_screen_propertiesP[property];
13272
- }
13273
- if (paramsP.call_screen_propertiesP[`xu-exp:${property}`]) {
13274
- property_value = (await func.expression.get(SESSION_ID, paramsP.call_screen_propertiesP[`xu-exp:${property}`], paramsP.dsSessionP, property)).result;
13309
+ // let $ret = $div;
13310
+ // var $nav = $(SESSION_OBJ[SESSION_ID].root_element).find('xu-nav');
13311
+ // var params;
13312
+ // switch (paramsP.screen_type) {
13313
+ // case 'modal':
13314
+ // const modal_id = 'app_modal-' + paramsP.dsSessionP.toString();
13315
+ // var xu_modal_controller = document.querySelector('xu-modal-controller');
13316
+ // if (!xu_modal_controller) {
13317
+ // func.UI.component.create_app_modal_component(SESSION_ID, modal_id);
13318
+ // xu_modal_controller = document.querySelector('xu-modal-controller');
13319
+ // }
13320
+
13321
+ // var controller_params = $(xu_modal_controller).data('xuControllerParams');
13322
+
13323
+ // if (!controller_params) {
13324
+ // controller_params = {};
13325
+ // }
13326
+
13327
+ // params = {
13328
+ // screenId: paramsP.screenId,
13329
+ // $dialogDiv: $div.children(),
13330
+ // $container: $container,
13331
+ // dsSession: paramsP.dsSessionP,
13332
+ // modal_id,
13333
+ // screenInfo: paramsP.screenInfo,
13334
+ // close_callback: close_modal,
13335
+ // paramsP,
13336
+ // };
13337
+
13338
+ // controller_params[modal_id] = params;
13339
+
13340
+ // $(xu_modal_controller).data('xuControllerParams', controller_params);
13341
+ // const modalController = await new UI_FRAMEWORK_PLUGIN.modal();
13342
+ // await set_call_screen_properties_values(modalController);
13343
+ // if (!APP_MODAL_OBJ[modal_id]) {
13344
+ // const modal = await modalController.create(params);
13345
+
13346
+ // APP_MODAL_OBJ[modal_id] = modal;
13347
+ // } else {
13348
+ // $(modal_id).empty();
13349
+ // }
13350
+
13351
+ // await modalController.init(params);
13352
+
13353
+ // break;
13354
+
13355
+ // case 'popover':
13356
+ // // open_popover($div);
13357
+
13358
+ // const xu_popover_controller = func.UI.component.create_app_popover_component(SESSION_ID);
13359
+ // params = {
13360
+ // menuTitle: paramsP.screenInfo.properties?.menuTitle,
13361
+ // screenId: paramsP.screenId,
13362
+ // $dialogDiv: $div.children(),
13363
+ // $container: $container,
13364
+ // };
13365
+
13366
+ // $(xu_popover_controller).data('xuControllerParams', params);
13367
+ // const popover = new UI_FRAMEWORK_PLUGIN.popover(SESSION_ID);
13368
+ // await set_call_screen_properties_values(popover);
13369
+ // await popover.open(params);
13370
+ // CURRENT_APP_POPOVER = popover;
13371
+
13372
+ // func.UI.utils.screen_blocker(false, paramsP.prog_id + '_' + paramsP.sourceScreenP);
13373
+ // break;
13374
+
13375
+ // case 'page':
13376
+ // const nav = $nav[0];
13377
+
13378
+ // params = {
13379
+ // div: $div_content,
13380
+ // name: paramsP.screenInfo.properties?.menuTitle,
13381
+ // screenId: paramsP.screenId,
13382
+ // $container: $container,
13383
+ // dsSession: paramsP.dsSessionP,
13384
+ // SESSION_ID,
13385
+ // nav,
13386
+ // paramsP,
13387
+ // };
13388
+
13389
+ // var component_name = 'xu-page-component-' + paramsP.dsSessionP;
13390
+ // if (!$(nav).data().xuData.nav_params) {
13391
+ // $(nav).data().xuData.nav_params = {};
13392
+ // }
13393
+
13394
+ // //restore validate
13395
+ // if ($(nav)?.data()?.xuData?.params?.[paramsP.dsSessionP]) {
13396
+ // params.$container.data().xuData.validate_screen_ready = $(nav).data().xuData.params[paramsP.dsSessionP].$container.data().xuData.validate_screen_ready;
13397
+ // }
13398
+
13399
+ // if (!$(nav)?.data()?.xuData) return;
13400
+ // $(nav).data().xuData.nav_params[paramsP.dsSessionP] = params;
13401
+ // if (!$(component_name).length) {
13402
+ // await func.UI.component.create_app_page_component(SESSION_ID, paramsP.dsSessionP);
13403
+ // const page = new UI_FRAMEWORK_PLUGIN.page();
13404
+ // await set_call_screen_properties_values(page);
13405
+ // await page.create(params);
13406
+ // await page.init(params);
13407
+ // nav.push(component_name, { params });
13408
+ // } else {
13409
+ // debugger;
13410
+ // $(component_name).empty();
13411
+
13412
+ // await UI_FRAMEWORK_PLUGIN.page(SESSION_ID, paramsP.dsSessionP);
13413
+ // }
13414
+ // $div.data().xuData.paramsP = $container.data().xuData.paramsP;
13415
+ // break;
13416
+
13417
+ // case 'panel':
13418
+ // $container.append($div_content);
13419
+ // $ret = $container;
13420
+ // break;
13421
+
13422
+ // default: // set data to nav to use in the component
13423
+ // if ($nav && $nav.length) {
13424
+ // // refresh made
13425
+ // } else {
13426
+ // $nav = $('<xu-nav>'); //.attr('xu-ui-id', SESSION_ID);
13427
+ // $container.append($nav);
13428
+ // func.UI.component.init_xu_nav($container, $nav);
13429
+ // }
13430
+
13431
+ // $nav.data().xuData.$div = $div_content;
13432
+
13433
+ // await $nav[0].setRoot('xu-root-component-' + SESSION_ID);
13434
+ // $ret = $container;
13435
+ // break;
13436
+ // }
13437
+ // return $ret;
13438
+ // };
13439
+
13440
+ // if (!(await init())) return;
13441
+ // debug();
13442
+ // const fx = {
13443
+ // widget: async function () {
13444
+ // var _session = SESSION_OBJ[SESSION_ID];
13445
+
13446
+ // var exist_elm_obj = get_element_info();
13447
+ // var $div = exist_elm_obj.div;
13448
+ // if (!exist_elm_obj.div) {
13449
+ // $div = await func.UI.screen.create_container(SESSION_ID, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, prop, 'widget_wrapper', null, null, null, null);
13450
+
13451
+ // //////////////////////////
13452
+
13453
+ // let plugin_name = prop['xu-widget'],
13454
+ // method = prop['xu-method'],
13455
+ // dsP = paramsP.dsSessionP,
13456
+ // propsP = prop,
13457
+ // sourceP = 'widgets';
13458
+
13459
+ // // const set_SYS_GLOBAL_OBJ_WIDGET_INFO = async function (docP) {
13460
+ // // var obj = _.clone(docP);
13461
+ // // obj.date = await func.utils.get_dateTime(
13462
+ // // SESSION_ID,
13463
+ // // "SYS_DATE",
13464
+ // // docP.date
13465
+ // // );
13466
+ // // obj.time = await func.utils.get_dateTime(
13467
+ // // SESSION_ID,
13468
+ // // "SYS_TIME",
13469
+ // // docP.date
13470
+ // // );
13471
+
13472
+ // // var datasource_changes = {
13473
+ // // [0]: {
13474
+ // // ["data_system"]: {
13475
+ // // ["SYS_GLOBAL_OBJ_WIDGET_INFO"]: obj,
13476
+ // // },
13477
+ // // },
13478
+ // // };
13479
+ // // await func.datasource.update(SESSION_ID, datasource_changes);
13480
+ // // };
13481
+ // const call_plugin_api = async function (plugin_nameP, dataP) {
13482
+ // return await func.utils.call_plugin_api(SESSION_ID, plugin_nameP, dataP);
13483
+ // };
13484
+ // const report_error = function (descP, warn) {
13485
+ // func.utils.debug.log(SESSION_ID, _session.DS_GLB[dsP].prog_id + '_' + _session.DS_GLB[dsP].callingMenuId, {
13486
+ // module: 'widgets',
13487
+ // action: 'Init',
13488
+ // source: sourceP,
13489
+ // prop: descP,
13490
+ // details: descP,
13491
+ // result: null,
13492
+ // error: warn ? false : true,
13493
+ // fields: null,
13494
+ // type: 'widgets',
13495
+ // prog_id: _session.DS_GLB[dsP].prog_id,
13496
+ // });
13497
+ // };
13498
+ // const get_fields_data = async function (fields, props) {
13499
+ // const report_error = function (descP, warn) {
13500
+ // func.utils.debug.log(SESSION_ID, _session.DS_GLB[dsP].prog_id + '_' + _session.DS_GLB[dsP].callingMenuId, {
13501
+ // module: 'widgets',
13502
+ // action: 'Init',
13503
+ // source: sourceP,
13504
+ // prop: descP,
13505
+ // details: descP,
13506
+ // result: null,
13507
+ // error: warn ? false : true,
13508
+ // fields: null,
13509
+ // type: 'widgets',
13510
+ // prog_id: _session.DS_GLB[dsP].prog_id,
13511
+ // });
13512
+ // };
13513
+ // const get_property_value = async function (fieldIdP, val) {
13514
+ // if (!val) return;
13515
+ // var value = fieldIdP in props ? props[fieldIdP] : typeof val.defaultValue === 'function' ? val?.defaultValue?.() : val?.defaultValue;
13516
+ // if (val.render === 'eventId') {
13517
+ // value = props?.[fieldIdP]?.event;
13518
+ // }
13519
+
13520
+ // if (props[`xu-exp:${fieldIdP}`]) {
13521
+ // value = (await func.expression.get(SESSION_ID, props[`xu-exp:${fieldIdP}`], dsP, 'widget property')).result;
13522
+ // }
13523
+
13524
+ // return func.common.get_cast_val(
13525
+ // SESSION_ID,
13526
+ // 'widgets',
13527
+ // fieldIdP,
13528
+ // val.type, //val.type !== "string" || val.type !== "number" ? "string" : val.type,
13529
+ // value,
13530
+ // null,
13531
+ // );
13532
+ // };
13533
+ // var data_obj = {};
13534
+ // var return_code = 1;
13535
+ // // $.each(fields, function (key, val) {
13536
+ // for await (const [key, val] of Object.entries(fields)) {
13537
+ // data_obj[key] = await get_property_value(key, val);
13538
+ // if (!data_obj[key] && val.mandatory) {
13539
+ // return_code = -1;
13540
+ // report_error(`${key} is a mandatory field.`);
13541
+ // break;
13542
+ // }
13543
+ // // console.log(val);
13544
+ // }
13545
+ // for await (const key of ['xu-bind']) {
13546
+ // data_obj[key] = await get_property_value(key, props[key]);
13547
+ // }
13548
+
13549
+ // return { code: return_code, data: data_obj };
13550
+ // };
13551
+
13552
+ // const load_css_style = function () {
13553
+ // const get_css_path = function (resource) {
13554
+ // if (_session.worker_type === 'Dev') {
13555
+ // return `../../plugins/${plugin_name}/${resource}`;
13556
+ // }
13557
+ // return `https://${_session.domain}/plugins/${plugin_name}/${APP_OBJ[_session.app_id].app_plugins_purchased[plugin_name].manifest[resource].dist ? 'dist/' : ''}${resource}?gtp_token=${_session.gtp_token}&app_id=${_session.app_id}`;
13558
+ // };
13559
+ // let path = get_css_path('style.css');
13560
+ // func.utils.load_css_on_demand(path);
13561
+ // };
13562
+
13563
+ // const _plugin = APP_OBJ[_session.app_id]?.app_plugins_purchased?.[plugin_name];
13564
+ // const index = await func.utils.get_plugin_resource(SESSION_ID, plugin_name, `${_plugin.manifest['index.mjs'].dist ? 'dist/' : ''}index.mjs`);
13565
+ // const methods = index.methods;
13566
+ // if (methods && !methods[method]) {
13567
+ // return report_error('method not found');
13568
+ // }
13569
+
13570
+ // const fields_ret = await get_fields_data(methods[method].fields, propsP);
13571
+ // if (fields_ret.code < 0) {
13572
+ // return report_error(fields_ret.data);
13573
+ // }
13574
+ // const fields = fields_ret.data;
13575
+
13576
+ // let exclude_attributes = [];
13577
+ // for await (const [key, val] of Object.entries(propsP)) {
13578
+ // if (typeof fields[key] !== 'undefined' || typeof fields[`xu-exp:${key}`] !== 'undefined') {
13579
+ // exclude_attributes.push(key);
13580
+ // }
13581
+ // }
13582
+
13583
+ // let ret = await func.UI.screen.set_attributes_new(SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, $div, true, exclude_attributes);
13584
+
13585
+ // $div.addClass('widget_wrapper'); // class get override in set_attributes_new
13586
+
13587
+ // if (!APP_OBJ[_session.app_id].app_plugins_purchased[plugin_name]) {
13588
+ // return report_error(`plugin ${plugin_name} not found`);
13589
+ // }
13590
+
13591
+ // if (APP_OBJ[_session.app_id].app_plugins_purchased[plugin_name].manifest['style.css'].exist) {
13592
+ // load_css_style();
13593
+ // }
13594
+
13595
+ // const plugin_setup_ret = await func.utils.get_plugin_setup(SESSION_ID, plugin_name);
13596
+ // if (plugin_setup_ret.code < 0) {
13597
+ // return report_error(plugin_setup_ret);
13598
+ // }
13599
+
13600
+ // const api_utils = await func.common.get_module(SESSION_ID, 'xuda-api-library.mjs', {
13601
+ // func,
13602
+ // glb,
13603
+ // SESSION_OBJ,
13604
+ // SESSION_ID,
13605
+ // APP_OBJ,
13606
+ // dsSession: paramsP.dsSessionP,
13607
+ // job_id: jobNoP,
13608
+ // });
13609
+
13610
+ // const params = {
13611
+ // SESSION_ID,
13612
+ // method,
13613
+ // _session,
13614
+ // dsP,
13615
+ // sourceP,
13616
+ // propsP,
13617
+ // plugin_name,
13618
+ // $containerP: $div,
13619
+ // plugin_setup: plugin_setup_ret.data,
13620
+
13621
+ // report_error,
13622
+ // call_plugin_api,
13623
+ // // set_SYS_GLOBAL_OBJ_WIDGET_INFO,
13624
+ // api_utils,
13625
+ // };
13626
+
13627
+ // const fx = await func.utils.get_plugin_resource(SESSION_ID, plugin_name, `${_plugin.manifest['runtime.mjs'].dist ? 'dist/' : ''}runtime.mjs`);
13628
+
13629
+ // if (_plugin?.manifest?.['runtime.mjs'].dist && _plugin?.manifest?.['runtime.mjs']?.css) {
13630
+ // const plugin_runtime_css_url = await func.utils.get_plugin_npm_cdn(SESSION_ID, plugin_name, 'dist/runtime.css');
13631
+ // func.utils.load_css_on_demand(plugin_runtime_css_url);
13632
+ // }
13633
+
13634
+ // if (!fx[method]) {
13635
+ // throw `Method: ${method} does not exist`;
13636
+ // }
13637
+ // try {
13638
+ // await fx[method](fields, params);
13639
+ // } catch (err) {
13640
+ // func.utils.debug_report(SESSION_ID, `${plugin_name} widget`, err.message, 'E');
13641
+ // }
13642
+ // }
13643
+ // return $div;
13644
+ // },
13645
+ // [`xu-single-view`]: async function () {
13646
+ // var exist_elm_obj = get_element_info();
13647
+ // var $div = exist_elm_obj.div;
13648
+
13649
+ // if (!exist_elm_obj.div) {
13650
+ // var $wrapper = $('<div>');
13651
+ // $div = await func.UI.screen.create_container(SESSION_ID, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, prop, null, null, 'div', $wrapper, '');
13652
+
13653
+ // if (!$div) return;
13654
+
13655
+ // if (!REFRESHER_IN_PROGRESS && (paramsP.is_mobile_popover || paramsP.is_mobile_page)) {
13656
+ // close_all_modals();
13657
+ // }
13658
+
13659
+ // $div.hover(
13660
+ // function (e) {
13661
+ // hover_in();
13662
+ // // func.UI.screen.hover_in(SESSION_ID, null, $container, paramsP, is_skeleton);
13663
+ // },
13664
+ // function (e) {
13665
+ // // func.UI.screen.hover_out(SESSION_ID, $container, is_skeleton, paramsP);
13666
+ // hover_out();
13667
+ // },
13668
+ // );
13669
+ // }
13670
+
13671
+ // const ret = await iterate_child($div, nodeP, null, $div);
13672
+ // if (_.isEmpty($container.data().xuAttributes)) {
13673
+ // await func.UI.screen.set_attributes_new(SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, $container, true);
13674
+ // }
13675
+
13676
+ // $.each($div.data().xuData, function (key, val) {
13677
+ // $container.data().xuData[key] = _.cloneDeep(val);
13678
+ // });
13679
+ // $.each($div.data().xuAttributes, function (key, val) {
13680
+ // // $container.data().xuAttributes[key] = _.cloneDeep(val);
13681
+ // $container.data().xuAttributes[key] = klona.klona(val);
13682
+ // });
13683
+
13684
+ // return await render_screen_type($div);
13685
+ // },
13686
+ // [`xu-multi-view`]: async function () {
13687
+ // var $div = $container;
13688
+
13689
+ // if (!$div.data().xuData.node || !$div.data().xuData.node.children) {
13690
+ // $div.data().xuData.node = nodeP;
13691
+ // }
13692
+
13693
+ // if (!$div.data().xuData.debug_info) {
13694
+ // $div.data().xuData.debug_info = {
13695
+ // id: nodeP.id,
13696
+ // parent_id: $container.data().xuData.ui_id,
13697
+ // };
13698
+ // }
13699
+
13700
+ // const done = async function (continuous_idx) {
13701
+ // // const do_callback = async function ($div) {
13702
+ // // // if ($root_container.data().xuData.progress_bar_circle) {
13703
+ // // // setTimeout(function () {
13704
+ // // // $.each(
13705
+ // // // $root_container.data().xuData.progress_bar_circle,
13706
+ // // // function (key, val) {
13707
+ // // // val.bar.set(parseFloat(val.value)); // Number from 0.0 to 1.0
13708
+ // // // }
13709
+ // // // );
13710
+ // // // }, 2000);
13711
+ // // // }
13712
+
13713
+ // // if (paramsP.screenInfo.properties?.rtl) {
13714
+ // // $div_content.attr('dir', 'rtl');
13715
+ // // }
13716
+
13717
+ // // return $div;
13718
+ // // };
13719
+ // await func.UI.screen.set_attributes_new(SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, $container, true);
13720
+
13721
+ // return await render_screen_type($div);
13722
+ // };
13723
+
13724
+ // if (!REFRESHER_IN_PROGRESS && (paramsP.is_mobile_popover || paramsP.is_mobile_page)) {
13725
+ // close_all_modals();
13726
+ // }
13727
+
13728
+ // const empty_result = async function () {
13729
+ // // var content = prop.empty_result_content || '';
13730
+
13731
+ // // var res = await func.expression.get(
13732
+ // // SESSION_ID,
13733
+ // // content, // prop["xu-exp:empty_result_content"],
13734
+ // // paramsP.dsSessionP,
13735
+ // // 'empty_result_content_EXP',
13736
+ // // _ds.currentRecordId,
13737
+ // // );
13738
+ // // content = res.result;
13739
+
13740
+ // // let empty_result_node = {
13741
+ // // type: 'element',
13742
+ // // id: crypto.randomUUID(),
13743
+ // // content,
13744
+ // // // : content || (typeof content === "undefined" && "Empty results"),
13745
+ // // tagName: 'div',
13746
+ // // attributes: {},
13747
+ // // children: [],
13748
+ // // };
13749
+
13750
+ // // const ret = await func.UI.screen.render_ui_tree(SESSION_ID, $container, empty_result_node, parent_infoP, paramsP, jobNoP, null, 0, null, nodeP, null, $root_container);
13751
+ // await func.events.validate(SESSION_ID, 'record_not_found', paramsP.dsSessionP);
13752
+ // return await done(null);
13753
+ // };
13754
+ // var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP];
13755
+
13756
+ // var continuous_idx = null;
13757
+
13758
+ // if (!_ds.data_feed || _.isEmpty(_ds.data_feed.rows)) {
13759
+ // return await empty_result();
13760
+ // }
13761
+
13762
+ // var i = 0;
13763
+ // for await (const [key, val] of Object.entries(_ds.data_feed.rows)) {
13764
+ // var node = JSON.parse(JSON.stringify(nodeP));
13765
+
13766
+ // _ds.currentRecordId = val._ROWID;
13767
+ // const ret = await iterate_child($div, node, { continuous_idx }, $root_container);
13768
+
13769
+ // if (_.isEmpty($container.data().xuAttributes)) {
13770
+ // await func.UI.screen.set_attributes_new(SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, $container, true);
13771
+ // }
13772
+ // }
13773
+
13774
+ // return await done(continuous_idx);
13775
+ // },
13776
+ // [`xu-panel`]: async function () {
13777
+ // const done = async function ($new_div) {
13778
+ // if (!$container.data()?.xuData?.paramsP) {
13779
+ // return $container;
13780
+ // }
13781
+ // var $div_items = $div.data().xuData.node.children;
13782
+
13783
+ // await func.UI.screen.panel_post_render_handler(SESSION_ID, $container, $new_div, nodeP, $div, jobNoP);
13784
+
13785
+ // // TO FIX should be timeout
13786
+ // $container.data().xuData.node.children = $div_items;
13787
+
13788
+ // return $container;
13789
+ // };
13790
+
13791
+ // var $wrapper = $('<div>');
13792
+ // $div = await func.UI.screen.create_container(SESSION_ID, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, prop, null, null, null, $wrapper, '');
13793
+
13794
+ // let ret = await func.UI.screen.set_attributes_new(SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, $div.clone(true), true, undefined, refreshed_ds);
13795
+ // if (ret.abort) {
13796
+ // // render N
13797
+ // return (ret.$new_div = $('<template>').append($div));
13798
+ // }
13799
+
13800
+ // let $ret_panel_div = ret.$new_div;
13801
+
13802
+ // if (!$ret_panel_div?.children()?.length) {
13803
+ // ////// render default children tree
13804
+ // if (nodeP.children.length) {
13805
+ // $ret_panel_div = await func.UI.screen.render_ui_tree(SESSION_ID, $container, nodeP.children[0], parent_infoP, paramsP, jobNoP, null, 0, null, nodeP, null, $root_container);
13806
+ // }
13807
+ // }
13808
+
13809
+ // let ret_done = await done($ret_panel_div);
13810
+
13811
+ // return ret_done;
13812
+ // },
13813
+ // };
13814
+
13815
+ // const draw_html_element_org = async function (element) {
13816
+ // const done = async function (ret = {}) {
13817
+ // return $div;
13818
+ // };
13819
+ // if (!element || element === 'script') return await done();
13820
+ // let str = '';
13821
+
13822
+ // var $div = await func.UI.screen.create_container(SESSION_ID, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, prop, null, null, element, null, str);
13823
+
13824
+ // $div.hover(
13825
+ // function (e) {
13826
+ // hover_in($div, e);
13827
+ // },
13828
+ // function (e) {
13829
+ // hover_out();
13830
+ // },
13831
+ // );
13832
+ // if (paramsP.paramsP === 'grid' || parent_infoP?.iterate_info) {
13833
+ // $div.on('click contextmenu', function (e) {
13834
+ // hover_in($div, e);
13835
+ // });
13836
+ // }
13837
+
13838
+ // // let ret = await func.UI.screen.set_attributes_new(SESSION_ID, is_skeleton, $container, nodeP, $div, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, $div, true);
13839
+ // let ret = await func.UI.screen.set_attributes_new(SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, $div, true);
13840
+ // if (ret.abort || nodeP.tagName === 'svg' || !_.isEmpty(nodeP?.attributes?.['xu-text']) || !_.isEmpty(nodeP?.attributes?.['xu-html']) || !_.isEmpty(nodeP?.attributes?.['xu-exp:xu-text']) || !_.isEmpty(nodeP?.attributes?.['xu-exp:xu-html'])) {
13841
+ // return await done(ret);
13842
+ // }
13843
+ // // check if iterator made to prevent children render
13844
+
13845
+ // if (nodeP?.attributes?.['xu-viewport'] == 'true') {
13846
+ // // const xu_viewport = async function () {
13847
+ // // const data = { $div: $div.clone(true), nodeP, parent_infoP, $root_container, paramsP, jobNoP, is_skeleton, keyP, refreshed_ds, parent_nodeP, check_existP, $container };
13848
+ // // const container_id = $container.attr('xu-ui-id');
13849
+ // // if (!UI_WORKER_OBJ.pending_for_viewport_render[container_id]) {
13850
+ // // UI_WORKER_OBJ.pending_for_viewport_render[container_id] = { base_$div: $div, data: [], $container };
13851
+ // // await iterate_child($div, nodeP, parent_infoP, $root_container);
13852
+ // // } else {
13853
+ // // $div.remove();
13854
+ // // }
13855
+ // // UI_WORKER_OBJ.pending_for_viewport_render[container_id].data.push(data);
13856
+
13857
+ // // // if (!$div.children().length) {
13858
+ // // // // render the first element to determine height
13859
+ // // // await iterate_child($div, nodeP, parent_infoP, $root_container);
13860
+ // // // // hover_in($div);
13861
+ // // // // func.UI.worker.add_to_queue(SESSION_ID, 'gui event', 'render_viewport', data, null, null, paramsP.dsSessionP);
13862
+ // // // } else {
13863
+ // // // }
13864
+ // // };
13865
+ // const xu_viewport = function () {
13866
+ // const observer_inViewport = new IntersectionObserver(
13867
+ // function (entries) {
13868
+ // entries.forEach((entry) => {
13869
+ // if (entry.isIntersecting) {
13870
+ // $(entry.target).trigger('inViewport');
13871
+
13872
+ // // Optional: stop observing once triggered
13873
+ // observer_inViewport.unobserve(entry.target);
13874
+ // }
13875
+ // });
13876
+ // },
13877
+ // {
13878
+ // threshold: 0.1, // Trigger when 10% of element is visible
13879
+ // },
13880
+ // );
13881
+
13882
+ // const observer_outViewport = new IntersectionObserver(
13883
+ // function (entries) {
13884
+ // entries.forEach((entry) => {
13885
+ // if (!entry.isIntersecting) {
13886
+ // // Element is OUT of viewport - trigger custom event
13887
+ // $(entry.target).trigger('outViewport');
13888
+
13889
+ // // Optional: stop observing once triggered
13890
+ // // observer_outViewport.unobserve(entry.target);
13891
+ // }
13892
+ // });
13893
+ // },
13894
+ // {
13895
+ // threshold: 0, // Trigger when element is completely out of view
13896
+ // },
13897
+ // );
13898
+
13899
+ // let ui_job_id;
13900
+ // $div.on('inViewport', function () {
13901
+ // if ($div.children().length) {
13902
+ // $div.removeClass('skeleton');
13903
+ // return;
13904
+ // }
13905
+
13906
+ // // if (UI_WORKER_OBJ.cache[$div.attr('xu-ui-id')]) {
13907
+ // // $div[0].style.removeProperty('height');
13908
+ // // $div.removeClass('skeleton');
13909
+ // // $div.html(UI_WORKER_OBJ.cache[$div.attr('xu-ui-id')]);
13910
+ // // } else {
13911
+ // hover_in($div);
13912
+ // ui_job_id = func.UI.worker.add_to_queue(SESSION_ID, 'gui event', 'render_viewport', { $div, nodeP, parent_infoP, $root_container, paramsP, jobNoP, is_skeleton, keyP, refreshed_ds, parent_nodeP, check_existP, $container }, null, null, paramsP.dsSessionP);
13913
+ // // }
13914
+ // observer_outViewport.observe($div[0]);
13915
+ // });
13916
+
13917
+ // $div.on('outViewport', function () {
13918
+ // func.UI.worker.delete_job(SESSION_ID, ui_job_id);
13919
+
13920
+ // if ($div.children().length) {
13921
+ // // UI_WORKER_OBJ.cache[$div.attr('xu-ui-id')] = $div.children().clone(true);
13922
+ // $div.empty();
13923
+ // const height = $div?.data()?.xuData?.viewport_height || 10;
13924
+ // if (typeof height !== 'undefined') {
13925
+ // $div.css('height', height);
13926
+ // }
13927
+ // }
13928
+ // // $div.addClass('skeleton');
13929
+ // observer_inViewport.observe($div[0]);
13930
+ // });
13931
+ // $div.addClass('skeleton');
13932
+ // observer_inViewport.observe($div[0]);
13933
+ // };
13934
+ // xu_viewport();
13935
+ // } else {
13936
+ // await iterate_child($div, nodeP, parent_infoP, $root_container);
13937
+ // }
13938
+
13939
+ // // const ret_iterate_child = await iterate_child($div, nodeP, parent_infoP, null, $root_container);
13940
+ // return await done(ret);
13941
+ // };
13942
+
13943
+ // const draw_html_element = async function (element) {
13944
+ // const done = async function (ret = {}) {
13945
+ // const xu_ui_id = $div.attr('xu-ui-id');
13946
+ // $div.removeClass('display_none');
13947
+ // if (ret.has_xu_exp_render_attribute) {
13948
+ // // $div.css('display', 'unset');
13949
+
13950
+ // const xu_render_cache_id = await get_xu_render_cache_str(SESSION_ID, paramsP.dsSessionP, Object.keys($div.data()?.xuData?.attr_exp_info?.['xu-render']?.fields || {}));
13951
+ // const _$div = $div.clone(true);
13952
+ // UI_WORKER_OBJ.xu_render_cache[xu_ui_id + xu_render_cache_id] = { $div: _$div, paramsP, data: _$div.data() };
13953
+ // nodeP.xu_render_xu_ui_id = xu_ui_id;
13954
+ // nodeP.xu_render_cache_id = xu_render_cache_id;
13955
+
13956
+ // if (ret.xu_render_background_processing) {
13957
+ // temp_$div.remove();
13958
+ // // $container.find(`[xu-ui-id="${xu_ui_id}"]`).remove();
13959
+ // return $div;
13960
+ // } else {
13961
+ // // $div.css('display', 'unset');
13962
+ // temp_$div.replaceWith($div);
13963
+ // return $div;
13964
+ // }
13965
+ // } else {
13966
+ // if (ret.has_xu_render_attribute) {
13967
+ // temp_$div.remove();
13968
+ // return $div;
13969
+ // }
13970
+ // // $div.css('display', 'unset');
13971
+ // temp_$div.replaceWith($div);
13972
+ // return $div;
13973
+ // }
13974
+ // };
13975
+ // if (!element || element === 'script') return await done();
13976
+ // let str = '';
13977
+
13978
+ // var temp_$div = await func.UI.screen.create_container(SESSION_ID, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, prop, null, null, element, null, str, true);
13979
+
13980
+ // let temp_$container = $('<tmp>').data('xuData', $container.data().xuData);
13981
+ // let $div = temp_$div.clone(true);
13982
+
13983
+ // // $div.css('display', 'none');
13984
+
13985
+ // $div.hover(
13986
+ // function (e) {
13987
+ // hover_in($div, e);
13988
+ // },
13989
+ // function (e) {
13990
+ // hover_out();
13991
+ // },
13992
+ // );
13993
+ // if (paramsP.paramsP === 'grid' || parent_infoP?.iterate_info) {
13994
+ // $div.on('click contextmenu', function (e) {
13995
+ // hover_in($div, e);
13996
+ // });
13997
+ // }
13998
+
13999
+ // let ret = await func.UI.screen.set_attributes_new(SESSION_ID, is_skeleton, $root_container, nodeP, temp_$container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, $div, true);
14000
+ // if (ret.abort || nodeP.tagName === 'svg' || !_.isEmpty(nodeP?.attributes?.['xu-text']) || !_.isEmpty(nodeP?.attributes?.['xu-html']) || !_.isEmpty(nodeP?.attributes?.['xu-exp:xu-text']) || !_.isEmpty(nodeP?.attributes?.['xu-exp:xu-html'])) {
14001
+ // return await done(ret);
14002
+ // }
14003
+ // // check if iterator made to prevent children render
14004
+
14005
+ // if (nodeP?.attributes?.['xu-viewport'] == 'true') {
14006
+ // // const xu_viewport = async function () {
14007
+ // // const data = { $div: $div.clone(true), nodeP, parent_infoP, $root_container, paramsP, jobNoP, is_skeleton, keyP, refreshed_ds, parent_nodeP, check_existP, $container };
14008
+ // // const container_id = $container.attr('xu-ui-id');
14009
+ // // if (!UI_WORKER_OBJ.pending_for_viewport_render[container_id]) {
14010
+ // // UI_WORKER_OBJ.pending_for_viewport_render[container_id] = { base_$div: $div, data: [], $container };
14011
+ // // await iterate_child($div, nodeP, parent_infoP, $root_container);
14012
+ // // } else {
14013
+ // // $div.remove();
14014
+ // // }
14015
+ // // UI_WORKER_OBJ.pending_for_viewport_render[container_id].data.push(data);
14016
+
14017
+ // // // if (!$div.children().length) {
14018
+ // // // // render the first element to determine height
14019
+ // // // await iterate_child($div, nodeP, parent_infoP, $root_container);
14020
+ // // // // hover_in($div);
14021
+ // // // // func.UI.worker.add_to_queue(SESSION_ID, 'gui event', 'render_viewport', data, null, null, paramsP.dsSessionP);
14022
+ // // // } else {
14023
+ // // // }
14024
+ // // };
14025
+ // const xu_viewport = function () {
14026
+ // const observer_inViewport = new IntersectionObserver(
14027
+ // function (entries) {
14028
+ // entries.forEach((entry) => {
14029
+ // if (entry.isIntersecting) {
14030
+ // $(entry.target).trigger('inViewport');
14031
+
14032
+ // // Optional: stop observing once triggered
14033
+ // observer_inViewport.unobserve(entry.target);
14034
+ // }
14035
+ // });
14036
+ // },
14037
+ // {
14038
+ // threshold: 0.1, // Trigger when 10% of element is visible
14039
+ // },
14040
+ // );
14041
+
14042
+ // const observer_outViewport = new IntersectionObserver(
14043
+ // function (entries) {
14044
+ // entries.forEach((entry) => {
14045
+ // if (!entry.isIntersecting) {
14046
+ // // Element is OUT of viewport - trigger custom event
14047
+ // $(entry.target).trigger('outViewport');
14048
+
14049
+ // // Optional: stop observing once triggered
14050
+ // // observer_outViewport.unobserve(entry.target);
14051
+ // }
14052
+ // });
14053
+ // },
14054
+ // {
14055
+ // threshold: 0, // Trigger when element is completely out of view
14056
+ // },
14057
+ // );
14058
+
14059
+ // let ui_job_id;
14060
+ // $div.on('inViewport', function () {
14061
+ // if ($div.children().length) {
14062
+ // $div.removeClass('skeleton');
14063
+ // return;
14064
+ // }
14065
+
14066
+ // // if (UI_WORKER_OBJ.cache[$div.attr('xu-ui-id')]) {
14067
+ // // $div[0].style.removeProperty('height');
14068
+ // // $div.removeClass('skeleton');
14069
+ // // $div.html(UI_WORKER_OBJ.cache[$div.attr('xu-ui-id')]);
14070
+ // // } else {
14071
+ // hover_in($div);
14072
+ // ui_job_id = func.UI.worker.add_to_queue(SESSION_ID, 'gui event', 'render_viewport', { $div, nodeP, parent_infoP, $root_container, paramsP, jobNoP, is_skeleton, keyP, refreshed_ds, parent_nodeP, check_existP, temp_$container }, null, null, paramsP.dsSessionP);
14073
+ // // }
14074
+ // observer_outViewport.observe($div[0]);
14075
+ // });
14076
+
14077
+ // $div.on('outViewport', function () {
14078
+ // func.UI.worker.delete_job(SESSION_ID, ui_job_id);
14079
+
14080
+ // if ($div.children().length) {
14081
+ // // UI_WORKER_OBJ.cache[$div.attr('xu-ui-id')] = $div.children().clone(true);
14082
+ // $div.empty();
14083
+ // const height = $div?.data()?.xuData?.viewport_height || 10;
14084
+ // if (typeof height !== 'undefined') {
14085
+ // $div.css('height', height);
14086
+ // }
14087
+ // }
14088
+ // // $div.addClass('skeleton');
14089
+ // observer_inViewport.observe($div[0]);
14090
+ // });
14091
+ // $div.addClass('skeleton');
14092
+ // observer_inViewport.observe($div[0]);
14093
+ // };
14094
+ // xu_viewport();
14095
+ // } else {
14096
+ // // if (ret.xu_render_background_processing) {
14097
+ // // // let temp_$div = $div.clone(true);
14098
+ // // iterate_child($div, nodeP, parent_infoP, $root_container);
14099
+ // // } else {
14100
+ // // await iterate_child($div, nodeP, parent_infoP, $root_container);
14101
+ // // }
14102
+ // if (!ret.xu_render_background_processing) {
14103
+ // iterate_child($div, nodeP, parent_infoP, $root_container);
14104
+ // }
14105
+ // }
14106
+
14107
+ // // const ret_iterate_child = await iterate_child($div, nodeP, parent_infoP, null, $root_container);
14108
+ // return await done(ret);
14109
+ // };
14110
+
14111
+ // if (nodeP.content && nodeP.attributes) {
14112
+ // nodeP.attributes['xu-content'] = nodeP.content;
14113
+ // }
14114
+
14115
+ // if (nodeP.tagName === 'xu-widget') {
14116
+ // if (is_skeleton) return;
14117
+ // return await fx['widget']();
14118
+ // }
14119
+ // if (fx[nodeP.tagName]) {
14120
+ // return await fx[nodeP.tagName]();
14121
+ // }
14122
+ // // const xu_viewport = async function () {
14123
+ // // const data = { $div, nodeP, parent_infoP, $root_container, paramsP, jobNoP, is_skeleton, keyP, refreshed_ds, parent_nodeP, check_existP, $container };
14124
+ // // const container_id = $container.attr('xu-ui-id');
14125
+ // // if (!UI_WORKER_OBJ.pending_for_viewport_render[container_id]) {
14126
+ // // UI_WORKER_OBJ.pending_for_viewport_render[container_id] = { base_$div: $div, data: [], $container };
14127
+ // // await iterate_child($div, nodeP, parent_infoP, $root_container);
14128
+ // // }
14129
+ // // UI_WORKER_OBJ.pending_for_viewport_render[container_id].data.push(data);
14130
+ // // };
14131
+
14132
+ // // if (nodeP?.attributes?.['xu-viewport'] == 'true') {
14133
+ // // return await xu_viewport();
14134
+ // // } else {
14135
+ // if (!glb.new_xu_render) {
14136
+ // return await draw_html_element_org(nodeP.tagName);
14137
+ // }
14138
+ // return await draw_html_element(nodeP.tagName);
14139
+
14140
+ // // }
14141
+ // };
14142
+
14143
+ func.UI.screen.render_ui_tree = async function (SESSION_ID, $container, nodeP, parent_infoP, paramsP, jobNoP, is_skeleton, keyP, refreshed_ds, parent_nodeP, check_existP, $root_container) {
14144
+ // Early cache session and datasource
14145
+ let _session, _ds;
14146
+ if (!is_skeleton) {
14147
+ _session = SESSION_OBJ[SESSION_ID];
14148
+ _ds = _session.DS_GLB[paramsP.dsSessionP];
14149
+ }
14150
+
14151
+ const prop = nodeP.attributes;
14152
+ const is_mobile = glb.MOBILE_ARR.includes(paramsP.screenInfo.properties?.menuType);
14153
+ const nodeTag = nodeP.tagName;
14154
+
14155
+ // Optimized element finder with caching
14156
+ const get_element_info = function () {
14157
+ if (!_ds) return {};
14158
+
14159
+ const currentRecordId = _ds.currentRecordId || '';
14160
+ const $div = func.UI.utils.find_in_element_data('xuData', $container.parent(), 'nodeid', nodeP.id);
14161
+
14162
+ for (let i = 0; i < $div.length; i++) {
14163
+ const $el = $($div[i]);
14164
+ const xuData = $el.data().xuData;
14165
+ if (xuData?.recordid === currentRecordId && xuData?.key === keyP && $el.prop('tagName') !== 'XURENDER') {
14166
+ return { div: $div };
14167
+ }
14168
+ }
14169
+ return {};
14170
+ };
14171
+
14172
+ const init = async function () {
14173
+ return !!nodeP;
14174
+ };
14175
+
14176
+ const debug = function (is_errorP, error_descP) {
14177
+ func.utils.debug.log(SESSION_ID, `${paramsP.prog_id}_${nodeP.id_org}_ui_prop`, {
14178
+ module: 'gui',
14179
+ action: 'init',
14180
+ prop: nodeP.id,
14181
+ details: error_descP,
14182
+ result: null,
14183
+ error: is_errorP,
14184
+ source: _ds?.tree_obj?.menuName || '',
14185
+ fields: null,
14186
+ type: null,
14187
+ prog_id: paramsP.prog_id,
14188
+ dsSession: null,
14189
+ });
14190
+ };
14191
+
14192
+ const close_modal = async function (modal_id) {
14193
+ delete APP_MODAL_OBJ[modal_id];
14194
+ const xu_modal_controller = document.querySelector('xu-modal-controller');
14195
+ const params = $(xu_modal_controller).data().xuControllerParams?.[modal_id];
14196
+ if (params?.container) {
14197
+ await func.UI.screen.validate_exit_events(SESSION_ID, params.$container.data().xuData.paramsP, null);
14198
+ func.datasource.clean_all(SESSION_ID, params.dsSession);
14199
+ }
14200
+ };
14201
+
14202
+ const close_all_modals = function () {
14203
+ Object.entries(APP_MODAL_OBJ).forEach(([key, val]) => {
14204
+ if (val) {
14205
+ UI_FRAMEWORK_PLUGIN.modal.close(key);
14206
+ }
14207
+ });
14208
+ };
14209
+
14210
+ const open_modal = async function ($div) {
14211
+ const modal_id = `app_modal-${paramsP.dsSessionP}`;
14212
+ let xu_modal_controller = document.querySelector('xu-modal-controller');
14213
+
14214
+ if (!xu_modal_controller) {
14215
+ func.UI.component.create_app_modal_component(SESSION_ID, modal_id);
14216
+ xu_modal_controller = document.querySelector('xu-modal-controller');
14217
+ }
14218
+
14219
+ let controller_params = $(xu_modal_controller).data('xuControllerParams') || {};
14220
+
14221
+ controller_params[modal_id] = {
14222
+ menuTitle: paramsP.screenInfo.properties?.menuTitle,
14223
+ screenId: paramsP.screenId,
14224
+ $dialogDiv: $div.children(),
14225
+ $container: $container,
14226
+ dsSession: paramsP.dsSessionP,
14227
+ };
14228
+
14229
+ $(xu_modal_controller).data('xuControllerParams', controller_params);
14230
+ const modalController = new UI_FRAMEWORK_PLUGIN.modal();
14231
+
14232
+ if (!APP_MODAL_OBJ[modal_id]) {
14233
+ APP_MODAL_OBJ[modal_id] = await modalController.create(SESSION_ID, modal_id, paramsP.screenInfo, close_modal);
14234
+ } else {
14235
+ $(modal_id).empty();
14236
+ }
14237
+
14238
+ await modalController.init(SESSION_ID, modal_id);
14239
+ return $div;
14240
+ };
14241
+
14242
+ const open_popover = async function ($div) {
14243
+ const xu_popover_controller = func.UI.component.create_app_popover_component(SESSION_ID);
14244
+
14245
+ $(xu_popover_controller).data('xuControllerParams', {
14246
+ menuTitle: paramsP.screenInfo.properties?.menuTitle,
14247
+ screenId: paramsP.screenId,
14248
+ $dialogDiv: $div.children(),
14249
+ $container: $container,
14250
+ });
14251
+
14252
+ const popover = new UI_FRAMEWORK_PLUGIN.popover(SESSION_ID);
14253
+ await popover.open(SESSION_ID);
14254
+ CURRENT_APP_POPOVER = popover;
14255
+ };
14256
+
14257
+ // OPTIMIZED: Parallel child iteration with improved logic
14258
+ const iterate_child = async function ($divP, nodeP, parent_infoP, $root_container, before_record_function) {
14259
+ if (!is_mobile && nodeP.busy) return $divP;
14260
+
14261
+ nodeP.busy = true;
14262
+
14263
+ const done = function ($divP) {
14264
+ setTimeout(() => {
14265
+ nodeP.busy = false;
14266
+ }, 1000);
14267
+ return $divP;
14268
+ };
14269
+
14270
+ if (!nodeP?.children?.length) {
14271
+ return done($divP);
14272
+ }
14273
+
14274
+ if (before_record_function) {
14275
+ await before_record_function();
14276
+ }
14277
+
14278
+ // Parallel rendering for better performance
14279
+ await Promise.all(nodeP.children.map((child, key) => func.UI.screen.render_ui_tree(SESSION_ID, $divP, child, parent_infoP, paramsP, jobNoP, is_skeleton, key, null, nodeP, null, $root_container)));
14280
+
14281
+ return done($divP);
14282
+ };
14283
+
14284
+ const _$ = function ($elm) {
14285
+ try {
14286
+ const id = $elm.attr('xu-ui-id');
14287
+ if (!id || !glb.DEBUG_MODE) return $elm;
14288
+
14289
+ const $el = $(`[xu-ui-id="${id}"]`);
14290
+ if ($el.length > 1) {
14291
+ console.warn(`Multiple elements for xu-ui-id: ${id}`, $el);
14292
+ }
14293
+ return $($el[0]);
14294
+ } catch (e) {
14295
+ console.error(e);
14296
+ return $elm;
14297
+ }
14298
+ };
14299
+
14300
+ const hover_in = function ($div, e) {
14301
+ if (is_skeleton || (e && (EXP_BUSY || UI_WORKER_OBJ.jobs.length))) return;
14302
+
14303
+ CLIENT_ACTIVITY_TS = Date.now();
14304
+
14305
+ const containerXuData = _$($container)?.data()?.xuData;
14306
+ if (containerXuData?.debug_info) {
14307
+ containerXuData.debug_info.hover_item = $div.attr('xu-ui-id');
14308
+ }
14309
+
14310
+ if (!_ds) return;
14311
+
14312
+ // Set attributes
14313
+ const attributes = {};
14314
+ Array.from($div[0].attributes).forEach((attr) => {
14315
+ attributes[attr.name] = attr.value;
14316
+ });
14317
+ _session.DS_GLB[0].data_system.SYS_OBJ_WIN_ELEMENT_HOVERED_ATTRIBUTES = attributes;
14318
+
14319
+ const divXuData = $div.data()?.xuData;
14320
+ if (!divXuData) return;
14321
+
14322
+ const _iterate_info = divXuData.iterate_info;
14323
+ if (_iterate_info) {
14324
+ const set_field_value = (field_id, value, is_dynamic) => {
14325
+ if (is_dynamic) {
14326
+ _ds.dynamic_fields[field_id].value = value;
14327
+ } else {
14328
+ try {
14329
+ const row_idx = func.common.find_ROWID_idx(_ds, _ds.currentRecordId);
14330
+ _ds.data_feed.rows[row_idx][field_id] = value;
14331
+ } catch (err) {
14332
+ console.error(err);
14333
+ }
14334
+ }
14335
+ };
14336
+
14337
+ set_field_value(_iterate_info.iterator_key, _iterate_info._key, _iterate_info.is_key_dynamic_field);
14338
+ set_field_value(_iterate_info.iterator_val, _iterate_info._val, _iterate_info.is_val_dynamic_field);
14339
+ }
14340
+
14341
+ if ($div && _$($div) && _ds && paramsP.renderType === 'grid') {
14342
+ func.UI.worker.add_to_queue(SESSION_ID, 'gui event', 'update_datasource', { currentRecordId: _$($div).data().xuData.currentRecordId }, null, null, paramsP.dsSessionP);
14343
+ }
14344
+
14345
+ const iterate_data = $div?.data()?.xuData?.iterate_info;
14346
+ if (iterate_data) {
14347
+ const set_value = (field_id, value) => {
14348
+ func.UI.worker.add_to_queue(SESSION_ID, 'gui event', 'update_datasource', { currentRecordId: _$($div).data().xuData.currentRecordId, field_id, field_value: value }, null, null, paramsP.dsSessionP);
14349
+ };
14350
+
14351
+ if (iterate_data.iterator_key) set_value(iterate_data.iterator_key, iterate_data._key);
14352
+ if (iterate_data.iterator_val) set_value(iterate_data.iterator_val, iterate_data._val);
14353
+ }
14354
+ };
14355
+
14356
+ const hover_out = function () {
14357
+ if (is_skeleton) return;
14358
+
14359
+ CLIENT_ACTIVITY_TS = Date.now();
14360
+
14361
+ const containerXuData = _$($container)?.data()?.xuData;
14362
+ if (containerXuData?.debug_info) {
14363
+ containerXuData.debug_info.hover_item = null;
14364
+ }
14365
+
14366
+ if (_ds?.data_system) {
14367
+ SESSION_OBJ[SESSION_ID].DS_GLB[0].data_system.SYS_OBJ_WIN_ELEMENT_HOVERED_ATTRIBUTES = {};
14368
+ }
14369
+ };
14370
+
14371
+ const render_screen_type = async function ($div) {
14372
+ const set_call_screen_properties_values = async function (ui_framework) {
14373
+ params.properties = {};
14374
+
14375
+ const get_values = async function (property) {
14376
+ let property_value = paramsP?.screenInfo?.properties?.[property] || paramsP?.screenInfo?.properties?.frameworkProperties?.[property];
14377
+
14378
+ if (paramsP?.call_screen_propertiesP) {
14379
+ if (paramsP.call_screen_propertiesP[property]) {
14380
+ property_value = paramsP.call_screen_propertiesP[property];
14381
+ }
14382
+ const expKey = `xu-exp:${property}`;
14383
+ if (paramsP.call_screen_propertiesP[expKey]) {
14384
+ property_value = (await func.expression.get(SESSION_ID, paramsP.call_screen_propertiesP[expKey], paramsP.dsSessionP, property)).result;
13275
14385
  }
13276
14386
  }
13277
14387
  return property_value;
13278
14388
  };
14389
+
13279
14390
  params.properties['name'] = await get_values('menuTitle');
13280
- if (await ui_framework?.properties()) {
13281
- for await (const [key, val] of Object.entries(await ui_framework.properties())) {
14391
+ const uiProps = await ui_framework?.properties?.();
14392
+ if (uiProps) {
14393
+ for (const [key, val] of Object.entries(uiProps)) {
13282
14394
  params.properties[key] = await get_values(key);
13283
14395
  }
13284
14396
  }
13285
14397
  };
13286
14398
 
13287
- var $div_content = $div.children();
14399
+ const $div_content = $div.children();
13288
14400
 
13289
- $.each($div_content, function (key, val) {
13290
- if (!$(val)?.data()?.xuData?.parent_container) {
13291
- return true;
14401
+ // Update parent container for children
14402
+ $div_content.each((key, val) => {
14403
+ const xuData = $(val)?.data()?.xuData;
14404
+ if (xuData && !xuData.parent_container) {
14405
+ xuData.parent_container = $div.data().xuData.parent_container;
13292
14406
  }
13293
- $(val).data().xuData.parent_container = $div.data().xuData.parent_container;
13294
14407
  });
13295
14408
 
13296
14409
  let $ret = $div;
13297
- var $nav = $(SESSION_OBJ[SESSION_ID].root_element).find('xu-nav');
13298
- var params;
14410
+ const $nav = $(SESSION_OBJ[SESSION_ID].root_element).find('xu-nav');
14411
+ let params;
14412
+
13299
14413
  switch (paramsP.screen_type) {
13300
14414
  case 'modal':
13301
- const modal_id = 'app_modal-' + paramsP.dsSessionP.toString();
13302
- var xu_modal_controller = document.querySelector('xu-modal-controller');
14415
+ const modal_id = `app_modal-${paramsP.dsSessionP}`;
14416
+ let xu_modal_controller = document.querySelector('xu-modal-controller');
14417
+
13303
14418
  if (!xu_modal_controller) {
13304
14419
  func.UI.component.create_app_modal_component(SESSION_ID, modal_id);
13305
14420
  xu_modal_controller = document.querySelector('xu-modal-controller');
13306
14421
  }
13307
14422
 
13308
- var controller_params = $(xu_modal_controller).data('xuControllerParams');
13309
-
13310
- if (!controller_params) {
13311
- controller_params = {};
13312
- }
14423
+ let controller_params = $(xu_modal_controller).data('xuControllerParams') || {};
13313
14424
 
13314
14425
  params = {
13315
14426
  screenId: paramsP.screenId,
@@ -13323,25 +14434,20 @@ func.UI.screen.render_ui_tree = async function (SESSION_ID, $container, nodeP, p
13323
14434
  };
13324
14435
 
13325
14436
  controller_params[modal_id] = params;
13326
-
13327
14437
  $(xu_modal_controller).data('xuControllerParams', controller_params);
13328
- const modalController = await new UI_FRAMEWORK_PLUGIN.modal();
14438
+
14439
+ const modalController = new UI_FRAMEWORK_PLUGIN.modal();
13329
14440
  await set_call_screen_properties_values(modalController);
13330
- if (!APP_MODAL_OBJ[modal_id]) {
13331
- const modal = await modalController.create(params);
13332
14441
 
13333
- APP_MODAL_OBJ[modal_id] = modal;
14442
+ if (!APP_MODAL_OBJ[modal_id]) {
14443
+ APP_MODAL_OBJ[modal_id] = await modalController.create(params);
13334
14444
  } else {
13335
14445
  $(modal_id).empty();
13336
14446
  }
13337
-
13338
14447
  await modalController.init(params);
13339
-
13340
14448
  break;
13341
14449
 
13342
14450
  case 'popover':
13343
- // open_popover($div);
13344
-
13345
14451
  const xu_popover_controller = func.UI.component.create_app_popover_component(SESSION_ID);
13346
14452
  params = {
13347
14453
  menuTitle: paramsP.screenInfo.properties?.menuTitle,
@@ -13355,13 +14461,11 @@ func.UI.screen.render_ui_tree = async function (SESSION_ID, $container, nodeP, p
13355
14461
  await set_call_screen_properties_values(popover);
13356
14462
  await popover.open(params);
13357
14463
  CURRENT_APP_POPOVER = popover;
13358
-
13359
- func.UI.utils.screen_blocker(false, paramsP.prog_id + '_' + paramsP.sourceScreenP);
14464
+ func.UI.utils.screen_blocker(false, `${paramsP.prog_id}_${paramsP.sourceScreenP}`);
13360
14465
  break;
13361
14466
 
13362
14467
  case 'page':
13363
14468
  const nav = $nav[0];
13364
-
13365
14469
  params = {
13366
14470
  div: $div_content,
13367
14471
  name: paramsP.screenInfo.properties?.menuTitle,
@@ -13373,18 +14477,21 @@ func.UI.screen.render_ui_tree = async function (SESSION_ID, $container, nodeP, p
13373
14477
  paramsP,
13374
14478
  };
13375
14479
 
13376
- var component_name = 'xu-page-component-' + paramsP.dsSessionP;
13377
- if (!$(nav).data().xuData.nav_params) {
13378
- $(nav).data().xuData.nav_params = {};
14480
+ const component_name = `xu-page-component-${paramsP.dsSessionP}`;
14481
+ const navXuData = $(nav).data().xuData;
14482
+
14483
+ if (!navXuData.nav_params) {
14484
+ navXuData.nav_params = {};
13379
14485
  }
13380
14486
 
13381
- //restore validate
13382
- if ($(nav)?.data()?.xuData?.params?.[paramsP.dsSessionP]) {
13383
- params.$container.data().xuData.validate_screen_ready = $(nav).data().xuData.params[paramsP.dsSessionP].$container.data().xuData.validate_screen_ready;
14487
+ // Restore validate
14488
+ if (navXuData.params?.[paramsP.dsSessionP]) {
14489
+ params.$container.data().xuData.validate_screen_ready = navXuData.params[paramsP.dsSessionP].$container.data().xuData.validate_screen_ready;
13384
14490
  }
13385
14491
 
13386
- if (!$(nav)?.data()?.xuData) return;
13387
- $(nav).data().xuData.nav_params[paramsP.dsSessionP] = params;
14492
+ if (!navXuData) return;
14493
+ navXuData.nav_params[paramsP.dsSessionP] = params;
14494
+
13388
14495
  if (!$(component_name).length) {
13389
14496
  await func.UI.component.create_app_page_component(SESSION_ID, paramsP.dsSessionP);
13390
14497
  const page = new UI_FRAMEWORK_PLUGIN.page();
@@ -13393,9 +14500,7 @@ func.UI.screen.render_ui_tree = async function (SESSION_ID, $container, nodeP, p
13393
14500
  await page.init(params);
13394
14501
  nav.push(component_name, { params });
13395
14502
  } else {
13396
- debugger;
13397
14503
  $(component_name).empty();
13398
-
13399
14504
  await UI_FRAMEWORK_PLUGIN.page(SESSION_ID, paramsP.dsSessionP);
13400
14505
  }
13401
14506
  $div.data().xuData.paramsP = $container.data().xuData.paramsP;
@@ -13406,18 +14511,15 @@ func.UI.screen.render_ui_tree = async function (SESSION_ID, $container, nodeP, p
13406
14511
  $ret = $container;
13407
14512
  break;
13408
14513
 
13409
- default: // set data to nav to use in the component
13410
- if ($nav && $nav.length) {
13411
- // refresh made
13412
- } else {
13413
- $nav = $('<xu-nav>'); //.attr('xu-ui-id', SESSION_ID);
14514
+ default:
14515
+ if (!$nav?.length) {
14516
+ $nav = $('<xu-nav>');
13414
14517
  $container.append($nav);
13415
14518
  func.UI.component.init_xu_nav($container, $nav);
13416
14519
  }
13417
14520
 
13418
14521
  $nav.data().xuData.$div = $div_content;
13419
-
13420
- await $nav[0].setRoot('xu-root-component-' + SESSION_ID);
14522
+ await $nav[0].setRoot(`xu-root-component-${SESSION_ID}`);
13421
14523
  $ret = $container;
13422
14524
  break;
13423
14525
  }
@@ -13426,130 +14528,92 @@ func.UI.screen.render_ui_tree = async function (SESSION_ID, $container, nodeP, p
13426
14528
 
13427
14529
  if (!(await init())) return;
13428
14530
  debug();
14531
+
13429
14532
  const fx = {
13430
14533
  widget: async function () {
13431
- var _session = SESSION_OBJ[SESSION_ID];
14534
+ const exist_elm_obj = get_element_info();
14535
+ let $div = exist_elm_obj.div;
13432
14536
 
13433
- var exist_elm_obj = get_element_info();
13434
- var $div = exist_elm_obj.div;
13435
14537
  if (!exist_elm_obj.div) {
13436
14538
  $div = await func.UI.screen.create_container(SESSION_ID, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, prop, 'widget_wrapper', null, null, null, null);
13437
14539
 
13438
- //////////////////////////
13439
-
13440
- let plugin_name = prop['xu-widget'],
13441
- method = prop['xu-method'],
13442
- dsP = paramsP.dsSessionP,
13443
- propsP = prop,
13444
- sourceP = 'widgets';
13445
-
13446
- // const set_SYS_GLOBAL_OBJ_WIDGET_INFO = async function (docP) {
13447
- // var obj = _.clone(docP);
13448
- // obj.date = await func.utils.get_dateTime(
13449
- // SESSION_ID,
13450
- // "SYS_DATE",
13451
- // docP.date
13452
- // );
13453
- // obj.time = await func.utils.get_dateTime(
13454
- // SESSION_ID,
13455
- // "SYS_TIME",
13456
- // docP.date
13457
- // );
13458
-
13459
- // var datasource_changes = {
13460
- // [0]: {
13461
- // ["data_system"]: {
13462
- // ["SYS_GLOBAL_OBJ_WIDGET_INFO"]: obj,
13463
- // },
13464
- // },
13465
- // };
13466
- // await func.datasource.update(SESSION_ID, datasource_changes);
13467
- // };
13468
- const call_plugin_api = async function (plugin_nameP, dataP) {
14540
+ const plugin_name = prop['xu-widget'];
14541
+ const method = prop['xu-method'];
14542
+ const dsP = paramsP.dsSessionP;
14543
+ const propsP = prop;
14544
+ const sourceP = 'widgets';
14545
+
14546
+ const call_plugin_api = async (plugin_nameP, dataP) => {
13469
14547
  return await func.utils.call_plugin_api(SESSION_ID, plugin_nameP, dataP);
13470
14548
  };
13471
- const report_error = function (descP, warn) {
13472
- func.utils.debug.log(SESSION_ID, _session.DS_GLB[dsP].prog_id + '_' + _session.DS_GLB[dsP].callingMenuId, {
14549
+
14550
+ const report_error = (descP, warn) => {
14551
+ func.utils.debug.log(SESSION_ID, `${_session.DS_GLB[dsP].prog_id}_${_session.DS_GLB[dsP].callingMenuId}`, {
13473
14552
  module: 'widgets',
13474
14553
  action: 'Init',
13475
14554
  source: sourceP,
13476
14555
  prop: descP,
13477
14556
  details: descP,
13478
14557
  result: null,
13479
- error: warn ? false : true,
14558
+ error: !warn,
13480
14559
  fields: null,
13481
14560
  type: 'widgets',
13482
14561
  prog_id: _session.DS_GLB[dsP].prog_id,
13483
14562
  });
13484
14563
  };
13485
- const get_fields_data = async function (fields, props) {
13486
- const report_error = function (descP, warn) {
13487
- func.utils.debug.log(SESSION_ID, _session.DS_GLB[dsP].prog_id + '_' + _session.DS_GLB[dsP].callingMenuId, {
13488
- module: 'widgets',
13489
- action: 'Init',
13490
- source: sourceP,
13491
- prop: descP,
13492
- details: descP,
13493
- result: null,
13494
- error: warn ? false : true,
13495
- fields: null,
13496
- type: 'widgets',
13497
- prog_id: _session.DS_GLB[dsP].prog_id,
13498
- });
13499
- };
13500
- const get_property_value = async function (fieldIdP, val) {
14564
+
14565
+ const get_fields_data = async (fields, props) => {
14566
+ const get_property_value = async (fieldIdP, val) => {
13501
14567
  if (!val) return;
13502
- var value = fieldIdP in props ? props[fieldIdP] : typeof val.defaultValue === 'function' ? val?.defaultValue?.() : val?.defaultValue;
14568
+
14569
+ let value = fieldIdP in props ? props[fieldIdP] : typeof val.defaultValue === 'function' ? val.defaultValue() : val.defaultValue;
14570
+
13503
14571
  if (val.render === 'eventId') {
13504
14572
  value = props?.[fieldIdP]?.event;
13505
14573
  }
13506
14574
 
13507
- if (props[`xu-exp:${fieldIdP}`]) {
13508
- value = (await func.expression.get(SESSION_ID, props[`xu-exp:${fieldIdP}`], dsP, 'widget property')).result;
14575
+ const expKey = `xu-exp:${fieldIdP}`;
14576
+ if (props[expKey]) {
14577
+ value = (await func.expression.get(SESSION_ID, props[expKey], dsP, 'widget property')).result;
13509
14578
  }
13510
14579
 
13511
- return func.common.get_cast_val(
13512
- SESSION_ID,
13513
- 'widgets',
13514
- fieldIdP,
13515
- val.type, //val.type !== "string" || val.type !== "number" ? "string" : val.type,
13516
- value,
13517
- null,
13518
- );
14580
+ return func.common.get_cast_val(SESSION_ID, 'widgets', fieldIdP, val.type, value, null);
13519
14581
  };
13520
- var data_obj = {};
13521
- var return_code = 1;
13522
- // $.each(fields, function (key, val) {
13523
- for await (const [key, val] of Object.entries(fields)) {
14582
+
14583
+ const data_obj = {};
14584
+ let return_code = 1;
14585
+
14586
+ for (const [key, val] of Object.entries(fields)) {
13524
14587
  data_obj[key] = await get_property_value(key, val);
13525
14588
  if (!data_obj[key] && val.mandatory) {
13526
14589
  return_code = -1;
13527
14590
  report_error(`${key} is a mandatory field.`);
13528
14591
  break;
13529
14592
  }
13530
- // console.log(val);
13531
- }
13532
- for await (const key of ['xu-bind']) {
13533
- data_obj[key] = await get_property_value(key, props[key]);
13534
14593
  }
13535
14594
 
14595
+ data_obj['xu-bind'] = await get_property_value('xu-bind', props['xu-bind']);
14596
+
13536
14597
  return { code: return_code, data: data_obj };
13537
14598
  };
13538
14599
 
13539
- const load_css_style = function () {
13540
- const get_css_path = function (resource) {
14600
+ const load_css_style = () => {
14601
+ const get_css_path = (resource) => {
13541
14602
  if (_session.worker_type === 'Dev') {
13542
14603
  return `../../plugins/${plugin_name}/${resource}`;
13543
14604
  }
13544
- return `https://${_session.domain}/plugins/${plugin_name}/${APP_OBJ[_session.app_id].app_plugins_purchased[plugin_name].manifest[resource].dist ? 'dist/' : ''}${resource}?gtp_token=${_session.gtp_token}&app_id=${_session.app_id}`;
14605
+ const manifest = APP_OBJ[_session.app_id].app_plugins_purchased[plugin_name].manifest[resource];
14606
+ const dist = manifest.dist ? 'dist/' : '';
14607
+ return `https://${_session.domain}/plugins/${plugin_name}/${dist}${resource}?gtp_token=${_session.gtp_token}&app_id=${_session.app_id}`;
13545
14608
  };
13546
- let path = get_css_path('style.css');
13547
- func.utils.load_css_on_demand(path);
14609
+ func.utils.load_css_on_demand(get_css_path('style.css'));
13548
14610
  };
13549
14611
 
13550
14612
  const _plugin = APP_OBJ[_session.app_id]?.app_plugins_purchased?.[plugin_name];
13551
- const index = await func.utils.get_plugin_resource(SESSION_ID, plugin_name, `${_plugin.manifest['index.mjs'].dist ? 'dist/' : ''}index.mjs`);
14613
+ const indexDist = _plugin.manifest['index.mjs'].dist ? 'dist/' : '';
14614
+ const index = await func.utils.get_plugin_resource(SESSION_ID, plugin_name, `${indexDist}index.mjs`);
13552
14615
  const methods = index.methods;
14616
+
13553
14617
  if (methods && !methods[method]) {
13554
14618
  return report_error('method not found');
13555
14619
  }
@@ -13558,18 +14622,13 @@ func.UI.screen.render_ui_tree = async function (SESSION_ID, $container, nodeP, p
13558
14622
  if (fields_ret.code < 0) {
13559
14623
  return report_error(fields_ret.data);
13560
14624
  }
13561
- const fields = fields_ret.data;
13562
14625
 
13563
- let exclude_attributes = [];
13564
- for await (const [key, val] of Object.entries(propsP)) {
13565
- if (typeof fields[key] !== 'undefined' || typeof fields[`xu-exp:${key}`] !== 'undefined') {
13566
- exclude_attributes.push(key);
13567
- }
13568
- }
14626
+ const fields = fields_ret.data;
14627
+ const exclude_attributes = Object.keys(propsP).filter((key) => fields[key] !== undefined || fields[`xu-exp:${key}`] !== undefined);
13569
14628
 
13570
- let ret = await func.UI.screen.set_attributes_new(SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, $div, true, exclude_attributes);
14629
+ const ret = await func.UI.screen.set_attributes_new(SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, $div, true, exclude_attributes);
13571
14630
 
13572
- $div.addClass('widget_wrapper'); // class get override in set_attributes_new
14631
+ $div.addClass('widget_wrapper');
13573
14632
 
13574
14633
  if (!APP_OBJ[_session.app_id].app_plugins_purchased[plugin_name]) {
13575
14634
  return report_error(`plugin ${plugin_name} not found`);
@@ -13604,23 +14663,23 @@ func.UI.screen.render_ui_tree = async function (SESSION_ID, $container, nodeP, p
13604
14663
  plugin_name,
13605
14664
  $containerP: $div,
13606
14665
  plugin_setup: plugin_setup_ret.data,
13607
-
13608
14666
  report_error,
13609
14667
  call_plugin_api,
13610
- // set_SYS_GLOBAL_OBJ_WIDGET_INFO,
13611
14668
  api_utils,
13612
14669
  };
13613
14670
 
13614
- const fx = await func.utils.get_plugin_resource(SESSION_ID, plugin_name, `${_plugin.manifest['runtime.mjs'].dist ? 'dist/' : ''}runtime.mjs`);
14671
+ const runtimeDist = _plugin.manifest['runtime.mjs'].dist ? 'dist/' : '';
14672
+ const fx = await func.utils.get_plugin_resource(SESSION_ID, plugin_name, `${runtimeDist}runtime.mjs`);
13615
14673
 
13616
14674
  if (_plugin?.manifest?.['runtime.mjs'].dist && _plugin?.manifest?.['runtime.mjs']?.css) {
13617
- const plugin_runtime_css_url = await func.utils.get_plugin_npm_cdn(SESSION_ID, plugin_name, 'dist/runtime.css');
13618
- func.utils.load_css_on_demand(plugin_runtime_css_url);
14675
+ const css_url = await func.utils.get_plugin_npm_cdn(SESSION_ID, plugin_name, 'dist/runtime.css');
14676
+ func.utils.load_css_on_demand(css_url);
13619
14677
  }
13620
14678
 
13621
14679
  if (!fx[method]) {
13622
14680
  throw `Method: ${method} does not exist`;
13623
14681
  }
14682
+
13624
14683
  try {
13625
14684
  await fx[method](fields, params);
13626
14685
  } catch (err) {
@@ -13629,12 +14688,13 @@ func.UI.screen.render_ui_tree = async function (SESSION_ID, $container, nodeP, p
13629
14688
  }
13630
14689
  return $div;
13631
14690
  },
13632
- [`xu-single-view`]: async function () {
13633
- var exist_elm_obj = get_element_info();
13634
- var $div = exist_elm_obj.div;
14691
+
14692
+ 'xu-single-view': async function () {
14693
+ const exist_elm_obj = get_element_info();
14694
+ let $div = exist_elm_obj.div;
13635
14695
 
13636
14696
  if (!exist_elm_obj.div) {
13637
- var $wrapper = $('<div>');
14697
+ const $wrapper = $('<div>');
13638
14698
  $div = await func.UI.screen.create_container(SESSION_ID, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, prop, null, null, 'div', $wrapper, '');
13639
14699
 
13640
14700
  if (!$div) return;
@@ -13644,67 +14704,41 @@ func.UI.screen.render_ui_tree = async function (SESSION_ID, $container, nodeP, p
13644
14704
  }
13645
14705
 
13646
14706
  $div.hover(
13647
- function (e) {
13648
- hover_in();
13649
- // func.UI.screen.hover_in(SESSION_ID, null, $container, paramsP, is_skeleton);
13650
- },
13651
- function (e) {
13652
- // func.UI.screen.hover_out(SESSION_ID, $container, is_skeleton, paramsP);
13653
- hover_out();
13654
- },
14707
+ (e) => hover_in(),
14708
+ (e) => hover_out(),
13655
14709
  );
13656
14710
  }
13657
14711
 
13658
- const ret = await iterate_child($div, nodeP, null, $div);
14712
+ await iterate_child($div, nodeP, null, $div);
14713
+
13659
14714
  if (_.isEmpty($container.data().xuAttributes)) {
13660
14715
  await func.UI.screen.set_attributes_new(SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, $container, true);
13661
14716
  }
13662
14717
 
13663
- $.each($div.data().xuData, function (key, val) {
13664
- $container.data().xuData[key] = _.cloneDeep(val);
13665
- });
13666
- $.each($div.data().xuAttributes, function (key, val) {
13667
- // $container.data().xuAttributes[key] = _.cloneDeep(val);
13668
- $container.data().xuAttributes[key] = klona.klona(val);
13669
- });
14718
+ // Copy xuData and xuAttributes
14719
+ Object.assign($container.data().xuData, _.cloneDeep($div.data().xuData));
14720
+ Object.assign($container.data().xuAttributes, klona.klona($div.data().xuAttributes));
13670
14721
 
13671
14722
  return await render_screen_type($div);
13672
14723
  },
13673
- [`xu-multi-view`]: async function () {
13674
- var $div = $container;
13675
14724
 
13676
- if (!$div.data().xuData.node || !$div.data().xuData.node.children) {
13677
- $div.data().xuData.node = nodeP;
14725
+ 'xu-multi-view': async function () {
14726
+ let $div = $container;
14727
+
14728
+ const divXuData = $div.data().xuData;
14729
+ if (!divXuData.node || !divXuData.node.children) {
14730
+ divXuData.node = nodeP;
13678
14731
  }
13679
14732
 
13680
- if (!$div.data().xuData.debug_info) {
13681
- $div.data().xuData.debug_info = {
14733
+ if (!divXuData.debug_info) {
14734
+ divXuData.debug_info = {
13682
14735
  id: nodeP.id,
13683
14736
  parent_id: $container.data().xuData.ui_id,
13684
14737
  };
13685
14738
  }
13686
14739
 
13687
14740
  const done = async function (continuous_idx) {
13688
- // const do_callback = async function ($div) {
13689
- // // if ($root_container.data().xuData.progress_bar_circle) {
13690
- // // setTimeout(function () {
13691
- // // $.each(
13692
- // // $root_container.data().xuData.progress_bar_circle,
13693
- // // function (key, val) {
13694
- // // val.bar.set(parseFloat(val.value)); // Number from 0.0 to 1.0
13695
- // // }
13696
- // // );
13697
- // // }, 2000);
13698
- // // }
13699
-
13700
- // if (paramsP.screenInfo.properties?.rtl) {
13701
- // $div_content.attr('dir', 'rtl');
13702
- // }
13703
-
13704
- // return $div;
13705
- // };
13706
14741
  await func.UI.screen.set_attributes_new(SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, $container, true);
13707
-
13708
14742
  return await render_screen_type($div);
13709
14743
  };
13710
14744
 
@@ -13713,351 +14747,150 @@ func.UI.screen.render_ui_tree = async function (SESSION_ID, $container, nodeP, p
13713
14747
  }
13714
14748
 
13715
14749
  const empty_result = async function () {
13716
- // var content = prop.empty_result_content || '';
13717
-
13718
- // var res = await func.expression.get(
13719
- // SESSION_ID,
13720
- // content, // prop["xu-exp:empty_result_content"],
13721
- // paramsP.dsSessionP,
13722
- // 'empty_result_content_EXP',
13723
- // _ds.currentRecordId,
13724
- // );
13725
- // content = res.result;
13726
-
13727
- // let empty_result_node = {
13728
- // type: 'element',
13729
- // id: crypto.randomUUID(),
13730
- // content,
13731
- // // : content || (typeof content === "undefined" && "Empty results"),
13732
- // tagName: 'div',
13733
- // attributes: {},
13734
- // children: [],
13735
- // };
13736
-
13737
- // const ret = await func.UI.screen.render_ui_tree(SESSION_ID, $container, empty_result_node, parent_infoP, paramsP, jobNoP, null, 0, null, nodeP, null, $root_container);
13738
14750
  await func.events.validate(SESSION_ID, 'record_not_found', paramsP.dsSessionP);
13739
14751
  return await done(null);
13740
14752
  };
13741
- var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP];
13742
-
13743
- var continuous_idx = null;
13744
14753
 
13745
14754
  if (!_ds.data_feed || _.isEmpty(_ds.data_feed.rows)) {
13746
14755
  return await empty_result();
13747
14756
  }
13748
14757
 
13749
- var i = 0;
13750
- for await (const [key, val] of Object.entries(_ds.data_feed.rows)) {
13751
- var node = JSON.parse(JSON.stringify(nodeP));
13752
-
14758
+ for (const [key, val] of Object.entries(_ds.data_feed.rows)) {
14759
+ const node = JSON.parse(JSON.stringify(nodeP));
13753
14760
  _ds.currentRecordId = val._ROWID;
13754
- const ret = await iterate_child($div, node, { continuous_idx }, $root_container);
14761
+ await iterate_child($div, node, { continuous_idx: null }, $root_container);
13755
14762
 
13756
14763
  if (_.isEmpty($container.data().xuAttributes)) {
13757
14764
  await func.UI.screen.set_attributes_new(SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, $container, true);
13758
14765
  }
13759
14766
  }
13760
14767
 
13761
- return await done(continuous_idx);
14768
+ return await done(null);
13762
14769
  },
13763
- [`xu-panel`]: async function () {
14770
+
14771
+ 'xu-panel': async function () {
13764
14772
  const done = async function ($new_div) {
13765
14773
  if (!$container.data()?.xuData?.paramsP) {
13766
14774
  return $container;
13767
14775
  }
13768
- var $div_items = $div.data().xuData.node.children;
13769
14776
 
14777
+ const $div_items = $div.data().xuData.node.children;
13770
14778
  await func.UI.screen.panel_post_render_handler(SESSION_ID, $container, $new_div, nodeP, $div, jobNoP);
13771
-
13772
- // TO FIX should be timeout
13773
14779
  $container.data().xuData.node.children = $div_items;
13774
-
13775
14780
  return $container;
13776
14781
  };
13777
14782
 
13778
- var $wrapper = $('<div>');
13779
- $div = await func.UI.screen.create_container(SESSION_ID, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, prop, null, null, null, $wrapper, '');
14783
+ const $wrapper = $('<div>');
14784
+ const $div = await func.UI.screen.create_container(SESSION_ID, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, prop, null, null, null, $wrapper, '');
14785
+
14786
+ const ret = await func.UI.screen.set_attributes_new(SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, $div.clone(true), true, undefined, refreshed_ds);
13780
14787
 
13781
- let ret = await func.UI.screen.set_attributes_new(SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, $div.clone(true), true, undefined, refreshed_ds);
13782
14788
  if (ret.abort) {
13783
- // render N
13784
14789
  return (ret.$new_div = $('<template>').append($div));
13785
14790
  }
13786
14791
 
13787
14792
  let $ret_panel_div = ret.$new_div;
13788
14793
 
13789
- if (!$ret_panel_div?.children()?.length) {
13790
- ////// render default children tree
13791
- if (nodeP.children.length) {
13792
- $ret_panel_div = await func.UI.screen.render_ui_tree(SESSION_ID, $container, nodeP.children[0], parent_infoP, paramsP, jobNoP, null, 0, null, nodeP, null, $root_container);
13793
- }
14794
+ if (!$ret_panel_div?.children()?.length && nodeP.children.length) {
14795
+ $ret_panel_div = await func.UI.screen.render_ui_tree(SESSION_ID, $container, nodeP.children[0], parent_infoP, paramsP, jobNoP, null, 0, null, nodeP, null, $root_container);
13794
14796
  }
13795
14797
 
13796
- let ret_done = await done($ret_panel_div);
13797
-
13798
- return ret_done;
14798
+ return await done($ret_panel_div);
13799
14799
  },
13800
14800
  };
13801
14801
 
13802
- const draw_html_element_org = async function (element) {
13803
- const done = async function (ret = {}) {
13804
- return $div;
13805
- };
13806
- if (!element || element === 'script') return await done();
13807
- let str = '';
13808
-
13809
- var $div = await func.UI.screen.create_container(SESSION_ID, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, prop, null, null, element, null, str);
13810
-
13811
- $div.hover(
13812
- function (e) {
13813
- hover_in($div, e);
13814
- },
13815
- function (e) {
13816
- hover_out();
13817
- },
13818
- );
13819
- if (paramsP.paramsP === 'grid' || parent_infoP?.iterate_info) {
13820
- $div.on('click contextmenu', function (e) {
13821
- hover_in($div, e);
13822
- });
13823
- }
13824
-
13825
- // let ret = await func.UI.screen.set_attributes_new(SESSION_ID, is_skeleton, $container, nodeP, $div, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, $div, true);
13826
- let ret = await func.UI.screen.set_attributes_new(SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, $div, true);
13827
- if (ret.abort || nodeP.tagName === 'svg' || !_.isEmpty(nodeP?.attributes?.['xu-text']) || !_.isEmpty(nodeP?.attributes?.['xu-html']) || !_.isEmpty(nodeP?.attributes?.['xu-exp:xu-text']) || !_.isEmpty(nodeP?.attributes?.['xu-exp:xu-html'])) {
13828
- return await done(ret);
13829
- }
13830
- // check if iterator made to prevent children render
13831
-
13832
- if (nodeP?.attributes?.['xu-viewport'] == 'true') {
13833
- // const xu_viewport = async function () {
13834
- // const data = { $div: $div.clone(true), nodeP, parent_infoP, $root_container, paramsP, jobNoP, is_skeleton, keyP, refreshed_ds, parent_nodeP, check_existP, $container };
13835
- // const container_id = $container.attr('xu-ui-id');
13836
- // if (!UI_WORKER_OBJ.pending_for_viewport_render[container_id]) {
13837
- // UI_WORKER_OBJ.pending_for_viewport_render[container_id] = { base_$div: $div, data: [], $container };
13838
- // await iterate_child($div, nodeP, parent_infoP, $root_container);
13839
- // } else {
13840
- // $div.remove();
13841
- // }
13842
- // UI_WORKER_OBJ.pending_for_viewport_render[container_id].data.push(data);
13843
-
13844
- // // if (!$div.children().length) {
13845
- // // // render the first element to determine height
13846
- // // await iterate_child($div, nodeP, parent_infoP, $root_container);
13847
- // // // hover_in($div);
13848
- // // // func.UI.worker.add_to_queue(SESSION_ID, 'gui event', 'render_viewport', data, null, null, paramsP.dsSessionP);
13849
- // // } else {
13850
- // // }
13851
- // };
13852
- const xu_viewport = function () {
13853
- const observer_inViewport = new IntersectionObserver(
13854
- function (entries) {
13855
- entries.forEach((entry) => {
13856
- if (entry.isIntersecting) {
13857
- $(entry.target).trigger('inViewport');
13858
-
13859
- // Optional: stop observing once triggered
13860
- observer_inViewport.unobserve(entry.target);
13861
- }
13862
- });
13863
- },
13864
- {
13865
- threshold: 0.1, // Trigger when 10% of element is visible
13866
- },
13867
- );
13868
-
13869
- const observer_outViewport = new IntersectionObserver(
13870
- function (entries) {
13871
- entries.forEach((entry) => {
13872
- if (!entry.isIntersecting) {
13873
- // Element is OUT of viewport - trigger custom event
13874
- $(entry.target).trigger('outViewport');
13875
-
13876
- // Optional: stop observing once triggered
13877
- // observer_outViewport.unobserve(entry.target);
13878
- }
13879
- });
13880
- },
13881
- {
13882
- threshold: 0, // Trigger when element is completely out of view
13883
- },
13884
- );
13885
-
13886
- let ui_job_id;
13887
- $div.on('inViewport', function () {
13888
- if ($div.children().length) {
13889
- $div.removeClass('skeleton');
13890
- return;
13891
- }
13892
-
13893
- // if (UI_WORKER_OBJ.cache[$div.attr('xu-ui-id')]) {
13894
- // $div[0].style.removeProperty('height');
13895
- // $div.removeClass('skeleton');
13896
- // $div.html(UI_WORKER_OBJ.cache[$div.attr('xu-ui-id')]);
13897
- // } else {
13898
- hover_in($div);
13899
- ui_job_id = func.UI.worker.add_to_queue(SESSION_ID, 'gui event', 'render_viewport', { $div, nodeP, parent_infoP, $root_container, paramsP, jobNoP, is_skeleton, keyP, refreshed_ds, parent_nodeP, check_existP, $container }, null, null, paramsP.dsSessionP);
13900
- // }
13901
- observer_outViewport.observe($div[0]);
13902
- });
13903
-
13904
- $div.on('outViewport', function () {
13905
- func.UI.worker.delete_job(SESSION_ID, ui_job_id);
13906
-
13907
- if ($div.children().length) {
13908
- // UI_WORKER_OBJ.cache[$div.attr('xu-ui-id')] = $div.children().clone(true);
13909
- $div.empty();
13910
- const height = $div?.data()?.xuData?.viewport_height || 10;
13911
- if (typeof height !== 'undefined') {
13912
- $div.css('height', height);
13913
- }
13914
- }
13915
- // $div.addClass('skeleton');
13916
- observer_inViewport.observe($div[0]);
13917
- });
13918
- $div.addClass('skeleton');
13919
- observer_inViewport.observe($div[0]);
13920
- };
13921
- xu_viewport();
13922
- } else {
13923
- await iterate_child($div, nodeP, parent_infoP, $root_container);
13924
- }
13925
-
13926
- // const ret_iterate_child = await iterate_child($div, nodeP, parent_infoP, null, $root_container);
13927
- return await done(ret);
13928
- };
13929
-
13930
14802
  const draw_html_element = async function (element) {
13931
14803
  const done = async function (ret = {}) {
13932
14804
  const xu_ui_id = $div.attr('xu-ui-id');
13933
14805
  $div.removeClass('display_none');
13934
- if (ret.has_xu_exp_render_attribute) {
13935
- // $div.css('display', 'unset');
13936
14806
 
14807
+ if (ret.has_xu_exp_render_attribute) {
13937
14808
  const xu_render_cache_id = await get_xu_render_cache_str(SESSION_ID, paramsP.dsSessionP, Object.keys($div.data()?.xuData?.attr_exp_info?.['xu-render']?.fields || {}));
14809
+
13938
14810
  const _$div = $div.clone(true);
13939
- UI_WORKER_OBJ.xu_render_cache[xu_ui_id + xu_render_cache_id] = { $div: _$div, paramsP, data: _$div.data() };
14811
+ UI_WORKER_OBJ.xu_render_cache[xu_ui_id + xu_render_cache_id] = {
14812
+ $div: _$div,
14813
+ paramsP,
14814
+ data: _$div.data(),
14815
+ };
14816
+
13940
14817
  nodeP.xu_render_xu_ui_id = xu_ui_id;
13941
14818
  nodeP.xu_render_cache_id = xu_render_cache_id;
13942
14819
 
13943
14820
  if (ret.xu_render_background_processing) {
13944
- temp_$div.remove();
13945
- // $container.find(`[xu-ui-id="${xu_ui_id}"]`).remove();
13946
- return $div;
13947
- } else {
13948
- // $div.css('display', 'unset');
13949
- temp_$div.replaceWith($div);
13950
- return $div;
13951
- }
13952
- } else {
13953
- if (ret.has_xu_render_attribute) {
13954
14821
  temp_$div.remove();
13955
14822
  return $div;
13956
14823
  }
13957
- // $div.css('display', 'unset');
13958
14824
  temp_$div.replaceWith($div);
13959
14825
  return $div;
13960
14826
  }
14827
+
14828
+ if (ret.has_xu_render_attribute) {
14829
+ temp_$div.remove();
14830
+ return $div;
14831
+ }
14832
+
14833
+ temp_$div.replaceWith($div);
14834
+ return $div;
13961
14835
  };
13962
- if (!element || element === 'script') return await done();
13963
- let str = '';
13964
14836
 
13965
- var temp_$div = await func.UI.screen.create_container(SESSION_ID, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, prop, null, null, element, null, str, true);
14837
+ if (!element || element === 'script') return await done();
13966
14838
 
13967
- let temp_$container = $('<tmp>').data('xuData', $container.data().xuData);
13968
- let $div = temp_$div.clone(true);
14839
+ const temp_$div = await func.UI.screen.create_container(SESSION_ID, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, prop, null, null, element, null, '', true);
13969
14840
 
13970
- // $div.css('display', 'none');
14841
+ const temp_$container = $('<tmp>').data('xuData', $container.data().xuData);
14842
+ const $div = temp_$div.clone(true);
13971
14843
 
13972
14844
  $div.hover(
13973
- function (e) {
13974
- hover_in($div, e);
13975
- },
13976
- function (e) {
13977
- hover_out();
13978
- },
14845
+ (e) => hover_in($div, e),
14846
+ (e) => hover_out(),
13979
14847
  );
14848
+
13980
14849
  if (paramsP.paramsP === 'grid' || parent_infoP?.iterate_info) {
13981
- $div.on('click contextmenu', function (e) {
13982
- hover_in($div, e);
13983
- });
14850
+ $div.on('click contextmenu', (e) => hover_in($div, e));
13984
14851
  }
13985
14852
 
13986
- let ret = await func.UI.screen.set_attributes_new(SESSION_ID, is_skeleton, $root_container, nodeP, temp_$container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, $div, true);
13987
- if (ret.abort || nodeP.tagName === 'svg' || !_.isEmpty(nodeP?.attributes?.['xu-text']) || !_.isEmpty(nodeP?.attributes?.['xu-html']) || !_.isEmpty(nodeP?.attributes?.['xu-exp:xu-text']) || !_.isEmpty(nodeP?.attributes?.['xu-exp:xu-html'])) {
14853
+ const ret = await func.UI.screen.set_attributes_new(SESSION_ID, is_skeleton, $root_container, nodeP, temp_$container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, $div, true);
14854
+
14855
+ if (ret.abort || nodeTag === 'svg' || !_.isEmpty(nodeP?.attributes?.['xu-text']) || !_.isEmpty(nodeP?.attributes?.['xu-html']) || !_.isEmpty(nodeP?.attributes?.['xu-exp:xu-text']) || !_.isEmpty(nodeP?.attributes?.['xu-exp:xu-html'])) {
13988
14856
  return await done(ret);
13989
14857
  }
13990
- // check if iterator made to prevent children render
13991
-
13992
- if (nodeP?.attributes?.['xu-viewport'] == 'true') {
13993
- // const xu_viewport = async function () {
13994
- // const data = { $div: $div.clone(true), nodeP, parent_infoP, $root_container, paramsP, jobNoP, is_skeleton, keyP, refreshed_ds, parent_nodeP, check_existP, $container };
13995
- // const container_id = $container.attr('xu-ui-id');
13996
- // if (!UI_WORKER_OBJ.pending_for_viewport_render[container_id]) {
13997
- // UI_WORKER_OBJ.pending_for_viewport_render[container_id] = { base_$div: $div, data: [], $container };
13998
- // await iterate_child($div, nodeP, parent_infoP, $root_container);
13999
- // } else {
14000
- // $div.remove();
14001
- // }
14002
- // UI_WORKER_OBJ.pending_for_viewport_render[container_id].data.push(data);
14003
-
14004
- // // if (!$div.children().length) {
14005
- // // // render the first element to determine height
14006
- // // await iterate_child($div, nodeP, parent_infoP, $root_container);
14007
- // // // hover_in($div);
14008
- // // // func.UI.worker.add_to_queue(SESSION_ID, 'gui event', 'render_viewport', data, null, null, paramsP.dsSessionP);
14009
- // // } else {
14010
- // // }
14011
- // };
14858
+
14859
+ if (nodeP?.attributes?.['xu-viewport'] === 'true') {
14012
14860
  const xu_viewport = function () {
14013
14861
  const observer_inViewport = new IntersectionObserver(
14014
- function (entries) {
14862
+ (entries) => {
14015
14863
  entries.forEach((entry) => {
14016
14864
  if (entry.isIntersecting) {
14017
14865
  $(entry.target).trigger('inViewport');
14018
-
14019
- // Optional: stop observing once triggered
14020
14866
  observer_inViewport.unobserve(entry.target);
14021
14867
  }
14022
14868
  });
14023
14869
  },
14024
- {
14025
- threshold: 0.1, // Trigger when 10% of element is visible
14026
- },
14870
+ { threshold: 0.1 },
14027
14871
  );
14028
14872
 
14029
14873
  const observer_outViewport = new IntersectionObserver(
14030
- function (entries) {
14874
+ (entries) => {
14031
14875
  entries.forEach((entry) => {
14032
14876
  if (!entry.isIntersecting) {
14033
- // Element is OUT of viewport - trigger custom event
14034
14877
  $(entry.target).trigger('outViewport');
14035
-
14036
- // Optional: stop observing once triggered
14037
- // observer_outViewport.unobserve(entry.target);
14038
14878
  }
14039
14879
  });
14040
14880
  },
14041
- {
14042
- threshold: 0, // Trigger when element is completely out of view
14043
- },
14881
+ { threshold: 0 },
14044
14882
  );
14045
14883
 
14046
14884
  let ui_job_id;
14885
+
14047
14886
  $div.on('inViewport', function () {
14048
14887
  if ($div.children().length) {
14049
14888
  $div.removeClass('skeleton');
14050
14889
  return;
14051
14890
  }
14052
14891
 
14053
- // if (UI_WORKER_OBJ.cache[$div.attr('xu-ui-id')]) {
14054
- // $div[0].style.removeProperty('height');
14055
- // $div.removeClass('skeleton');
14056
- // $div.html(UI_WORKER_OBJ.cache[$div.attr('xu-ui-id')]);
14057
- // } else {
14058
14892
  hover_in($div);
14059
14893
  ui_job_id = func.UI.worker.add_to_queue(SESSION_ID, 'gui event', 'render_viewport', { $div, nodeP, parent_infoP, $root_container, paramsP, jobNoP, is_skeleton, keyP, refreshed_ds, parent_nodeP, check_existP, temp_$container }, null, null, paramsP.dsSessionP);
14060
- // }
14061
14894
  observer_outViewport.observe($div[0]);
14062
14895
  });
14063
14896
 
@@ -14065,66 +14898,49 @@ func.UI.screen.render_ui_tree = async function (SESSION_ID, $container, nodeP, p
14065
14898
  func.UI.worker.delete_job(SESSION_ID, ui_job_id);
14066
14899
 
14067
14900
  if ($div.children().length) {
14068
- // UI_WORKER_OBJ.cache[$div.attr('xu-ui-id')] = $div.children().clone(true);
14069
14901
  $div.empty();
14070
14902
  const height = $div?.data()?.xuData?.viewport_height || 10;
14071
- if (typeof height !== 'undefined') {
14903
+ if (height !== undefined) {
14072
14904
  $div.css('height', height);
14073
14905
  }
14074
14906
  }
14075
- // $div.addClass('skeleton');
14076
14907
  observer_inViewport.observe($div[0]);
14077
14908
  });
14909
+
14078
14910
  $div.addClass('skeleton');
14079
14911
  observer_inViewport.observe($div[0]);
14080
14912
  };
14081
14913
  xu_viewport();
14082
14914
  } else {
14083
- // if (ret.xu_render_background_processing) {
14084
- // // let temp_$div = $div.clone(true);
14085
- // iterate_child($div, nodeP, parent_infoP, $root_container);
14086
- // } else {
14087
- // await iterate_child($div, nodeP, parent_infoP, $root_container);
14088
- // }
14089
14915
  if (!ret.xu_render_background_processing) {
14090
14916
  iterate_child($div, nodeP, parent_infoP, $root_container);
14091
14917
  }
14092
14918
  }
14093
14919
 
14094
- // const ret_iterate_child = await iterate_child($div, nodeP, parent_infoP, null, $root_container);
14095
14920
  return await done(ret);
14096
14921
  };
14097
14922
 
14923
+ // Handle content attribute
14098
14924
  if (nodeP.content && nodeP.attributes) {
14099
14925
  nodeP.attributes['xu-content'] = nodeP.content;
14100
14926
  }
14101
14927
 
14102
- if (nodeP.tagName === 'xu-widget') {
14928
+ // Handle xu-widget
14929
+ if (nodeTag === 'xu-widget') {
14103
14930
  if (is_skeleton) return;
14104
14931
  return await fx['widget']();
14105
14932
  }
14106
- if (fx[nodeP.tagName]) {
14107
- return await fx[nodeP.tagName]();
14933
+
14934
+ // Handle custom tags
14935
+ if (fx[nodeTag]) {
14936
+ return await fx[nodeTag]();
14108
14937
  }
14109
- // const xu_viewport = async function () {
14110
- // const data = { $div, nodeP, parent_infoP, $root_container, paramsP, jobNoP, is_skeleton, keyP, refreshed_ds, parent_nodeP, check_existP, $container };
14111
- // const container_id = $container.attr('xu-ui-id');
14112
- // if (!UI_WORKER_OBJ.pending_for_viewport_render[container_id]) {
14113
- // UI_WORKER_OBJ.pending_for_viewport_render[container_id] = { base_$div: $div, data: [], $container };
14114
- // await iterate_child($div, nodeP, parent_infoP, $root_container);
14115
- // }
14116
- // UI_WORKER_OBJ.pending_for_viewport_render[container_id].data.push(data);
14117
- // };
14118
14938
 
14119
- // if (nodeP?.attributes?.['xu-viewport'] == 'true') {
14120
- // return await xu_viewport();
14121
- // } else {
14939
+ // Render HTML element
14122
14940
  if (!glb.new_xu_render) {
14123
- return await draw_html_element_org(nodeP.tagName);
14941
+ return await draw_html_element_org(nodeTag);
14124
14942
  }
14125
- return await draw_html_element(nodeP.tagName);
14126
-
14127
- // }
14943
+ return await draw_html_element(nodeTag);
14128
14944
  };
14129
14945
 
14130
14946
  func.UI.screen.refresh_document_changes_for_realtime_update = async function (SESSION_ID, doc_change) {