@xuda.io/runtime-bundle 1.0.1248 → 1.0.1250

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.
@@ -31890,278 +31890,1203 @@ const get_params_obj_new = async function (SESSION_ID, prog_id, nodeP, dsSession
31890
31890
  return { params_res, params_raw };
31891
31891
  };
31892
31892
 
31893
- func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, xu_func, $elm, val, is_init, refreshed_ds) {
31894
- if (is_skeleton) return;
31893
+ // func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, xu_func, $elm, val, is_init, refreshed_ds) {
31894
+ // if (is_skeleton) return;
31895
+
31896
+ // // console.log(nodeP.id, xu_func, val);
31897
+ // var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP];
31898
+ // const tag_fx = {
31899
+ // [`xu-panel`]: {
31900
+ // program: async function ($elm, val) {
31901
+ // var ret = {};
31902
+ // var _session = SESSION_OBJ[SESSION_ID];
31903
+ // var _ds = _session.DS_GLB[paramsP.dsSessionP];
31904
+ // const init_program = async function () {
31905
+ // async function render_panel() {
31906
+ // const prog_id = val.value?.prog || val.value;
31907
+ // const params_obj = await get_params_obj_new(SESSION_ID, prog_id, nodeP, paramsP.dsSessionP);
31908
+ // let ret_panel = await func.UI.screen.init(SESSION_ID, prog_id, paramsP.screenId, _ds, $elm, null, _ds.currentRecordId, null, true, params_obj.params_res, 'initXu_panel', undefined, prog_id !== _ds.prog_id ? null : refreshed_ds, params_obj.params_raw);
31909
+ // ret = { $new_div: ret_panel };
31910
+ // if ($container.data().xuData) {
31911
+ // $container.data().xuData.xuPanelProps = $elm.data().xuAttributes;
31912
+ // $container.data().xuData.xuPanelData = ret_panel.data();
31913
+ // }
31914
+ // return ret;
31915
+ // }
31916
+
31917
+ // if (!val.value) {
31918
+ // val.value = '_empty_panel_program';
31919
+ // }
31920
+
31921
+ // ret = await render_panel();
31922
+
31923
+ // return ret;
31924
+ // };
31925
+ // const alter_program = async function () {
31926
+ // var _session = SESSION_OBJ[SESSION_ID];
31927
+ // var _ds = _session.DS_GLB[paramsP.dsSessionP];
31928
+
31929
+ // /////////////////
31930
+ // async function render_panel() {
31931
+ // // // if (!cache_str) {
31932
+ // // // await update_container(screen_ready_function);
31933
+ // // // }
31934
+ // // // if (cache_str && !CACHE_PROG_UI[cache_str]) {
31935
+ // // // await update_container(screen_ready_function);
31936
+ // // // save_cache();
31937
+ // // // }
31938
+ // // // if (callback) callback($div);
31939
+ // // // $container.data().xuData.node.children =
31940
+ // // // $div.data().xuData.node.children;
31941
+ // // // //swiper-wrapper
31942
+ // // // var restore_slides_elements = async function () {
31943
+ // // // if ($tmp_div.children().length) {
31944
+ // // // $tmp_div
31945
+ // // // .find(".swiper-wrapper")
31946
+ // // // .empty()
31947
+ // // // .append($new_div.children());
31948
+ // // // $new_div.append($tmp_div.children());
31949
+ // // // }
31950
+ // // // };
31951
+ // // // // console.log($tmp_div);
31952
+ // // // await restore_slides_elements();
31953
+ // // // // CHANGE_PANEL_BUSY = false;
31954
+ // // // func.events.delete_job(SESSION_ID, jobNo);
31955
+ // // };
31956
+ // const program = val.value?.prog || val.value;
31957
+ // var $wrapper = $('<div>');
31958
+ // var $div = await func.UI.screen.create_container(SESSION_ID, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, nodeP.attributes, null, null, null, $wrapper, '');
31959
+ // const params_obj = await get_params_obj_new(SESSION_ID, program, nodeP, paramsP.dsSessionP);
31960
+ // let ret_init = await func.UI.screen.init(SESSION_ID, program, paramsP.screenId, _ds, $div, null, _ds.currentRecordId, jobNoP, true, params_obj.params_res, 'alterXu_panel', undefined, undefined, params_obj.params_raw);
31961
+ // ret = {
31962
+ // $new_div: ret_init,
31963
+ // abort: true,
31964
+ // };
31965
+ // await func.UI.screen.panel_post_render_handler(SESSION_ID, $elm, $new_div, nodeP, $div.clone(true), jobNoP);
31966
+
31967
+ // return ret;
31968
+ // }
31969
+ // if (!val.value) {
31970
+ // return { abort: true };
31971
+ // }
31972
+ // await render_panel();
31973
+ // return ret;
31974
+ // };
31975
+
31976
+ // if (is_init) {
31977
+ // let ret = await init_program();
31978
+ // return ret;
31979
+ // }
31980
+ // return alter_program();
31981
+ // },
31982
+
31983
+ // 'xu-render': async function ($elm, val) {
31984
+ // let ret = await common_fx['xu-render']($elm, val, true);
31985
+ // return ret;
31986
+ // },
31987
+ // 'xu-ref': async function ($elm, val) {
31988
+ // let ret = await common_fx['xu-ref']($container, val, $container.data().xuData.xuPanelData.xuData.paramsP.dsSessionP);
31989
+ // return ret;
31990
+ // },
31991
+ // },
31992
+ // [`xu-teleport`]: {
31993
+ // to: async function ($elm, val) {
31994
+ // if (!glb.new_xu_render) {
31995
+ // if (val.value) {
31996
+ // // parent_infoP.is_xu_teleport;
31997
+ // if ($elm?.parent()?.data()?.xuData?.length) {
31998
+ // $elm.parent().data('xuTeleportData', []);
31999
+ // for (const [key, node] of Object.entries(nodeP.children)) {
32000
+ // const $teleport_elm = await func.UI.screen.render_ui_tree(SESSION_ID, $(val.value), node, parent_infoP, paramsP, jobNoP, is_skeleton, Number(key), null, node, null, $root_container);
32001
+
32002
+ // $elm.parent().data().xuTeleportData.push($teleport_elm.attr('xu-ui-id'));
32003
+ // $teleport_elm.attr('xu-teleport-parent-id', $elm.parent().attr('xu-ui-id'));
32004
+ // }
32005
+ // $elm.remove();
32006
+ // } else {
32007
+ // $elm.data('xuTeleportData', []).attr('hidden', true);
32008
+ // for (const [key, node] of Object.entries(nodeP.children)) {
32009
+ // const $to_container = $(val.value);
32010
+ // if (!$to_container?.length) {
32011
+ // return console.error(`container ${val.value} for xuTeleportData not found`);
32012
+ // }
32013
+ // const $teleport_elm = await func.UI.screen.render_ui_tree(SESSION_ID, $to_container, node, parent_infoP, paramsP, jobNoP, is_skeleton, Number(key), null, node, null, $root_container);
32014
+
32015
+ // $elm.data().xuTeleportData.push($teleport_elm.attr('xu-ui-id'));
32016
+ // $teleport_elm.attr('xu-teleport-parent-id', $elm.attr('xu-ui-id'));
32017
+ // }
32018
+ // }
32019
+ // }
32020
+ // return { abort: true };
32021
+ // }
32022
+
32023
+ // if (val.value) {
32024
+ // // // parent_infoP.is_xu_teleport;
32025
+ // // if ($elm?.parent()?.data()?.xuData?.length) {
32026
+ // // $elm.parent().data('xuTeleportData', []);
32027
+ // // for (const [key, node] of Object.entries(nodeP.children)) {
32028
+ // // const $teleport_elm = await func.UI.screen.render_ui_tree(SESSION_ID, $(val.value), node, parent_infoP, paramsP, jobNoP, is_skeleton, Number(key), null, node, null, $root_container);
32029
+ // // $elm.parent().data().xuTeleportData.push($teleport_elm.attr('xu-ui-id'));
32030
+ // // $teleport_elm.attr('xu-teleport-parent-id', $elm.parent().attr('xu-ui-id'));
32031
+ // // }
32032
+ // // $elm.remove();
32033
+ // // } else {
32034
+ // // $elm.data('xuTeleportData', []).attr('hidden', true);
32035
+ // // for (const [key, node] of Object.entries(nodeP.children)) {
32036
+ // // const $to_container = $(val.value);
32037
+ // // if (!$to_container?.length) {
32038
+ // // return console.error(`container ${val.value} for xuTeleportData not found`);
32039
+ // // }
32040
+ // // const $teleport_elm = await func.UI.screen.render_ui_tree(SESSION_ID, $to_container, node, parent_infoP, paramsP, jobNoP, is_skeleton, Number(key), null, node, null, $root_container);
32041
+ // // $elm.data().xuTeleportData.push($teleport_elm.attr('xu-ui-id'));
32042
+ // // $teleport_elm.attr('xu-teleport-parent-id', $elm.attr('xu-ui-id'));
32043
+ // // }
32044
+ // // }
32045
+ // }
32046
+ // return {};
32047
+ // },
32048
+ // 'xu-render': async function ($elm, val) {
32049
+ // let ret = await common_fx['xu-render']($elm, val, true);
32050
+ // return ret;
32051
+ // },
32052
+ // 'xu-show': async function ($elm, val) {
32053
+ // let ret = await common_fx['xu-show']($elm, val, true);
32054
+ // return ret;
32055
+ // },
32056
+ // },
32057
+ // };
32058
+
32059
+ // const load_cdn = async function (resource) {
32060
+ // // console.log("loading cdn", resource);
32061
+ // if (!_.isObject(resource) && _.isString(resource)) {
32062
+ // resource = { src: resource, type: 'js' };
32063
+ // }
32064
+ // if (!_.isObject(resource)) {
32065
+ // throw new Error('cdn resource in wrong format');
32066
+ // }
32067
+ // return new Promise(async (resolve) => {
32068
+ // try {
32069
+ // switch (resource.type) {
32070
+ // case 'js':
32071
+ // await func.utils.load_js_on_demand(resource.src);
32072
+ // break;
32073
+ // case 'css':
32074
+ // await func.utils.load_js_on_demand(resource.src);
32075
+ // break;
32076
+ // case 'module':
32077
+ // func.utils.load_js_on_demand(resource.src, 'module');
32078
+ // break;
32079
+
32080
+ // default:
32081
+ // await func.utils.load_js_on_demand(resource.src);
32082
+ // break;
32083
+ // }
32084
+ // resolve();
32085
+ // } catch (error) {
32086
+ // func.utils.debug_report(SESSION_ID, 'xu-cdn', 'Fail to load: ' + resource, 'W');
32087
+ // resolve();
32088
+ // }
32089
+
32090
+ // // if (resource.type === "js" || !resource.type) {
32091
+ // // await func.utils.load_js_on_demand(resource.src);
32092
+ // // return resolve();
32093
+ // // }
32094
+ // // if (resource.type === "css") {
32095
+ // // func.utils.load_css_on_demand(resource.src);
32096
+ // // return resolve();
32097
+ // // }
32098
+ // // if (resource.type === "module") {
32099
+ // // func.utils.load_js_on_demand(resource.src, "module");
32100
+ // // return resolve();
32101
+ // // }
32102
+ // // func.utils.debug_report(
32103
+ // // SESSION_ID,
32104
+ // // "xu-cdn",
32105
+ // // "Fail to load: " + resource,
32106
+ // // "W"
32107
+ // // );
32108
+ // // return resolve();
32109
+ // });
32110
+ // };
32111
+
32112
+ // const common_fx = {
32113
+ // 'xu-attrs': async function ($elm, val) {
32114
+ // if (!val.value) return {};
32115
+ // if (!_.isObject(val.value)) throw 'xu-attrs value us not an object';
32116
+ // for (const [attr_key, attr_val] of Object.entries(val.value)) {
32117
+ // nodeP.attributes[attr_key] = attr_val;
32118
+ // }
32119
+
32120
+ // return {};
32121
+ // },
32122
+ // 'xu-ref': async function ($elm, val, dsSession) {
32123
+ // if (!val.value) return {};
32124
+
32125
+ // func.UI.update_xu_ref(SESSION_ID, dsSession || paramsP.dsSessionP, val.value, $elm);
32126
+
32127
+ // // Select the node that will be observed for mutations
32128
+ // const targetNode = $elm[0];
32129
+
32130
+ // if (!targetNode) return;
32131
+
32132
+ // // Options for the observer (which mutations to observe)
32133
+ // const config = { attributes: true, childList: true, subtree: true };
32134
+
32135
+ // // Callback function to execute when mutations are observed
32136
+ // const callback = (mutationList, observer) => {
32137
+ // func.UI.screen.refresh_xu_attributes(SESSION_ID, [val.value]);
32138
+ // };
32139
+
32140
+ // // Create an observer instance linked to the callback function
32141
+ // const observer = new MutationObserver(callback);
32142
+
32143
+ // // Start observing the target node for configured mutations
32144
+ // observer.observe(targetNode, config);
32145
+
32146
+ // // Later, you can stop observing
32147
+ // // observer.disconnect();
32148
+
32149
+ // return {};
32150
+ // },
32151
+ // 'xu-bind': async function ($elm, val) {
32152
+ // if (is_skeleton) return;
32153
+
32154
+ // let val_is_reference_field = false;
32155
+
32156
+ // let _prog_id = $elm.data().xuData.paramsP.prog_id;
32157
+ // let _dsP = $elm.data().xuData.paramsP.dsSessionP;
32158
+ // const view_ret = await func.utils.VIEWS_OBJ.get(SESSION_ID, _prog_id);
32159
+ // if (!view_ret) return {};
32160
+
32161
+ // let is_dynamic_field = false;
32162
+ // let field_prop;
32163
+ // let bind_field_id;
32164
+
32165
+ // const input_field_type = $elm.attr('type');
32166
+
32167
+ // const get_bind_field = async function (field_id) {
32168
+ // if (['_FOR_VAL', '_FOR_KEY'].includes(field_id)) {
32169
+ // is_dynamic_field = true;
32170
+ // field_prop = _ds.dynamic_fields[field_id];
32171
+ // } else {
32172
+ // field_prop = func.common.find_item_by_key(view_ret.progFields, 'field_id', field_id);
32173
+ // if (!field_prop) {
32174
+ // /// find the field everywhere in the chain Aug 30 2024
32175
+ // const ret_get_value = await func.datasource.get_value(SESSION_ID, field_id, _dsP);
32176
+
32177
+ // if (ret_get_value.found) {
32178
+ // _dsP = ret_get_value.dsSessionP;
32179
+ // let _ds = SESSION_OBJ[SESSION_ID].DS_GLB[_dsP];
32180
+ // _prog_id = _ds.prog_id;
32181
+ // const view_ret = await func.utils.VIEWS_OBJ.get(SESSION_ID, _prog_id);
32182
+ // if (!view_ret) return {};
32183
+ // field_prop = func.common.find_item_by_key(view_ret.progFields, 'field_id', field_id);
32184
+ // }
32185
+ // if (!field_prop) {
32186
+ // throw `field ${field_id} not found in the program scope`;
32187
+ // }
32188
+ // }
32189
+ // }
32190
+ // return field_id;
32191
+ // };
32192
+
32193
+ // try {
32194
+ // bind_field_id = await get_bind_field(val.value.split('.')[0]);
32195
+ // val_is_reference_field = true;
32196
+ // } catch (err) {
32197
+ // console.error(err?.message || err);
32198
+ // return {};
32199
+ // }
32200
+
32201
+ // const field_changed = async function (e) {
32202
+ // var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[_dsP];
32203
+
32204
+ // // update array for checkbox that not in xu-for
32205
+ // if (field_prop.props.fieldType === 'array' && input_field_type === 'checkbox' && val_is_reference_field) {
32206
+ // let arr_value_before_cast = _.clone((await func.datasource.get_value(SESSION_ID, bind_field_id, _dsP, _ds.currentRecordId)).ret.value);
32207
+ // let value_from_getter = bind.getter($elm[0]);
32208
+ // let value;
32209
+ // if (arr_value_before_cast.includes(value_from_getter)) {
32210
+ // value = arr_value_before_cast.filter((item) => !_.isEqual(item, value_from_getter));
32211
+ // } else {
32212
+ // arr_value_before_cast.push(value_from_getter);
32213
+ // value = arr_value_before_cast;
32214
+ // }
32215
+
32216
+ // let datasource_changes = {
32217
+ // [_dsP]: {
32218
+ // [_ds.currentRecordId]: {
32219
+ // [bind_field_id]: value,
32220
+ // },
32221
+ // },
32222
+ // };
32223
+
32224
+ // return await func.datasource.update(SESSION_ID, datasource_changes);
32225
+ // }
32226
+
32227
+ // // update array for radio that not in xu-for
32228
+ // if (field_prop.props.fieldType === 'array' && input_field_type === 'radio' && val_is_reference_field) {
32229
+ // let value_from_getter = bind.getter($elm[0]);
32230
+
32231
+ // let datasource_changes = {
32232
+ // [_dsP]: {
32233
+ // [_ds.currentRecordId]: {
32234
+ // [bind_field_id]: [value_from_getter],
32235
+ // },
32236
+ // },
32237
+ // };
32238
+
32239
+ // return await func.datasource.update(SESSION_ID, datasource_changes);
32240
+ // }
32241
+
32242
+ // var value = await func.common.get_cast_val(SESSION_ID, 'xu-bind', 'value', field_prop.props.fieldType, bind.getter($elm[0]));
32243
+
32244
+ // if (field_prop.props.fieldType === 'object') {
32245
+ // value = await func.common.get_cast_val(SESSION_ID, 'xu-bind', 'value', input_field_type, bind.getter($elm[0]));
32246
+ // }
32247
+
32248
+ // if (!_ds.currentRecordId) return;
32249
+
32250
+ // let datasource_changes = {
32251
+ // [_dsP]: {
32252
+ // [_ds.currentRecordId]: {
32253
+ // [bind_field_id]: value,
32254
+ // },
32255
+ // },
32256
+ // };
32257
+
32258
+ // await func.datasource.update(SESSION_ID, datasource_changes);
32259
+ // const iterate_info = $elm?.data()?.xuData?.iterate_info;
32260
+ // const reference_source_obj = iterate_info?.reference_source_obj;
32261
+ // if (reference_source_obj) {
32262
+ // if (reference_source_obj.ret.type === 'array') {
32263
+ // if (iterate_info.iterator_val === bind_field_id) {
32264
+ // const arr_idx = Number($elm?.data()?.xuData?.iterate_info._key);
32265
+
32266
+ // const dataset_arr = await func.datasource.get_value(SESSION_ID, reference_source_obj.fieldIdP, _dsP, reference_source_obj.currentRecordId);
32267
+ // let new_arr = _.cloneDeep(dataset_arr.ret.value);
32268
+
32269
+ // if (field_prop.props.fieldType === 'object' && val_is_reference_field) {
32270
+ // let obj_item = new_arr[arr_idx];
32271
+
32272
+ // let e_exp = val.value.replace(bind_field_id, 'obj_item');
32273
+
32274
+ // let new_val = eval(e_exp + (input_field_type === 'string' ? `="${value}"` : `=${value}`));
32275
+
32276
+ // new_arr[arr_idx] = obj_item;
32277
+ // } else {
32278
+ // new_arr[arr_idx] = value;
32279
+ // }
32280
+ // // datasource_changes[_dsP][_ds.currentRecordId][reference_source_obj.fieldIdP] = new_arr;
32281
+
32282
+ // let datasource_changes = {
32283
+ // [_dsP]: {
32284
+ // [_ds.currentRecordId]: {
32285
+ // [reference_source_obj.fieldIdP]: new_arr,
32286
+ // },
32287
+ // },
32288
+ // };
32289
+
32290
+ // await func.datasource.update(SESSION_ID, datasource_changes, null, true);
32291
+ // }
32292
+ // }
32293
+ // }
32294
+
32295
+ // await func.datasource.update_changes_for_out_parameter(SESSION_ID, _dsP, _ds.parentDataSourceNo);
32296
+ // };
32297
+
32298
+ // const bind = new UI_FRAMEWORK_PLUGIN.bind();
32299
+
32300
+ // bind.listener($elm[0], field_changed);
32301
+
32302
+ // const set_value = function () {
32303
+ // let _ds = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP];
32304
+ // if (!_ds.currentRecordId) return;
32305
+ // let value;
32306
+ // try {
32307
+ // if (val_is_reference_field) {
32308
+ // if (is_dynamic_field) {
32309
+ // value = _ds.dynamic_fields[bind_field_id].value;
32310
+ // } else {
32311
+ // const row_idx = func.common.find_ROWID_idx(_ds, _ds.currentRecordId);
32312
+ // value = _ds.data_feed.rows?.[row_idx]?.[bind_field_id];
32313
+ // }
32314
+ // if (field_prop.props.fieldType === 'array' && $elm.attr('type') === 'checkbox' && $elm.attr('value')) {
32315
+ // if (value.includes($elm.attr('value'))) {
32316
+ // value = true;
32317
+ // } else {
32318
+ // value = false;
32319
+ // }
32320
+ // } else if (field_prop.props.fieldType === 'array' && $elm.attr('type') === 'radio' && $elm.attr('value')) {
32321
+ // if (value.includes($elm.attr('value'))) {
32322
+ // value = $elm.attr('value');
32323
+ // } else {
32324
+ // value = false;
32325
+ // }
32326
+ // } else if (field_prop.props.fieldType === 'object' && val.value.split('.').length > 1) {
32327
+ // let str = val.value.replace(bind_field_id, '(' + JSON.stringify(value) + ')');
32328
+ // value = eval(str);
32329
+ // }
32330
+ // } else {
32331
+ // value = val.value;
32332
+ // }
32333
+ // if (typeof value === 'undefined') return;
32334
+ // bind.setter($elm[0], value);
32335
+ // } catch (err) {
32336
+ // console.error(err);
32337
+ // }
32338
+ // };
32339
+ // /// init value from ds
32340
+ // $('body').on('xu-bind-refresh.' + _ds.dsSession.toString(), () => {
32341
+ // set_value();
32342
+ // });
32343
+
32344
+ // set_value();
32345
+ // return {};
32346
+ // },
32347
+ // 'xu-render': async function ($elm, val, from_panel) {
32348
+ // const old_render = async function () {
32349
+ // var value = await func.common.get_cast_val(SESSION_ID, 'common fx', 'xu-render', 'bool', val.value);
32350
+ // const init_render = function () {
32351
+ // if (!value) {
32352
+ // var cloned_$div = $elm.clone(true);
32353
+
32354
+ // let $xurender = $('<xurender>').attr('xu-ui-id', $elm.attr('xu-ui-id')).attr('hidden', true).appendTo($container); //.hide();
32355
+ // let original_data_obj = {
32356
+ // $container: cloned_$div,
32357
+ // nodeP: _.cloneDeep(nodeP),
32358
+ // parent_infoP,
32359
+ // paramsP,
32360
+ // keyP,
32361
+ // parent_nodeP,
32362
+ // $root_container,
32363
+ // };
32364
+ // $xurender.data('xuData', cloned_$div.data().xuData);
32365
+ // $xurender.data().xuData.original_data_obj = original_data_obj;
32366
+ // $xurender.data().xuData.xurender_node = cloned_$div;
32367
+ // $xurender.data().xuAttributes = nodeP.attributes || {};
32368
+ // // $xurender.hide();
32369
+
32370
+ // $elm.remove();
32371
+ // return { abort: true };
32372
+ // }
32373
+ // return {};
32374
+ // };
32375
+
32376
+ // const post_render = async function () {
32377
+ // if (value) {
32378
+ // try {
32379
+ // // abort if already rended
32380
+ // if ($elm[0].tagName !== 'XURENDER' && $elm?.length) {
32381
+ // return func.events.delete_job(SESSION_ID, jobNoP);
32382
+ // }
32383
+
32384
+ // let original_data_obj = $elm.data().xuData.original_data_obj;
32385
+
32386
+ // if (!original_data_obj) {
32387
+ // func.events.delete_job(SESSION_ID, jobNoP);
32388
+ // return { delete_job: jobNoP };
32389
+ // }
32390
+
32391
+ // const new_$div = await func.UI.screen.render_ui_tree(
32392
+ // SESSION_ID,
32393
+ // $elm, //original_data_obj.$container,
32394
+ // _.cloneDeep(original_data_obj.nodeP),
32395
+ // original_data_obj.parent_infoP,
32396
+ // original_data_obj.paramsP,
32397
+ // jobNoP,
32398
+ // null,
32399
+ // original_data_obj.keyP,
32400
+ // null,
32401
+ // original_data_obj.parent_nodeP,
32402
+ // null,
32403
+ // original_data_obj.$root_container,
32404
+ // );
32405
+
32406
+ // new_$div.data().xuData.original_data_obj = original_data_obj;
32407
+ // new_$div.data().xuData.xurender_node = $elm.clone(true);
32408
+ // new_$div.data().xuAttributes = $elm.data().xuAttributes || {};
32409
+
32410
+ // const replace = async function () {
32411
+ // $elm.replaceWith(new_$div);
32412
+ // if (from_panel) {
32413
+ // const xuPanelWrapper = _.clone(new_$div.data().xuPanelWrapper);
32414
+ // $elm.parent().data().xuPanelWrapper = xuPanelWrapper;
32415
+ // $elm.replaceWith(new_$div.children());
32416
+ // }
32417
+
32418
+ // if (val.fields_arr) {
32419
+ // return await func.UI.screen.refresh_xu_attributes(SESSION_ID, val.fields_arr, val.jobNoP, new_$div);
32420
+ // }
32421
+ // func.events.delete_job(SESSION_ID, jobNoP);
32422
+ // };
32423
+ // // if ($elm && func.UI.utils.find_in_element_data('xuData', $(SESSION_OBJ[SESSION_ID].root_element), 'xu_id', $elm.data().xuData.xu_id).length) {
32424
+ // if ($elm && $(`[xu-ui-id="${$elm.attr('xu-ui-id')}"]`).length) {
32425
+ // if (new_$div.data().xuData.paramsP) {
32426
+ // return await replace();
32427
+ // }
32428
+
32429
+ // func.events.delete_job(SESSION_ID, jobNoP);
32430
+ // }
32431
+ // } catch (error) {
32432
+ // func.events.delete_job(SESSION_ID, jobNoP);
32433
+ // }
32434
+ // return;
32435
+ // }
32436
+ // // if (!value) {
32437
+ // if ($elm.prop('tagName') === 'XURENDER') {
32438
+ // func.events.delete_job(SESSION_ID, jobNoP);
32439
+ // return;
32440
+ // }
32441
+
32442
+ // let tmp_$div = $('<div>');
32443
+
32444
+ // let $xurender = $('<xurender>').attr('xu-ui-id', $elm.attr('xu-ui-id')).appendTo(tmp_$div); //.hide();
32445
+ // // was true before
32446
+ // if ($elm.data().xuData.xurender_node) {
32447
+ // $xurender.data({
32448
+ // xuAttributes: $elm.data().xuData.xurender_node.data().xuAttributes || {},
32449
+ // xuData: $elm.data().xuData.xurender_node.data().xuData || {},
32450
+ // });
32451
+ // } else {
32452
+ // // default new state
32453
+
32454
+ // $xurender.data({
32455
+ // xuAttributes: $elm.data().xuAttributes || {},
32456
+ // xuData: $elm.data().xuData || {},
32457
+ // });
32458
+ // const original_data_obj = {
32459
+ // nodeP: _.cloneDeep($elm.data().xuData.node_org),
32460
+ // paramsP: $elm.data().xuData.paramsP,
32461
+ // $container: $elm.clone(true),
32462
+ // parent_infoP: parent_infoP,
32463
+ // };
32464
+
32465
+ // $xurender.data().xuData.original_data_obj = original_data_obj;
32466
+ // }
32467
+
32468
+ // //remove xu-teleport trace
32469
+ // $.each($elm.find('xu-teleport'), (key, val) => {
32470
+ // const xuTeleportData = $(val).data().xuTeleportData || [];
32471
+ // for (const teleported_elm_id of xuTeleportData) {
32472
+ // $(`[xu-ui-id="${teleported_elm_id}"]`).remove();
32473
+ // }
32474
+ // });
32475
+
32476
+ // $elm.replaceWith(tmp_$div.children());
32477
+ // func.events.delete_job(SESSION_ID, jobNoP);
32478
+ // // }
32479
+ // };
32480
+ // if (is_init) {
32481
+ // return init_render();
32482
+ // }
32483
+ // return await post_render();
32484
+ // };
32485
+
32486
+ // const new_render = async function () {
32487
+ // var value = await func.common.get_cast_val(SESSION_ID, 'common fx', 'xu-render', 'bool', val.value);
32488
+ // const has_xu_render_attribute = true;
32489
+ // const has_xu_exp_render_attribute = $elm.data()?.xuData?.attr_exp_info?.['xu-render'] ? true : false;
32490
+ // const init_render = async function () {
32491
+ // nodeP.xu_render_made = value;
32492
+ // if (!value) {
32493
+ // if (has_xu_exp_render_attribute) {
32494
+ // return { has_xu_exp_render_attribute, has_xu_render_attribute, xu_render_background_processing: true };
32495
+ // }
32496
+ // return { has_xu_render_attribute, abort: true };
32497
+ // }
32498
+ // return { has_xu_exp_render_attribute, has_xu_render_attribute };
32499
+ // };
32500
+
32501
+ // const post_render = async function () {
32502
+ // // always come from refresh
32503
+ // let nodeP = $container.data().xuData.node.children[keyP];
32504
+ // nodeP.xu_render_made = value;
32505
+ // if (value) {
32506
+ // try {
32507
+ // const xu_render_cache_id = await get_xu_render_cache_str(SESSION_ID, paramsP.dsSessionP, Object.keys($elm.data()?.xuData?.attr_exp_info?.['xu-render']?.fields || {}));
32508
+ // const xu_ui_id = $elm.attr('xu-ui-id');
32509
+ // let new_$div = UI_WORKER_OBJ?.xu_render_cache?.[xu_ui_id + xu_render_cache_id]?.$div.clone(true);
32510
+ // let found_parent_vars = false;
32511
+ // if (new_$div) {
32512
+ // // validate if $div contains fields from parent ds
32513
+ // const parent_data = get_parent_ds_fields(SESSION_ID, paramsP.dsSessionP);
32514
+ // const parent_fields = Object.keys(parent_data);
32515
+
32516
+ // $.each(new_$div.find('*'), (key, val) => {
32517
+ // const _xuAttributes = $(val)?.data()?.xuAttributes;
32518
+ // if (found_parent_vars || !_xuAttributes) return;
32519
+ // for (const [attr_key, attr_val] of Object.entries(_xuAttributes)) {
32520
+ // if (found_parent_vars) break;
32521
+ // for (const [key, val] of Object.entries(parent_fields)) {
32522
+ // if (attr_val.includes('@' + key)) {
32523
+ // found_parent_vars = true;
32524
+ // break;
32525
+ // }
32526
+ // }
32527
+ // }
32528
+ // });
32529
+ // }
32530
+
32531
+ // if (!new_$div || found_parent_vars) {
32532
+ // UI_WORKER_OBJ.xu_render_cache[xu_ui_id + xu_render_cache_id] = { paramsP };
32533
+ // nodeP.xu_render_xu_ui_id = xu_ui_id;
32534
+ // nodeP.xu_render_cache_id = xu_render_cache_id;
32535
+ // new_$div = await func.UI.screen.render_ui_tree(SESSION_ID, $container, nodeP, parent_infoP, paramsP, jobNoP, null, keyP, null, parent_nodeP, null, $root_container);
32536
+ // const _$div = new_$div.clone(true);
32537
+ // UI_WORKER_OBJ.xu_render_cache[xu_ui_id + xu_render_cache_id].$div = _$div;
32538
+ // UI_WORKER_OBJ.xu_render_cache[xu_ui_id + xu_render_cache_id].data = _$div.data();
32539
+ // }
32540
+ // // append order handling
32541
+
32542
+ // if (!$container.children().length) {
32543
+ // new_$div.appendTo($container);
32544
+ // } else {
32545
+ // // iterate the container node
32546
+ // let $last_elm_found = [];
32547
+ // $.each($container.data().xuData.node.children, (item_key, item_val) => {
32548
+ // // const $elm = $(`[xu-node-id="${item_val.id}"]`);
32549
+ // const $elm = func.UI.utils.find_in_element_data('xuData', $(SESSION_OBJ[SESSION_ID].root_element), 'nodeid', item_val.id);
32550
+ // if ($elm.length) {
32551
+ // $last_elm_found = $elm;
32552
+ // }
32553
+ // if (keyP == item_key) {
32554
+ // if ($last_elm_found.length) {
32555
+ // new_$div.after($last_elm_found);
32556
+ // } else {
32557
+ // $container.prepend(new_$div);
32558
+ // }
32559
+ // }
32560
+ // });
32561
+ // }
32562
+ // } catch (error) {
32563
+ // func.events.delete_job(SESSION_ID, jobNoP);
32564
+ // }
32565
+ // return;
32566
+ // }
32567
+
32568
+ // /////////// !value ///////////
32569
+
32570
+ // const xu_ui_id = $elm.attr('xu-ui-id');
32571
+
32572
+ // const cache_str = await get_xu_render_cache_str(SESSION_ID, paramsP.dsSessionP, Object.keys($elm.data()?.xuData?.attr_exp_info?.['xu-render']?.fields || {}));
32573
+ // const _$div = $elm.clone(true);
32574
+ // UI_WORKER_OBJ.xu_render_cache[xu_ui_id + cache_str] = { $div: _$div, data: _$div.data(), paramsP };
32575
+ // $elm.remove();
32576
+ // func.events.delete_job(SESSION_ID, jobNoP);
32577
+ // };
32578
+ // if (is_init) {
32579
+ // return await init_render();
32580
+ // }
32581
+ // return await post_render();
32582
+ // };
32583
+
32584
+ // if (glb.new_xu_render) {
32585
+ // return new_render();
32586
+ // }
32587
+ // return old_render();
32588
+ // },
32589
+ // 'xu-show': async function ($elm, val) {
32590
+ // var value = await func.common.get_cast_val(SESSION_ID, 'common fx', 'xu-show', 'bool', val.value);
32591
+ // if (value) {
32592
+ // $elm.show();
32593
+ // }
32594
+ // if (!value) {
32595
+ // $elm.hide();
32596
+ // }
32597
+ // return {};
32598
+ // },
32599
+ // 'xu-content': async function ($elm, val) {
32600
+ // try {
32601
+ // $elm.html(val.value);
32602
+ // } catch (error) {
32603
+ // console.warn(e);
32604
+ // }
32605
+ // return;
32606
+ // },
32607
+ // 'xu-text': async function ($elm, val) {
32608
+ // try {
32609
+ // $elm.text(val.value);
32610
+ // } catch (error) {
32611
+ // console.warn(e);
32612
+ // }
32613
+ // return;
32614
+ // },
32615
+ // 'xu-html': async function ($elm, val) {
32616
+ // try {
32617
+ // $elm.html(val.value);
32618
+ // } catch (error) {
32619
+ // console.warn(e);
32620
+ // }
32621
+ // return;
32622
+ // },
32623
+ // 'xu-for': async function ($elm, data) {
32624
+ // // exit if call from rendered xu-for item to prevent infante loop (parent_infoP?.iterate_info indicate call from rendered item)
32625
+ // if (parent_infoP?.iterate_info) return {};
32626
+ // if (!data.value) return {};
32627
+ // try {
32628
+ // // data.value (xu-for) can store actual values such as an array, a CSV, or a field_id that references a specific field within the dataset, initialized with values for the iteration.
32629
+ // let arr = data.value;
32630
+
32631
+ // // find reference source field
32632
+ // let reference_source_obj;
32633
+
32634
+ // const _progFields = await func.datasource.get_progFields(SESSION_ID, paramsP.dsSessionP);
32635
+
32636
+ // let view_field_obj = func.common.find_item_by_key(_progFields, 'field_id', data.value);
32637
+ // // detect if data.value (xu-for) is reference field_id by checking if exist in the dataset
32638
+ // if (view_field_obj) {
32639
+ // // xu-for is reference field_id
32640
+ // reference_source_obj = await func.datasource.get_value(SESSION_ID, data.value, paramsP.dsSessionP);
32641
+ // arr = reference_source_obj?.ret?.value;
32642
+ // } else {
32643
+ // // xu-for is actual data
32644
+ // if (typeof data.value === 'string') {
32645
+ // arr = eval(data.value.replaceAll('\\', ''));
32646
+ // }
32647
+ // if (typeof arr === 'number') {
32648
+ // arr = Array.from(Array(arr).keys());
32649
+ // }
32650
+ // }
32651
+
32652
+ // const custom_iterator_key = $elm.data().xuData.iterator_key;
32653
+ // const custom_iterator_val = $elm.data().xuData.iterator_val;
32654
+
32655
+ // let iterator_key = custom_iterator_key;
32656
+ // let iterator_val = custom_iterator_val;
32657
+ // let is_key_dynamic_field, is_val_dynamic_field;
32658
+
32659
+ // // custom FOR_VAL name or namespaced default name
32660
+ // if (!custom_iterator_key) {
32661
+ // is_key_dynamic_field = true;
32662
+
32663
+ // iterator_key = '_FOR_KEY';
32664
+ // }
32665
+
32666
+ // if (!custom_iterator_val) {
32667
+ // is_val_dynamic_field = true;
32668
+
32669
+ // iterator_val = '_FOR_VAL';
32670
+ // }
32671
+
32672
+ // var i = 0;
32673
+ // for await (let [_key, _val] of Object.entries(arr)) {
32674
+ // if (_.isArray(arr)) {
32675
+ // _key = Number(_key);
32676
+ // }
32677
+
32678
+ // const set_value = async function (is_dynamic_field, currentRecordId, field_id, value) {
32679
+ // if (is_dynamic_field) {
32680
+ // func.datasource.add_dynamic_field_to_ds(SESSION_ID, paramsP.dsSessionP, field_id, value);
32681
+ // } else {
32682
+ // const _progFields = await func.datasource.get_progFields(SESSION_ID, paramsP.dsSessionP);
32683
+
32684
+ // let view_field_obj = func.common.find_item_by_key(_progFields, 'field_id', field_id);
32685
+ // if (view_field_obj) {
32686
+ // let _ds = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP];
32687
+ // try {
32688
+ // const row_idx = func.common.find_ROWID_idx(_ds, currentRecordId);
32689
+ // _ds.data_feed.rows[row_idx][field_id] = value;
32690
+ // } catch (err) {
32691
+ // console.error(err);
32692
+ // }
32693
+ // } else {
32694
+ // console.error('field not exist in dataset for xu-for method');
32695
+ // }
32696
+ // }
32697
+ // };
32698
+
32699
+ // var currentRecordId = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP].currentRecordId.toString();
32700
+
32701
+ // await set_value(is_key_dynamic_field, currentRecordId, iterator_key, _key);
32702
+ // await set_value(is_val_dynamic_field, currentRecordId, iterator_val, _val);
32703
+
32704
+ // var iterate_info = {
32705
+ // _val,
32706
+ // _key,
32707
+ // iterator_key,
32708
+ // iterator_val,
32709
+ // is_key_dynamic_field,
32710
+ // is_val_dynamic_field,
32711
+ // reference_source_obj,
32712
+ // };
32713
+ // // let _parent_info = _.cloneDeep(parent_infoP) || {};
32714
+ // let _parent_info = klona.klona(parent_infoP) || {};
32715
+ // _parent_info.iterate_info = iterate_info;
32716
+
32717
+ // const $divP = await func.UI.screen.render_ui_tree(
32718
+ // SESSION_ID,
32719
+ // $container,
32720
+ // nodeP,
32721
+ // _parent_info, //parent_infoP ? _.cloneDeep(_parent_info) : null,
32722
+ // paramsP,
32723
+ // jobNoP,
32724
+ // null,
32725
+ // i,
32726
+ // null,
32727
+ // nodeP,
32728
+ // null,
32729
+ // $root_container,
32730
+ // );
32731
+
32732
+ // $.each($divP.children(), function (key, val) {
32733
+ // if ($(val)?.data()?.xuData) {
32734
+ // $(val).data().xuData.iterate_info = iterate_info;
32735
+ // }
32736
+ // });
32737
+
32738
+ // i++;
32739
+ // }
32740
+ // $elm.remove();
32741
+ // return { abort: true };
32742
+ // } catch (e) {
32743
+ // console.error(' Iterator Arr parse error');
32744
+ // return { abort: true };
32745
+ // }
32746
+ // },
32747
+ // 'xu-for-key': async function ($elm, val) {
32748
+ // $elm.data().xuData.iterator_key = val.value;
32749
+ // return {};
32750
+ // },
32751
+ // 'xu-for-val': async function ($elm, val) {
32752
+ // $elm.data().xuData.iterator_val = val.value;
32753
+ // return {};
32754
+ // },
32755
+ // 'xu-class': async function ($elm, val) {
32756
+ // try {
32757
+ // const classes_string = val.value;
32758
+ // // let obj = _.isString(classes_string) ? JSON.parse(classes_string) : _.defaults(classes_string, {});
32759
+
32760
+ // const classes_obj = _.isString(classes_string) ? JSON.parse(classes_string) : _.defaults(classes_string, {});
32761
+ // for await (const [cla, cond] of Object.entries(classes_obj)) {
32762
+ // let res = await func.expression.get(
32763
+ // SESSION_ID,
32764
+ // cond,
32765
+ // paramsP.dsSessionP,
32766
+ // 'UI Attr EXP',
32767
+ // $elm.data().xuData.currentRecordId, // SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP].currentRecordId
32768
+ // null,
32769
+ // null,
32770
+ // null,
32771
+ // null,
32772
+ // null,
32773
+ // $elm.data().xuData.iterate_info,
32774
+ // );
32775
+
32776
+ // if (res.result) {
32777
+ // $elm.addClass(cla);
32778
+ // } else {
32779
+ // $elm.removeClass(cla);
32780
+ // }
32781
+
32782
+ // $elm.data().xuData.debug_info.attribute_stat['xu-class'] = $elm.attr('class');
32783
+ // }
32784
+ // return {};
32785
+ // } catch (e) {
32786
+ // console.warn('parse error:' + val.value);
32787
+ // return { abort: true };
32788
+ // }
32789
+ // },
32790
+ // 'xu-exp': async function ($elm, val) {
32791
+ // let exp = val.value === null ? true : val.value;
32792
+
32793
+ // let exp_ret = await func.expression.get(SESSION_ID, exp, paramsP.dsSessionP, 'UI Attr EXP', SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP].currentRecordId, null, null, null, null, null, $elm.data().xuData.iterate_info);
32794
+
32795
+ // let value = func.UI.screen.fix_val_defaults(val.key, exp_ret.result);
32796
+
32797
+ // var new_val = {
32798
+ // key: val.key,
32799
+ // value,
32800
+ // };
32801
+
32802
+ // if (nodeP.tagName.substr(0, 3) === 'xu-') {
32803
+ // if (tag_fx[nodeP.tagName][new_val.key]) {
32804
+ // return await tag_fx[nodeP.tagName][new_val.key]($elm, new_val);
32805
+ // }
32806
+ // console.warn(`attribute ${new_val.key} not found for ${nodeP.tagName}`);
32807
+ // return {};
32808
+ // }
32809
+ // if (!$elm.data().xuData) return;
32810
+
32811
+ // $elm.data().xuData.debug_info.attribute_stat[new_val.key] = new_val.value;
32812
+
32813
+ // // IGNORE UNDEFINED or NULL ATTRIBUTES
32814
+ // if (typeof new_val.value === 'undefined' || new_val.value === null) {
32815
+ // return {};
32816
+ // }
32817
+
32818
+ // // IGNORE ATTRIBUTES WITH EMPTY VALUES
32819
+ // if (glb.solid_attributes.includes(new_val.key) && !new_val.value) {
32820
+ // return {};
32821
+ // }
32822
+
32823
+ // if (new_val.key.substr(0, 2) === 'xu') {
32824
+ // return await common_fx[new_val.key]($elm, new_val);
32825
+ // }
32826
+
32827
+ // $elm.attr(new_val.key, ($elm.attr(new_val.key) || '') + new_val.value);
32828
+ // return {};
32829
+ // },
32830
+ // 'xu-on': async function ($elm, val) {
32831
+ // CLIENT_ACTIVITY_TS = Date.now();
32832
+ // const trigger = val.key.split('xu-on:')[1].toLowerCase();
32833
+ // $elm.on(trigger, async function (evt) {
32834
+ // const _$elm = $(evt.currentTarget);
32835
+ // if (_.isEmpty(_$elm.data().xuAttributes)) return;
32836
+
32837
+ // for await (const [key, val] of Object.entries(_$elm.data().xuAttributes['xu-on:' + evt.type])) {
32838
+ // if (!_.isEmpty(val.props.condition)) {
32839
+ // const expCond = await func.expression.get(SESSION_ID, val.props.condition, paramsP.dsSessionP, 'condition', paramsP.recordid); // execute expression
32840
+ // if (!expCond.result) continue;
32841
+ // }
32842
+
32843
+ // if (val.event_modifiers && evt[val.event_modifiers]) {
32844
+ // evt[val.event_modifiers]();
32845
+ // }
32846
+
32847
+ // // if (val.handler === 'custom') {
32848
+ // if (val.workflow) {
32849
+ // // do BL
32850
+ // for await (const [key2, val2] of Object.entries(val.workflow)) {
32851
+ // // var cond = val2.data.enabled;
32852
+ // // if (val2.data.enabled && val2.props.condition) {
32853
+ // // expCond = await func.expression.get(SESSION_ID, val2.props.condition, paramsP.dsSessionP, 'condition', paramsP.recordid); // execute expression
32854
+ // // cond = expCond.result;
32855
+ // // }
32856
+ // // if (!cond) continue;
32857
+
32858
+ // if (!val2.data.enabled) continue; // added Jul 3, 25 - condition validate on execution
32859
+
32860
+ // func.events.add_to_queue(SESSION_ID, 'element event', val2.id, evt.type, val2.data.action, val2.data.name, null, _$elm.attr('xu-ui-id'), null, evt, null, null, null, paramsP.dsSessionP, null, null, null, evt.type, val2.data.name, null, null, val2, null, null, null, null, null, null);
32861
+ // }
32862
+ // }
32863
+ // }
32864
+ // });
32865
+ // return {};
32866
+ // },
32867
+ // 'xu-script': async function ($elm, val) {
32868
+ // var checkExist = setInterval(async function () {
32869
+ // if ($elm.is(':visible')) {
32870
+ // try {
32871
+ // // var res = eval('(' + val.value + ')');
32872
+ // // const fn = `(function(el) {
32873
+ // // ${val.value}
32874
+ // // })(document.querySelector(\`[xu-ui-id="${$elm.attr('xu-ui-id')}"]\`));`;
32875
+
32876
+ // const fn = `async (el)=>{${val.value} };`;
32877
+
32878
+ // var res = eval(fn);
32879
+ // await res($elm[0]);
32880
+ // // if (typeof res === 'function') {
32881
+ // // res($elm[0]);
32882
+ // // }
32883
+ // } catch (e) {
32884
+ // eval(val.value);
32885
+ // }
32886
+
32887
+ // clearInterval(checkExist);
32888
+ // }
32889
+ // }, 100); // check every 100ms
32890
+
32891
+ // return {};
32892
+ // },
32893
+ // 'xu-style-global': async function ($elm, val) {
32894
+ // $('head').append(`<style>${val.value}</style>`);
32895
+ // return {};
32896
+ // },
32897
+ // 'xu-style': async function ($elm, val) {
32898
+ // var cssString = val.value;
32899
+
32900
+ // var parser = new cssjs();
32901
+
32902
+ // var parsed = parser.parseCSS(cssString);
32903
+ // var xuUiId = `[xu-ui-id="${$elm.attr('xu-ui-id')}"]`;
32904
+
32905
+ // $.each(parsed, function (key, val) {
32906
+ // var selectors_arr = val.selector.split(',');
32907
+
32908
+ // $.each(selectors_arr, function (key2, val2) {
32909
+ // selectors_arr[key2] = `${xuUiId} ${val2}, ${xuUiId}${val2}`;
32910
+ // // console.log(new_selector);
32911
+ // });
32912
+
32913
+ // val.selector = selectors_arr.join(',');
32914
+ // // console.log(parsed);
32915
+ // });
32916
+
32917
+ // var newCSSString = parser.getCSSForEditor(parsed);
32918
+
32919
+ // $('head').append(`<style>${newCSSString}</style>`);
32920
+ // return {};
32921
+ // },
32922
+ // 'xu-cdn': async function ($elm, val) {
32923
+ // for await (const [key, resource] of Object.entries(val.value)) {
32924
+ // await load_cdn(resource);
32925
+ // }
32926
+
32927
+ // return {};
32928
+ // },
32929
+ // 'xu-ui-plugin': async function ($elm, val) {
32930
+ // var _session = SESSION_OBJ[SESSION_ID];
32931
+
32932
+ // for await (const [plugin_name, value] of Object.entries(val.value)) {
32933
+ // const _plugin = APP_OBJ[_session.app_id]?.app_plugins_purchased?.[plugin_name];
32934
+ // if (_plugin?.installed && _plugin?.manifest?.['runtime.mjs']?.exist && _plugin?.manifest?.['index.mjs']?.exist && value.enabled) {
32935
+ // if (_plugin?.manifest?.['runtime.mjs'].dist && _plugin?.manifest?.['runtime.mjs']?.css) {
32936
+ // const plugin_runtime_css_url = await func.utils.get_plugin_npm_cdn(SESSION_ID, plugin_name, 'dist/runtime.css');
32937
+ // func.utils.load_css_on_demand(plugin_runtime_css_url);
32938
+ // }
31895
32939
 
31896
- // console.log(nodeP.id, xu_func, val);
31897
- var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP];
31898
- const tag_fx = {
31899
- [`xu-panel`]: {
31900
- program: async function ($elm, val) {
31901
- var ret = {};
31902
- var _session = SESSION_OBJ[SESSION_ID];
31903
- var _ds = _session.DS_GLB[paramsP.dsSessionP];
31904
- const init_program = async function () {
31905
- async function render_panel() {
31906
- const prog_id = val.value?.prog || val.value;
31907
- const params_obj = await get_params_obj_new(SESSION_ID, prog_id, nodeP, paramsP.dsSessionP);
31908
- let ret_panel = await func.UI.screen.init(SESSION_ID, prog_id, paramsP.screenId, _ds, $elm, null, _ds.currentRecordId, null, true, params_obj.params_res, 'initXu_panel', undefined, prog_id !== _ds.prog_id ? null : refreshed_ds, params_obj.params_raw);
31909
- ret = { $new_div: ret_panel };
31910
- if ($container.data().xuData) {
31911
- $container.data().xuData.xuPanelProps = $elm.data().xuAttributes;
31912
- $container.data().xuData.xuPanelData = ret_panel.data();
31913
- }
31914
- return ret;
31915
- }
32940
+ // const plugin_index_src = await func.utils.get_plugin_npm_cdn(SESSION_ID, plugin_name, `${_plugin.manifest['index.mjs'].dist ? 'dist/' : ''}index.mjs`);
31916
32941
 
31917
- if (!val.value) {
31918
- val.value = '_empty_panel_program';
31919
- }
32942
+ // const plugin_index_resources = await import(plugin_index_src);
31920
32943
 
31921
- ret = await render_panel();
32944
+ // let properties = _.cloneDeep(plugin_index_resources.properties);
32945
+ // for await (let [prop_name, prop_val] of Object.entries(properties)) {
32946
+ // prop_val.value = value?.attributes?.[prop_name];
32947
+ // if (value?.attributes?.[`xu-exp:${prop_name}`]) {
32948
+ // const res = await func.expression.get(SESSION_ID, value?.attributes?.[`xu-exp:${prop_name}`], paramsP.dsSessionP, 'UI Attr EXP');
32949
+ // prop_val.value = res.result;
32950
+ // }
32951
+ // }
32952
+ // // $elm.data().xu_ui_plugin = { properties };
32953
+ // const plugin_runtime_src = await func.utils.get_plugin_npm_cdn(SESSION_ID, plugin_name, `${_plugin.manifest['runtime.mjs'].dist ? 'dist/' : ''}runtime.mjs`);
31922
32954
 
31923
- return ret;
31924
- };
31925
- const alter_program = async function () {
31926
- var _session = SESSION_OBJ[SESSION_ID];
31927
- var _ds = _session.DS_GLB[paramsP.dsSessionP];
32955
+ // const plugin_runtime_resources = await import(plugin_runtime_src);
31928
32956
 
31929
- /////////////////
31930
- async function render_panel() {
31931
- // // if (!cache_str) {
31932
- // // await update_container(screen_ready_function);
31933
- // // }
31934
- // // if (cache_str && !CACHE_PROG_UI[cache_str]) {
31935
- // // await update_container(screen_ready_function);
31936
- // // save_cache();
31937
- // // }
31938
- // // if (callback) callback($div);
31939
- // // $container.data().xuData.node.children =
31940
- // // $div.data().xuData.node.children;
31941
- // // //swiper-wrapper
31942
- // // var restore_slides_elements = async function () {
31943
- // // if ($tmp_div.children().length) {
31944
- // // $tmp_div
31945
- // // .find(".swiper-wrapper")
31946
- // // .empty()
31947
- // // .append($new_div.children());
31948
- // // $new_div.append($tmp_div.children());
31949
- // // }
31950
- // // };
31951
- // // // console.log($tmp_div);
31952
- // // await restore_slides_elements();
31953
- // // // CHANGE_PANEL_BUSY = false;
31954
- // // func.events.delete_job(SESSION_ID, jobNo);
31955
- // };
31956
- const program = val.value?.prog || val.value;
31957
- var $wrapper = $('<div>');
31958
- var $div = await func.UI.screen.create_container(SESSION_ID, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, nodeP.attributes, null, null, null, $wrapper, '');
31959
- const params_obj = await get_params_obj_new(SESSION_ID, program, nodeP, paramsP.dsSessionP);
31960
- let ret_init = await func.UI.screen.init(SESSION_ID, program, paramsP.screenId, _ds, $div, null, _ds.currentRecordId, jobNoP, true, params_obj.params_res, 'alterXu_panel', undefined, undefined, params_obj.params_raw);
31961
- ret = {
31962
- $new_div: ret_init,
31963
- abort: true,
31964
- };
31965
- await func.UI.screen.panel_post_render_handler(SESSION_ID, $elm, $new_div, nodeP, $div.clone(true), jobNoP);
32957
+ // if (plugin_runtime_resources.cdn && typeof _.isArray(plugin_runtime_resources.cdn)) {
32958
+ // for await (const resource of plugin_runtime_resources.cdn) {
32959
+ // await load_cdn(resource);
32960
+ // }
32961
+ // }
31966
32962
 
31967
- return ret;
31968
- }
31969
- if (!val.value) {
31970
- return { abort: true };
31971
- }
31972
- await render_panel();
31973
- return ret;
31974
- };
32963
+ // if (plugin_runtime_resources.fn) {
32964
+ // await plugin_runtime_resources.fn(plugin_name, $elm?.[0], properties);
32965
+ // // await plugin_runtime_resources.fn(plugin_name, $elm?.[0], $elm.data().xu_ui_plugin.properties);
32966
+ // }
32967
+ // }
32968
+ // }
31975
32969
 
31976
- if (is_init) {
31977
- let ret = await init_program();
31978
- return ret;
31979
- }
31980
- return alter_program();
31981
- },
32970
+ // return {};
32971
+ // },
32972
+ // 'xu-store': async function ($elm, val) {
32973
+ // try {
32974
+ // const fields_obj = JSON5.parse(val.value);
32975
+ // for (const [field_id, value] of Object.entries(fields_obj)) {
32976
+ // func.datasource.add_dynamic_field_to_ds(SESSION_ID, paramsP.dsSessionP, field_id, value);
32977
+ // }
32978
+ // } catch (err) {
32979
+ // console.error(err);
32980
+ // }
32981
+ // return {};
32982
+ // },
32983
+ // 'xu-viewport': async function ($elm, val) {
32984
+ // // functionality in draw_html_element
32985
+ // return {};
32986
+ // },
32987
+ // };
31982
32988
 
31983
- 'xu-render': async function ($elm, val) {
31984
- let ret = await common_fx['xu-render']($elm, val, true);
31985
- return ret;
31986
- },
31987
- 'xu-ref': async function ($elm, val) {
31988
- let ret = await common_fx['xu-ref']($container, val, $container.data().xuData.xuPanelData.xuData.paramsP.dsSessionP);
31989
- return ret;
31990
- },
31991
- },
31992
- [`xu-teleport`]: {
31993
- to: async function ($elm, val) {
31994
- if (!glb.new_xu_render) {
31995
- if (val.value) {
31996
- // parent_infoP.is_xu_teleport;
31997
- if ($elm?.parent()?.data()?.xuData?.length) {
31998
- $elm.parent().data('xuTeleportData', []);
31999
- for (const [key, node] of Object.entries(nodeP.children)) {
32000
- const $teleport_elm = await func.UI.screen.render_ui_tree(SESSION_ID, $(val.value), node, parent_infoP, paramsP, jobNoP, is_skeleton, Number(key), null, node, null, $root_container);
32001
-
32002
- $elm.parent().data().xuTeleportData.push($teleport_elm.attr('xu-ui-id'));
32003
- $teleport_elm.attr('xu-teleport-parent-id', $elm.parent().attr('xu-ui-id'));
32004
- }
32005
- $elm.remove();
32006
- } else {
32007
- $elm.data('xuTeleportData', []).attr('hidden', true);
32008
- for (const [key, node] of Object.entries(nodeP.children)) {
32009
- const $to_container = $(val.value);
32010
- if (!$to_container?.length) {
32011
- return console.error(`container ${val.value} for xuTeleportData not found`);
32012
- }
32013
- const $teleport_elm = await func.UI.screen.render_ui_tree(SESSION_ID, $to_container, node, parent_infoP, paramsP, jobNoP, is_skeleton, Number(key), null, node, null, $root_container);
32989
+ // if (nodeP.tagName.substr(0, 3) === 'xu-') {
32990
+ // if (xu_func === 'xu-exp') {
32991
+ // return common_fx[xu_func]($elm, val);
32992
+ // }
32014
32993
 
32015
- $elm.data().xuTeleportData.push($teleport_elm.attr('xu-ui-id'));
32016
- $teleport_elm.attr('xu-teleport-parent-id', $elm.attr('xu-ui-id'));
32017
- }
32018
- }
32019
- }
32020
- return { abort: true };
32021
- }
32994
+ // if (tag_fx?.[nodeP.tagName]?.[xu_func]) {
32995
+ // let ret = await tag_fx[nodeP.tagName][xu_func]($elm, val);
32996
+ // return ret;
32997
+ // }
32998
+ // // if (xu_func !== "tree_id")
32999
+ // console.warn(`attribute ${xu_func} not found for ${nodeP.tagName}`);
33000
+ // return {};
33001
+ // }
33002
+ // if (_.isEmpty($elm.data())) {
33003
+ // return {};
33004
+ // }
33005
+ // if (!$elm.data().xuData.debug_info.attribute_stat) {
33006
+ // $elm.data().xuData.debug_info.attribute_stat = {};
33007
+ // }
33008
+ // if (xu_func !== 'xu-exp') {
33009
+ // $elm.data().xuData.debug_info.attribute_stat[xu_func] = val.value;
33010
+ // }
33011
+ // try {
33012
+ // if (!common_fx[xu_func]) {
33013
+ // console.warn('invalid xu-tag', xu_func, error);
33014
+ // return {};
33015
+ // }
32022
33016
 
32023
- if (val.value) {
32024
- // // parent_infoP.is_xu_teleport;
32025
- // if ($elm?.parent()?.data()?.xuData?.length) {
32026
- // $elm.parent().data('xuTeleportData', []);
32027
- // for (const [key, node] of Object.entries(nodeP.children)) {
32028
- // const $teleport_elm = await func.UI.screen.render_ui_tree(SESSION_ID, $(val.value), node, parent_infoP, paramsP, jobNoP, is_skeleton, Number(key), null, node, null, $root_container);
32029
- // $elm.parent().data().xuTeleportData.push($teleport_elm.attr('xu-ui-id'));
32030
- // $teleport_elm.attr('xu-teleport-parent-id', $elm.parent().attr('xu-ui-id'));
32031
- // }
32032
- // $elm.remove();
32033
- // } else {
32034
- // $elm.data('xuTeleportData', []).attr('hidden', true);
32035
- // for (const [key, node] of Object.entries(nodeP.children)) {
32036
- // const $to_container = $(val.value);
32037
- // if (!$to_container?.length) {
32038
- // return console.error(`container ${val.value} for xuTeleportData not found`);
32039
- // }
32040
- // const $teleport_elm = await func.UI.screen.render_ui_tree(SESSION_ID, $to_container, node, parent_infoP, paramsP, jobNoP, is_skeleton, Number(key), null, node, null, $root_container);
32041
- // $elm.data().xuTeleportData.push($teleport_elm.attr('xu-ui-id'));
32042
- // $teleport_elm.attr('xu-teleport-parent-id', $elm.attr('xu-ui-id'));
32043
- // }
32044
- // }
32045
- }
32046
- return {};
32047
- },
32048
- 'xu-render': async function ($elm, val) {
32049
- let ret = await common_fx['xu-render']($elm, val, true);
32050
- return ret;
32051
- },
32052
- 'xu-show': async function ($elm, val) {
32053
- let ret = await common_fx['xu-show']($elm, val, true);
32054
- return ret;
32055
- },
32056
- },
32057
- };
33017
+ // return await common_fx[xu_func]($elm, val);
33018
+ // } catch (error) {
33019
+ // debugger;
33020
+ // }
33021
+ // };
33022
+
33023
+ func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, xu_func, $elm, val, is_init, refreshed_ds) {
33024
+ if (is_skeleton) return;
33025
+
33026
+ // Cache frequently accessed values
33027
+ const _session = SESSION_OBJ[SESSION_ID];
33028
+ const _ds = _session.DS_GLB[paramsP.dsSessionP];
33029
+ const elmData = $elm.data();
33030
+ const xuData = elmData.xuData;
33031
+ const nodeTag = nodeP.tagName;
33032
+ const isXuTag = nodeTag && nodeTag.startsWith('xu-');
32058
33033
 
32059
33034
  const load_cdn = async function (resource) {
32060
- // console.log("loading cdn", resource);
32061
- if (!_.isObject(resource) && _.isString(resource)) {
32062
- resource = { src: resource, type: 'js' };
32063
- }
32064
33035
  if (!_.isObject(resource)) {
33036
+ resource = _.isString(resource) ? { src: resource, type: 'js' } : null;
33037
+ }
33038
+ if (!resource) {
32065
33039
  throw new Error('cdn resource in wrong format');
32066
33040
  }
32067
- return new Promise(async (resolve) => {
32068
- try {
32069
- switch (resource.type) {
32070
- case 'js':
32071
- await func.utils.load_js_on_demand(resource.src);
32072
- break;
32073
- case 'css':
32074
- await func.utils.load_js_on_demand(resource.src);
32075
- break;
32076
- case 'module':
32077
- func.utils.load_js_on_demand(resource.src, 'module');
32078
- break;
32079
-
32080
- default:
32081
- await func.utils.load_js_on_demand(resource.src);
32082
- break;
32083
- }
32084
- resolve();
32085
- } catch (error) {
32086
- func.utils.debug_report(SESSION_ID, 'xu-cdn', 'Fail to load: ' + resource, 'W');
32087
- resolve();
32088
- }
32089
33041
 
32090
- // if (resource.type === "js" || !resource.type) {
32091
- // await func.utils.load_js_on_demand(resource.src);
32092
- // return resolve();
32093
- // }
32094
- // if (resource.type === "css") {
32095
- // func.utils.load_css_on_demand(resource.src);
32096
- // return resolve();
32097
- // }
32098
- // if (resource.type === "module") {
32099
- // func.utils.load_js_on_demand(resource.src, "module");
32100
- // return resolve();
32101
- // }
32102
- // func.utils.debug_report(
32103
- // SESSION_ID,
32104
- // "xu-cdn",
32105
- // "Fail to load: " + resource,
32106
- // "W"
32107
- // );
32108
- // return resolve();
32109
- });
33042
+ try {
33043
+ const loadFn = resource.type === 'css' ? func.utils.load_css_on_demand : func.utils.load_js_on_demand;
33044
+ const moduleArg = resource.type === 'module' ? 'module' : undefined;
33045
+ await loadFn(resource.src, moduleArg);
33046
+ } catch (error) {
33047
+ func.utils.debug_report(SESSION_ID, 'xu-cdn', 'Fail to load: ' + resource.src, 'W');
33048
+ }
32110
33049
  };
32111
33050
 
32112
33051
  const common_fx = {
32113
33052
  'xu-attrs': async function ($elm, val) {
32114
- if (!val.value) return {};
32115
- if (!_.isObject(val.value)) throw 'xu-attrs value us not an object';
32116
- for (const [attr_key, attr_val] of Object.entries(val.value)) {
32117
- nodeP.attributes[attr_key] = attr_val;
33053
+ if (!val.value || !_.isObject(val.value)) {
33054
+ if (val.value) throw 'xu-attrs value is not an object';
33055
+ return {};
32118
33056
  }
32119
-
33057
+ Object.assign(nodeP.attributes, val.value);
32120
33058
  return {};
32121
33059
  },
33060
+
32122
33061
  'xu-ref': async function ($elm, val, dsSession) {
32123
33062
  if (!val.value) return {};
32124
33063
 
32125
33064
  func.UI.update_xu_ref(SESSION_ID, dsSession || paramsP.dsSessionP, val.value, $elm);
32126
33065
 
32127
- // Select the node that will be observed for mutations
32128
33066
  const targetNode = $elm[0];
33067
+ if (!targetNode) return {};
32129
33068
 
32130
- if (!targetNode) return;
32131
-
32132
- // Options for the observer (which mutations to observe)
32133
- const config = { attributes: true, childList: true, subtree: true };
32134
-
32135
- // Callback function to execute when mutations are observed
32136
- const callback = (mutationList, observer) => {
33069
+ const observer = new MutationObserver(() => {
32137
33070
  func.UI.screen.refresh_xu_attributes(SESSION_ID, [val.value]);
32138
- };
32139
-
32140
- // Create an observer instance linked to the callback function
32141
- const observer = new MutationObserver(callback);
32142
-
32143
- // Start observing the target node for configured mutations
32144
- observer.observe(targetNode, config);
32145
-
32146
- // Later, you can stop observing
32147
- // observer.disconnect();
33071
+ });
32148
33072
 
33073
+ observer.observe(targetNode, { attributes: true, childList: true, subtree: true });
32149
33074
  return {};
32150
33075
  },
33076
+
32151
33077
  'xu-bind': async function ($elm, val) {
32152
- if (is_skeleton) return;
33078
+ if (is_skeleton) return {};
32153
33079
 
32154
33080
  let val_is_reference_field = false;
33081
+ let _prog_id = xuData.paramsP.prog_id;
33082
+ let _dsP = xuData.paramsP.dsSessionP;
32155
33083
 
32156
- let _prog_id = $elm.data().xuData.paramsP.prog_id;
32157
- let _dsP = $elm.data().xuData.paramsP.dsSessionP;
32158
33084
  const view_ret = await func.utils.VIEWS_OBJ.get(SESSION_ID, _prog_id);
32159
33085
  if (!view_ret) return {};
32160
33086
 
32161
33087
  let is_dynamic_field = false;
32162
33088
  let field_prop;
32163
33089
  let bind_field_id;
32164
-
32165
33090
  const input_field_type = $elm.attr('type');
32166
33091
 
32167
33092
  const get_bind_field = async function (field_id) {
@@ -32171,16 +33096,14 @@ func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $
32171
33096
  } else {
32172
33097
  field_prop = func.common.find_item_by_key(view_ret.progFields, 'field_id', field_id);
32173
33098
  if (!field_prop) {
32174
- /// find the field everywhere in the chain Aug 30 2024
32175
33099
  const ret_get_value = await func.datasource.get_value(SESSION_ID, field_id, _dsP);
32176
-
32177
33100
  if (ret_get_value.found) {
32178
33101
  _dsP = ret_get_value.dsSessionP;
32179
- let _ds = SESSION_OBJ[SESSION_ID].DS_GLB[_dsP];
32180
- _prog_id = _ds.prog_id;
32181
- const view_ret = await func.utils.VIEWS_OBJ.get(SESSION_ID, _prog_id);
32182
- if (!view_ret) return {};
32183
- field_prop = func.common.find_item_by_key(view_ret.progFields, 'field_id', field_id);
33102
+ const ds = _session.DS_GLB[_dsP];
33103
+ _prog_id = ds.prog_id;
33104
+ const new_view_ret = await func.utils.VIEWS_OBJ.get(SESSION_ID, _prog_id);
33105
+ if (!new_view_ret) return {};
33106
+ field_prop = func.common.find_item_by_key(new_view_ret.progFields, 'field_id', field_id);
32184
33107
  }
32185
33108
  if (!field_prop) {
32186
33109
  throw `field ${field_id} not found in the program scope`;
@@ -32199,160 +33122,125 @@ func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $
32199
33122
  }
32200
33123
 
32201
33124
  const field_changed = async function (e) {
32202
- var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[_dsP];
32203
-
32204
- // update array for checkbox that not in xu-for
32205
- if (field_prop.props.fieldType === 'array' && input_field_type === 'checkbox' && val_is_reference_field) {
32206
- let arr_value_before_cast = _.clone((await func.datasource.get_value(SESSION_ID, bind_field_id, _dsP, _ds.currentRecordId)).ret.value);
32207
- let value_from_getter = bind.getter($elm[0]);
32208
- let value;
32209
- if (arr_value_before_cast.includes(value_from_getter)) {
32210
- value = arr_value_before_cast.filter((item) => !_.isEqual(item, value_from_getter));
32211
- } else {
32212
- arr_value_before_cast.push(value_from_getter);
32213
- value = arr_value_before_cast;
32214
- }
32215
-
32216
- let datasource_changes = {
32217
- [_dsP]: {
32218
- [_ds.currentRecordId]: {
32219
- [bind_field_id]: value,
32220
- },
32221
- },
32222
- };
32223
-
32224
- return await func.datasource.update(SESSION_ID, datasource_changes);
33125
+ const ds = _session.DS_GLB[_dsP];
33126
+ const fieldType = field_prop.props.fieldType;
33127
+ const isCheckbox = input_field_type === 'checkbox';
33128
+ const isRadio = input_field_type === 'radio';
33129
+
33130
+ // Handle array field with checkbox
33131
+ if (fieldType === 'array' && isCheckbox && val_is_reference_field) {
33132
+ const arr_value = _.clone((await func.datasource.get_value(SESSION_ID, bind_field_id, _dsP, ds.currentRecordId)).ret.value);
33133
+ const value_from_getter = bind.getter($elm[0]);
33134
+ const value = arr_value.includes(value_from_getter) ? arr_value.filter((item) => !_.isEqual(item, value_from_getter)) : [...arr_value, value_from_getter];
33135
+
33136
+ return await func.datasource.update(SESSION_ID, {
33137
+ [_dsP]: { [ds.currentRecordId]: { [bind_field_id]: value } },
33138
+ });
32225
33139
  }
32226
33140
 
32227
- // update array for radio that not in xu-for
32228
- if (field_prop.props.fieldType === 'array' && input_field_type === 'radio' && val_is_reference_field) {
32229
- let value_from_getter = bind.getter($elm[0]);
32230
-
32231
- let datasource_changes = {
32232
- [_dsP]: {
32233
- [_ds.currentRecordId]: {
32234
- [bind_field_id]: [value_from_getter],
32235
- },
32236
- },
32237
- };
32238
-
32239
- return await func.datasource.update(SESSION_ID, datasource_changes);
33141
+ // Handle array field with radio
33142
+ if (fieldType === 'array' && isRadio && val_is_reference_field) {
33143
+ return await func.datasource.update(SESSION_ID, {
33144
+ [_dsP]: { [ds.currentRecordId]: { [bind_field_id]: [bind.getter($elm[0])] } },
33145
+ });
32240
33146
  }
32241
33147
 
32242
- var value = await func.common.get_cast_val(SESSION_ID, 'xu-bind', 'value', field_prop.props.fieldType, bind.getter($elm[0]));
33148
+ let value = await func.common.get_cast_val(SESSION_ID, 'xu-bind', 'value', fieldType, bind.getter($elm[0]));
32243
33149
 
32244
- if (field_prop.props.fieldType === 'object') {
33150
+ if (fieldType === 'object') {
32245
33151
  value = await func.common.get_cast_val(SESSION_ID, 'xu-bind', 'value', input_field_type, bind.getter($elm[0]));
32246
33152
  }
32247
33153
 
32248
- if (!_ds.currentRecordId) return;
33154
+ if (!ds.currentRecordId) return;
32249
33155
 
32250
- let datasource_changes = {
32251
- [_dsP]: {
32252
- [_ds.currentRecordId]: {
32253
- [bind_field_id]: value,
32254
- },
32255
- },
32256
- };
33156
+ await func.datasource.update(SESSION_ID, {
33157
+ [_dsP]: { [ds.currentRecordId]: { [bind_field_id]: value } },
33158
+ });
32257
33159
 
32258
- await func.datasource.update(SESSION_ID, datasource_changes);
32259
- const iterate_info = $elm?.data()?.xuData?.iterate_info;
33160
+ const iterate_info = xuData?.iterate_info;
32260
33161
  const reference_source_obj = iterate_info?.reference_source_obj;
32261
- if (reference_source_obj) {
32262
- if (reference_source_obj.ret.type === 'array') {
32263
- if (iterate_info.iterator_val === bind_field_id) {
32264
- const arr_idx = Number($elm?.data()?.xuData?.iterate_info._key);
32265
-
32266
- const dataset_arr = await func.datasource.get_value(SESSION_ID, reference_source_obj.fieldIdP, _dsP, reference_source_obj.currentRecordId);
32267
- let new_arr = _.cloneDeep(dataset_arr.ret.value);
32268
-
32269
- if (field_prop.props.fieldType === 'object' && val_is_reference_field) {
32270
- let obj_item = new_arr[arr_idx];
32271
33162
 
32272
- let e_exp = val.value.replace(bind_field_id, 'obj_item');
32273
-
32274
- let new_val = eval(e_exp + (input_field_type === 'string' ? `="${value}"` : `=${value}`));
32275
-
32276
- new_arr[arr_idx] = obj_item;
32277
- } else {
32278
- new_arr[arr_idx] = value;
32279
- }
32280
- // datasource_changes[_dsP][_ds.currentRecordId][reference_source_obj.fieldIdP] = new_arr;
32281
-
32282
- let datasource_changes = {
32283
- [_dsP]: {
32284
- [_ds.currentRecordId]: {
32285
- [reference_source_obj.fieldIdP]: new_arr,
32286
- },
32287
- },
32288
- };
33163
+ if (reference_source_obj?.ret?.type === 'array' && iterate_info.iterator_val === bind_field_id) {
33164
+ const arr_idx = Number(iterate_info._key);
33165
+ const dataset_arr = await func.datasource.get_value(SESSION_ID, reference_source_obj.fieldIdP, _dsP, reference_source_obj.currentRecordId);
33166
+ const new_arr = _.cloneDeep(dataset_arr.ret.value);
32289
33167
 
32290
- await func.datasource.update(SESSION_ID, datasource_changes, null, true);
32291
- }
33168
+ if (fieldType === 'object' && val_is_reference_field) {
33169
+ let obj_item = new_arr[arr_idx];
33170
+ const e_exp = val.value.replace(bind_field_id, 'obj_item');
33171
+ eval(e_exp + (input_field_type === 'string' ? `="${value}"` : `=${value}`));
33172
+ new_arr[arr_idx] = obj_item;
33173
+ } else {
33174
+ new_arr[arr_idx] = value;
32292
33175
  }
33176
+
33177
+ await func.datasource.update(
33178
+ SESSION_ID,
33179
+ {
33180
+ [_dsP]: { [ds.currentRecordId]: { [reference_source_obj.fieldIdP]: new_arr } },
33181
+ },
33182
+ null,
33183
+ true,
33184
+ );
32293
33185
  }
32294
33186
 
32295
- await func.datasource.update_changes_for_out_parameter(SESSION_ID, _dsP, _ds.parentDataSourceNo);
33187
+ await func.datasource.update_changes_for_out_parameter(SESSION_ID, _dsP, ds.parentDataSourceNo);
32296
33188
  };
32297
33189
 
32298
33190
  const bind = new UI_FRAMEWORK_PLUGIN.bind();
32299
-
32300
33191
  bind.listener($elm[0], field_changed);
32301
33192
 
32302
33193
  const set_value = function () {
32303
- let _ds = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP];
32304
- if (!_ds.currentRecordId) return;
32305
- let value;
33194
+ const ds = _session.DS_GLB[paramsP.dsSessionP];
33195
+ if (!ds.currentRecordId) return;
33196
+
32306
33197
  try {
33198
+ let value;
32307
33199
  if (val_is_reference_field) {
32308
33200
  if (is_dynamic_field) {
32309
- value = _ds.dynamic_fields[bind_field_id].value;
33201
+ value = ds.dynamic_fields[bind_field_id].value;
32310
33202
  } else {
32311
- const row_idx = func.common.find_ROWID_idx(_ds, _ds.currentRecordId);
32312
- value = _ds.data_feed.rows?.[row_idx]?.[bind_field_id];
33203
+ const row_idx = func.common.find_ROWID_idx(ds, ds.currentRecordId);
33204
+ value = ds.data_feed.rows?.[row_idx]?.[bind_field_id];
32313
33205
  }
32314
- if (field_prop.props.fieldType === 'array' && $elm.attr('type') === 'checkbox' && $elm.attr('value')) {
32315
- if (value.includes($elm.attr('value'))) {
32316
- value = true;
32317
- } else {
32318
- value = false;
32319
- }
32320
- } else if (field_prop.props.fieldType === 'array' && $elm.attr('type') === 'radio' && $elm.attr('value')) {
32321
- if (value.includes($elm.attr('value'))) {
32322
- value = $elm.attr('value');
32323
- } else {
32324
- value = false;
32325
- }
32326
- } else if (field_prop.props.fieldType === 'object' && val.value.split('.').length > 1) {
32327
- let str = val.value.replace(bind_field_id, '(' + JSON.stringify(value) + ')');
32328
- value = eval(str);
33206
+
33207
+ const fieldType = field_prop.props.fieldType;
33208
+ const elmValue = $elm.attr('value');
33209
+
33210
+ if (fieldType === 'array' && input_field_type === 'checkbox' && elmValue) {
33211
+ value = value.includes(elmValue);
33212
+ } else if (fieldType === 'array' && input_field_type === 'radio' && elmValue) {
33213
+ value = value.includes(elmValue) ? elmValue : false;
33214
+ } else if (fieldType === 'object' && val.value.split('.').length > 1) {
33215
+ value = eval(val.value.replace(bind_field_id, '(' + JSON.stringify(value) + ')'));
32329
33216
  }
32330
33217
  } else {
32331
33218
  value = val.value;
32332
33219
  }
32333
- if (typeof value === 'undefined') return;
32334
- bind.setter($elm[0], value);
33220
+
33221
+ if (value !== undefined) {
33222
+ bind.setter($elm[0], value);
33223
+ }
32335
33224
  } catch (err) {
32336
33225
  console.error(err);
32337
33226
  }
32338
33227
  };
32339
- /// init value from ds
32340
- $('body').on('xu-bind-refresh.' + _ds.dsSession.toString(), () => {
32341
- set_value();
32342
- });
32343
33228
 
33229
+ $('body').on('xu-bind-refresh.' + _ds.dsSession, set_value);
32344
33230
  set_value();
32345
33231
  return {};
32346
33232
  },
33233
+
32347
33234
  'xu-render': async function ($elm, val, from_panel) {
32348
- const old_render = async function () {
32349
- var value = await func.common.get_cast_val(SESSION_ID, 'common fx', 'xu-render', 'bool', val.value);
33235
+ const value = await func.common.get_cast_val(SESSION_ID, 'common fx', 'xu-render', 'bool', val.value);
33236
+
33237
+ if (!glb.new_xu_render) {
33238
+ // Old render logic (kept as is for compatibility)
32350
33239
  const init_render = function () {
32351
33240
  if (!value) {
32352
- var cloned_$div = $elm.clone(true);
32353
-
32354
- let $xurender = $('<xurender>').attr('xu-ui-id', $elm.attr('xu-ui-id')).attr('hidden', true).appendTo($container); //.hide();
32355
- let original_data_obj = {
33241
+ const cloned_$div = $elm.clone(true);
33242
+ const $xurender = $('<xurender>').attr('xu-ui-id', $elm.attr('xu-ui-id')).attr('hidden', true).appendTo($container);
33243
+ const original_data_obj = {
32356
33244
  $container: cloned_$div,
32357
33245
  nodeP: _.cloneDeep(nodeP),
32358
33246
  parent_infoP,
@@ -32365,8 +33253,6 @@ func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $
32365
33253
  $xurender.data().xuData.original_data_obj = original_data_obj;
32366
33254
  $xurender.data().xuData.xurender_node = cloned_$div;
32367
33255
  $xurender.data().xuAttributes = nodeP.attributes || {};
32368
- // $xurender.hide();
32369
-
32370
33256
  $elm.remove();
32371
33257
  return { abort: true };
32372
33258
  }
@@ -32376,271 +33262,207 @@ func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $
32376
33262
  const post_render = async function () {
32377
33263
  if (value) {
32378
33264
  try {
32379
- // abort if already rended
32380
- if ($elm[0].tagName !== 'XURENDER' && $elm?.length) {
33265
+ if ($elm[0].tagName !== 'XURENDER' || !$elm?.length) {
32381
33266
  return func.events.delete_job(SESSION_ID, jobNoP);
32382
33267
  }
32383
33268
 
32384
- let original_data_obj = $elm.data().xuData.original_data_obj;
32385
-
33269
+ const original_data_obj = $elm.data().xuData.original_data_obj;
32386
33270
  if (!original_data_obj) {
32387
33271
  func.events.delete_job(SESSION_ID, jobNoP);
32388
33272
  return { delete_job: jobNoP };
32389
33273
  }
32390
33274
 
32391
- const new_$div = await func.UI.screen.render_ui_tree(
32392
- SESSION_ID,
32393
- $elm, //original_data_obj.$container,
32394
- _.cloneDeep(original_data_obj.nodeP),
32395
- original_data_obj.parent_infoP,
32396
- original_data_obj.paramsP,
32397
- jobNoP,
32398
- null,
32399
- original_data_obj.keyP,
32400
- null,
32401
- original_data_obj.parent_nodeP,
32402
- null,
32403
- original_data_obj.$root_container,
32404
- );
33275
+ const new_$div = await func.UI.screen.render_ui_tree(SESSION_ID, $elm, _.cloneDeep(original_data_obj.nodeP), original_data_obj.parent_infoP, original_data_obj.paramsP, jobNoP, null, original_data_obj.keyP, null, original_data_obj.parent_nodeP, null, original_data_obj.$root_container);
32405
33276
 
32406
33277
  new_$div.data().xuData.original_data_obj = original_data_obj;
32407
33278
  new_$div.data().xuData.xurender_node = $elm.clone(true);
32408
33279
  new_$div.data().xuAttributes = $elm.data().xuAttributes || {};
32409
33280
 
32410
33281
  const replace = async function () {
32411
- $elm.replaceWith(new_$div);
33282
+ $elm.replaceWith(from_panel ? new_$div.children() : new_$div);
32412
33283
  if (from_panel) {
32413
- const xuPanelWrapper = _.clone(new_$div.data().xuPanelWrapper);
32414
- $elm.parent().data().xuPanelWrapper = xuPanelWrapper;
32415
- $elm.replaceWith(new_$div.children());
33284
+ $elm.parent().data().xuPanelWrapper = _.clone(new_$div.data().xuPanelWrapper);
32416
33285
  }
32417
-
32418
33286
  if (val.fields_arr) {
32419
33287
  return await func.UI.screen.refresh_xu_attributes(SESSION_ID, val.fields_arr, val.jobNoP, new_$div);
32420
33288
  }
32421
33289
  func.events.delete_job(SESSION_ID, jobNoP);
32422
33290
  };
32423
- // if ($elm && func.UI.utils.find_in_element_data('xuData', $(SESSION_OBJ[SESSION_ID].root_element), 'xu_id', $elm.data().xuData.xu_id).length) {
32424
- if ($elm && $(`[xu-ui-id="${$elm.attr('xu-ui-id')}"]`).length) {
32425
- if (new_$div.data().xuData.paramsP) {
32426
- return await replace();
32427
- }
32428
33291
 
32429
- func.events.delete_job(SESSION_ID, jobNoP);
33292
+ if ($elm && $(`[xu-ui-id="${$elm.attr('xu-ui-id')}"]`).length && new_$div.data().xuData.paramsP) {
33293
+ return await replace();
32430
33294
  }
33295
+ func.events.delete_job(SESSION_ID, jobNoP);
32431
33296
  } catch (error) {
32432
33297
  func.events.delete_job(SESSION_ID, jobNoP);
32433
33298
  }
32434
33299
  return;
32435
33300
  }
32436
- // if (!value) {
33301
+
32437
33302
  if ($elm.prop('tagName') === 'XURENDER') {
32438
33303
  func.events.delete_job(SESSION_ID, jobNoP);
32439
33304
  return;
32440
33305
  }
32441
33306
 
32442
- let tmp_$div = $('<div>');
33307
+ const $xurender = $('<xurender>').attr('xu-ui-id', $elm.attr('xu-ui-id'));
32443
33308
 
32444
- let $xurender = $('<xurender>').attr('xu-ui-id', $elm.attr('xu-ui-id')).appendTo(tmp_$div); //.hide();
32445
- // was true before
32446
33309
  if ($elm.data().xuData.xurender_node) {
32447
33310
  $xurender.data({
32448
33311
  xuAttributes: $elm.data().xuData.xurender_node.data().xuAttributes || {},
32449
33312
  xuData: $elm.data().xuData.xurender_node.data().xuData || {},
32450
33313
  });
32451
33314
  } else {
32452
- // default new state
32453
-
32454
33315
  $xurender.data({
32455
33316
  xuAttributes: $elm.data().xuAttributes || {},
32456
33317
  xuData: $elm.data().xuData || {},
32457
33318
  });
32458
- const original_data_obj = {
33319
+ $xurender.data().xuData.original_data_obj = {
32459
33320
  nodeP: _.cloneDeep($elm.data().xuData.node_org),
32460
33321
  paramsP: $elm.data().xuData.paramsP,
32461
33322
  $container: $elm.clone(true),
32462
33323
  parent_infoP: parent_infoP,
32463
33324
  };
32464
-
32465
- $xurender.data().xuData.original_data_obj = original_data_obj;
32466
33325
  }
32467
33326
 
32468
- //remove xu-teleport trace
32469
33327
  $.each($elm.find('xu-teleport'), (key, val) => {
32470
33328
  const xuTeleportData = $(val).data().xuTeleportData || [];
32471
- for (const teleported_elm_id of xuTeleportData) {
32472
- $(`[xu-ui-id="${teleported_elm_id}"]`).remove();
32473
- }
33329
+ xuTeleportData.forEach((id) => $(`[xu-ui-id="${id}"]`).remove());
32474
33330
  });
32475
33331
 
32476
- $elm.replaceWith(tmp_$div.children());
33332
+ $elm.replaceWith($xurender);
32477
33333
  func.events.delete_job(SESSION_ID, jobNoP);
32478
- // }
32479
33334
  };
32480
- if (is_init) {
32481
- return init_render();
32482
- }
32483
- return await post_render();
32484
- };
32485
33335
 
32486
- const new_render = async function () {
32487
- var value = await func.common.get_cast_val(SESSION_ID, 'common fx', 'xu-render', 'bool', val.value);
32488
- const has_xu_render_attribute = true;
32489
- const has_xu_exp_render_attribute = $elm.data()?.xuData?.attr_exp_info?.['xu-render'] ? true : false;
32490
- const init_render = async function () {
32491
- nodeP.xu_render_made = value;
32492
- if (!value) {
32493
- if (has_xu_exp_render_attribute) {
32494
- return { has_xu_exp_render_attribute, has_xu_render_attribute, xu_render_background_processing: true };
32495
- }
32496
- return { has_xu_render_attribute, abort: true };
32497
- }
32498
- return { has_xu_exp_render_attribute, has_xu_render_attribute };
32499
- };
33336
+ return is_init ? init_render() : await post_render();
33337
+ }
32500
33338
 
32501
- const post_render = async function () {
32502
- // always come from refresh
32503
- let nodeP = $container.data().xuData.node.children[keyP];
32504
- nodeP.xu_render_made = value;
32505
- if (value) {
32506
- try {
32507
- const xu_render_cache_id = await get_xu_render_cache_str(SESSION_ID, paramsP.dsSessionP, Object.keys($elm.data()?.xuData?.attr_exp_info?.['xu-render']?.fields || {}));
32508
- const xu_ui_id = $elm.attr('xu-ui-id');
32509
- let new_$div = UI_WORKER_OBJ?.xu_render_cache?.[xu_ui_id + xu_render_cache_id]?.$div.clone(true);
32510
- let found_parent_vars = false;
32511
- if (new_$div) {
32512
- // validate if $div contains fields from parent ds
32513
- const parent_data = get_parent_ds_fields(SESSION_ID, paramsP.dsSessionP);
32514
- const parent_fields = Object.keys(parent_data);
32515
-
32516
- $.each(new_$div.find('*'), (key, val) => {
32517
- const _xuAttributes = $(val)?.data()?.xuAttributes;
32518
- if (found_parent_vars || !_xuAttributes) return;
32519
- for (const [attr_key, attr_val] of Object.entries(_xuAttributes)) {
32520
- if (found_parent_vars) break;
32521
- for (const [key, val] of Object.entries(parent_fields)) {
32522
- if (attr_val.includes('@' + key)) {
32523
- found_parent_vars = true;
32524
- break;
32525
- }
32526
- }
32527
- }
32528
- });
32529
- }
33339
+ // New render logic
33340
+ const has_xu_render_attribute = true;
33341
+ const has_xu_exp_render_attribute = !!xuData?.attr_exp_info?.['xu-render'];
32530
33342
 
32531
- if (!new_$div || found_parent_vars) {
32532
- UI_WORKER_OBJ.xu_render_cache[xu_ui_id + xu_render_cache_id] = { paramsP };
32533
- nodeP.xu_render_xu_ui_id = xu_ui_id;
32534
- nodeP.xu_render_cache_id = xu_render_cache_id;
32535
- new_$div = await func.UI.screen.render_ui_tree(SESSION_ID, $container, nodeP, parent_infoP, paramsP, jobNoP, null, keyP, null, parent_nodeP, null, $root_container);
32536
- const _$div = new_$div.clone(true);
32537
- UI_WORKER_OBJ.xu_render_cache[xu_ui_id + xu_render_cache_id].$div = _$div;
32538
- UI_WORKER_OBJ.xu_render_cache[xu_ui_id + xu_render_cache_id].data = _$div.data();
32539
- }
32540
- // append order handling
33343
+ const init_render = async function () {
33344
+ nodeP.xu_render_made = value;
33345
+ if (!value) {
33346
+ return has_xu_exp_render_attribute ? { has_xu_exp_render_attribute, has_xu_render_attribute, xu_render_background_processing: true } : { has_xu_render_attribute, abort: true };
33347
+ }
33348
+ return { has_xu_exp_render_attribute, has_xu_render_attribute };
33349
+ };
32541
33350
 
32542
- if (!$container.children().length) {
32543
- new_$div.appendTo($container);
32544
- } else {
32545
- // iterate the container node
32546
- let $last_elm_found = [];
32547
- $.each($container.data().xuData.node.children, (item_key, item_val) => {
32548
- // const $elm = $(`[xu-node-id="${item_val.id}"]`);
32549
- const $elm = func.UI.utils.find_in_element_data('xuData', $(SESSION_OBJ[SESSION_ID].root_element), 'nodeid', item_val.id);
32550
- if ($elm.length) {
32551
- $last_elm_found = $elm;
32552
- }
32553
- if (keyP == item_key) {
32554
- if ($last_elm_found.length) {
32555
- new_$div.after($last_elm_found);
32556
- } else {
32557
- $container.prepend(new_$div);
32558
- }
33351
+ const post_render = async function () {
33352
+ const containerNodeP = $container.data().xuData.node.children[keyP];
33353
+ containerNodeP.xu_render_made = value;
33354
+
33355
+ if (value) {
33356
+ try {
33357
+ const xu_render_cache_id = await get_xu_render_cache_str(SESSION_ID, paramsP.dsSessionP, Object.keys(xuData?.attr_exp_info?.['xu-render']?.fields || {}));
33358
+ const xu_ui_id = $elm.attr('xu-ui-id');
33359
+ const cache_key = xu_ui_id + xu_render_cache_id;
33360
+ let new_$div = UI_WORKER_OBJ?.xu_render_cache?.[cache_key]?.$div?.clone(true);
33361
+ let found_parent_vars = false;
33362
+
33363
+ if (new_$div) {
33364
+ const parent_data = get_parent_ds_fields(SESSION_ID, paramsP.dsSessionP);
33365
+ const parent_fields = Object.keys(parent_data);
33366
+
33367
+ $.each(new_$div.find('*'), (key, val) => {
33368
+ if (found_parent_vars) return;
33369
+ const _xuAttributes = $(val)?.data()?.xuAttributes;
33370
+ if (!_xuAttributes) return;
33371
+
33372
+ for (const attr_val of Object.values(_xuAttributes)) {
33373
+ if (parent_fields.some((field) => attr_val.includes('@' + field))) {
33374
+ found_parent_vars = true;
33375
+ break;
32559
33376
  }
32560
- });
32561
- }
32562
- } catch (error) {
32563
- func.events.delete_job(SESSION_ID, jobNoP);
33377
+ }
33378
+ });
32564
33379
  }
32565
- return;
32566
- }
32567
33380
 
32568
- /////////// !value ///////////
33381
+ if (!new_$div || found_parent_vars) {
33382
+ UI_WORKER_OBJ.xu_render_cache[cache_key] = { paramsP };
33383
+ containerNodeP.xu_render_xu_ui_id = xu_ui_id;
33384
+ containerNodeP.xu_render_cache_id = xu_render_cache_id;
32569
33385
 
32570
- const xu_ui_id = $elm.attr('xu-ui-id');
33386
+ new_$div = await func.UI.screen.render_ui_tree(SESSION_ID, $container, containerNodeP, parent_infoP, paramsP, jobNoP, null, keyP, null, parent_nodeP, null, $root_container);
32571
33387
 
32572
- const cache_str = await get_xu_render_cache_str(SESSION_ID, paramsP.dsSessionP, Object.keys($elm.data()?.xuData?.attr_exp_info?.['xu-render']?.fields || {}));
32573
- const _$div = $elm.clone(true);
32574
- UI_WORKER_OBJ.xu_render_cache[xu_ui_id + cache_str] = { $div: _$div, data: _$div.data(), paramsP };
32575
- $elm.remove();
32576
- func.events.delete_job(SESSION_ID, jobNoP);
32577
- };
32578
- if (is_init) {
32579
- return await init_render();
33388
+ const _$div = new_$div.clone(true);
33389
+ UI_WORKER_OBJ.xu_render_cache[cache_key] = { $div: _$div, data: _$div.data(), paramsP };
33390
+ }
33391
+
33392
+ // Append order handling
33393
+ if (!$container.children().length) {
33394
+ new_$div.appendTo($container);
33395
+ } else {
33396
+ let $last_elm_found = [];
33397
+ $.each($container.data().xuData.node.children, (item_key, item_val) => {
33398
+ const $elm = func.UI.utils.find_in_element_data('xuData', $(_session.root_element), 'nodeid', item_val.id);
33399
+ if ($elm.length) $last_elm_found = $elm;
33400
+ if (keyP == item_key) {
33401
+ $last_elm_found.length ? new_$div.after($last_elm_found) : $container.prepend(new_$div);
33402
+ }
33403
+ });
33404
+ }
33405
+ } catch (error) {
33406
+ func.events.delete_job(SESSION_ID, jobNoP);
33407
+ }
33408
+ return;
32580
33409
  }
32581
- return await post_render();
33410
+
33411
+ // !value
33412
+ const xu_ui_id = $elm.attr('xu-ui-id');
33413
+ const cache_str = await get_xu_render_cache_str(SESSION_ID, paramsP.dsSessionP, Object.keys(xuData?.attr_exp_info?.['xu-render']?.fields || {}));
33414
+ const _$div = $elm.clone(true);
33415
+ UI_WORKER_OBJ.xu_render_cache[xu_ui_id + cache_str] = { $div: _$div, data: _$div.data(), paramsP };
33416
+ $elm.remove();
33417
+ func.events.delete_job(SESSION_ID, jobNoP);
32582
33418
  };
32583
33419
 
32584
- if (glb.new_xu_render) {
32585
- return new_render();
32586
- }
32587
- return old_render();
33420
+ return is_init ? await init_render() : await post_render();
32588
33421
  },
33422
+
32589
33423
  'xu-show': async function ($elm, val) {
32590
- var value = await func.common.get_cast_val(SESSION_ID, 'common fx', 'xu-show', 'bool', val.value);
32591
- if (value) {
32592
- $elm.show();
32593
- }
32594
- if (!value) {
32595
- $elm.hide();
32596
- }
33424
+ const value = await func.common.get_cast_val(SESSION_ID, 'common fx', 'xu-show', 'bool', val.value);
33425
+ $elm.toggle(value);
32597
33426
  return {};
32598
33427
  },
33428
+
32599
33429
  'xu-content': async function ($elm, val) {
32600
33430
  try {
32601
33431
  $elm.html(val.value);
32602
33432
  } catch (error) {
32603
- console.warn(e);
33433
+ console.warn(error);
32604
33434
  }
32605
- return;
32606
33435
  },
33436
+
32607
33437
  'xu-text': async function ($elm, val) {
32608
33438
  try {
32609
33439
  $elm.text(val.value);
32610
33440
  } catch (error) {
32611
- console.warn(e);
33441
+ console.warn(error);
32612
33442
  }
32613
- return;
32614
33443
  },
33444
+
32615
33445
  'xu-html': async function ($elm, val) {
32616
33446
  try {
32617
33447
  $elm.html(val.value);
32618
33448
  } catch (error) {
32619
- console.warn(e);
33449
+ console.warn(error);
32620
33450
  }
32621
- return;
32622
33451
  },
33452
+
32623
33453
  'xu-for': async function ($elm, data) {
32624
- // exit if call from rendered xu-for item to prevent infante loop (parent_infoP?.iterate_info indicate call from rendered item)
32625
- if (parent_infoP?.iterate_info) return {};
32626
- if (!data.value) return {};
33454
+ if (parent_infoP?.iterate_info || !data.value) return {};
33455
+
32627
33456
  try {
32628
- // data.value (xu-for) can store actual values such as an array, a CSV, or a field_id that references a specific field within the dataset, initialized with values for the iteration.
32629
33457
  let arr = data.value;
32630
-
32631
- // find reference source field
32632
33458
  let reference_source_obj;
32633
-
32634
33459
  const _progFields = await func.datasource.get_progFields(SESSION_ID, paramsP.dsSessionP);
33460
+ const view_field_obj = func.common.find_item_by_key(_progFields, 'field_id', data.value);
32635
33461
 
32636
- let view_field_obj = func.common.find_item_by_key(_progFields, 'field_id', data.value);
32637
- // detect if data.value (xu-for) is reference field_id by checking if exist in the dataset
32638
33462
  if (view_field_obj) {
32639
- // xu-for is reference field_id
32640
33463
  reference_source_obj = await func.datasource.get_value(SESSION_ID, data.value, paramsP.dsSessionP);
32641
33464
  arr = reference_source_obj?.ret?.value;
32642
33465
  } else {
32643
- // xu-for is actual data
32644
33466
  if (typeof data.value === 'string') {
32645
33467
  arr = eval(data.value.replaceAll('\\', ''));
32646
33468
  }
@@ -32649,59 +33471,44 @@ func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $
32649
33471
  }
32650
33472
  }
32651
33473
 
32652
- const custom_iterator_key = $elm.data().xuData.iterator_key;
32653
- const custom_iterator_val = $elm.data().xuData.iterator_val;
32654
-
32655
- let iterator_key = custom_iterator_key;
32656
- let iterator_val = custom_iterator_val;
32657
- let is_key_dynamic_field, is_val_dynamic_field;
32658
-
32659
- // custom FOR_VAL name or namespaced default name
32660
- if (!custom_iterator_key) {
32661
- is_key_dynamic_field = true;
32662
-
32663
- iterator_key = '_FOR_KEY';
32664
- }
32665
-
32666
- if (!custom_iterator_val) {
32667
- is_val_dynamic_field = true;
32668
-
32669
- iterator_val = '_FOR_VAL';
32670
- }
32671
-
32672
- var i = 0;
32673
- for await (let [_key, _val] of Object.entries(arr)) {
32674
- if (_.isArray(arr)) {
32675
- _key = Number(_key);
32676
- }
33474
+ const custom_iterator_key = xuData.iterator_key;
33475
+ const custom_iterator_val = xuData.iterator_val;
33476
+ const iterator_key = custom_iterator_key || '_FOR_KEY';
33477
+ const iterator_val = custom_iterator_val || '_FOR_VAL';
33478
+ const is_key_dynamic_field = !custom_iterator_key;
33479
+ const is_val_dynamic_field = !custom_iterator_val;
32677
33480
 
32678
- const set_value = async function (is_dynamic_field, currentRecordId, field_id, value) {
32679
- if (is_dynamic_field) {
32680
- func.datasource.add_dynamic_field_to_ds(SESSION_ID, paramsP.dsSessionP, field_id, value);
32681
- } else {
32682
- const _progFields = await func.datasource.get_progFields(SESSION_ID, paramsP.dsSessionP);
33481
+ const set_value = async function (is_dynamic_field, currentRecordId, field_id, value) {
33482
+ if (is_dynamic_field) {
33483
+ func.datasource.add_dynamic_field_to_ds(SESSION_ID, paramsP.dsSessionP, field_id, value);
33484
+ } else {
33485
+ const _progFields = await func.datasource.get_progFields(SESSION_ID, paramsP.dsSessionP);
33486
+ const view_field_obj = func.common.find_item_by_key(_progFields, 'field_id', field_id);
32683
33487
 
32684
- let view_field_obj = func.common.find_item_by_key(_progFields, 'field_id', field_id);
32685
- if (view_field_obj) {
32686
- let _ds = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP];
32687
- try {
32688
- const row_idx = func.common.find_ROWID_idx(_ds, currentRecordId);
32689
- _ds.data_feed.rows[row_idx][field_id] = value;
32690
- } catch (err) {
32691
- console.error(err);
32692
- }
32693
- } else {
32694
- console.error('field not exist in dataset for xu-for method');
33488
+ if (view_field_obj) {
33489
+ const ds = _session.DS_GLB[paramsP.dsSessionP];
33490
+ try {
33491
+ const row_idx = func.common.find_ROWID_idx(ds, currentRecordId);
33492
+ ds.data_feed.rows[row_idx][field_id] = value;
33493
+ } catch (err) {
33494
+ console.error(err);
32695
33495
  }
33496
+ } else {
33497
+ console.error('field not exist in dataset for xu-for method');
32696
33498
  }
32697
- };
33499
+ }
33500
+ };
33501
+
33502
+ const currentRecordId = _ds.currentRecordId.toString();
33503
+ let i = 0;
32698
33504
 
32699
- var currentRecordId = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP].currentRecordId.toString();
33505
+ for (let [_key, _val] of Object.entries(arr)) {
33506
+ if (_.isArray(arr)) _key = Number(_key);
32700
33507
 
32701
33508
  await set_value(is_key_dynamic_field, currentRecordId, iterator_key, _key);
32702
33509
  await set_value(is_val_dynamic_field, currentRecordId, iterator_val, _val);
32703
33510
 
32704
- var iterate_info = {
33511
+ const iterate_info = {
32705
33512
  _val,
32706
33513
  _key,
32707
33514
  iterator_key,
@@ -32710,26 +33517,13 @@ func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $
32710
33517
  is_val_dynamic_field,
32711
33518
  reference_source_obj,
32712
33519
  };
32713
- // let _parent_info = _.cloneDeep(parent_infoP) || {};
32714
- let _parent_info = klona.klona(parent_infoP) || {};
33520
+
33521
+ const _parent_info = klona.klona(parent_infoP) || {};
32715
33522
  _parent_info.iterate_info = iterate_info;
32716
33523
 
32717
- const $divP = await func.UI.screen.render_ui_tree(
32718
- SESSION_ID,
32719
- $container,
32720
- nodeP,
32721
- _parent_info, //parent_infoP ? _.cloneDeep(_parent_info) : null,
32722
- paramsP,
32723
- jobNoP,
32724
- null,
32725
- i,
32726
- null,
32727
- nodeP,
32728
- null,
32729
- $root_container,
32730
- );
33524
+ const $divP = await func.UI.screen.render_ui_tree(SESSION_ID, $container, nodeP, _parent_info, paramsP, jobNoP, null, i, null, nodeP, null, $root_container);
32731
33525
 
32732
- $.each($divP.children(), function (key, val) {
33526
+ $.each($divP.children(), (key, val) => {
32733
33527
  if ($(val)?.data()?.xuData) {
32734
33528
  $(val).data().xuData.iterate_info = iterate_info;
32735
33529
  }
@@ -32737,106 +33531,87 @@ func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $
32737
33531
 
32738
33532
  i++;
32739
33533
  }
33534
+
32740
33535
  $elm.remove();
32741
33536
  return { abort: true };
32742
33537
  } catch (e) {
32743
- console.error(' Iterator Arr parse error');
33538
+ console.error('Iterator Arr parse error', e);
32744
33539
  return { abort: true };
32745
33540
  }
32746
33541
  },
33542
+
32747
33543
  'xu-for-key': async function ($elm, val) {
32748
- $elm.data().xuData.iterator_key = val.value;
33544
+ xuData.iterator_key = val.value;
32749
33545
  return {};
32750
33546
  },
33547
+
32751
33548
  'xu-for-val': async function ($elm, val) {
32752
- $elm.data().xuData.iterator_val = val.value;
33549
+ xuData.iterator_val = val.value;
32753
33550
  return {};
32754
33551
  },
33552
+
32755
33553
  'xu-class': async function ($elm, val) {
32756
33554
  try {
32757
- const classes_string = val.value;
32758
- // let obj = _.isString(classes_string) ? JSON.parse(classes_string) : _.defaults(classes_string, {});
32759
-
32760
- const classes_obj = _.isString(classes_string) ? JSON.parse(classes_string) : _.defaults(classes_string, {});
32761
- for await (const [cla, cond] of Object.entries(classes_obj)) {
32762
- let res = await func.expression.get(
32763
- SESSION_ID,
32764
- cond,
32765
- paramsP.dsSessionP,
32766
- 'UI Attr EXP',
32767
- $elm.data().xuData.currentRecordId, // SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP].currentRecordId
32768
- null,
32769
- null,
32770
- null,
32771
- null,
32772
- null,
32773
- $elm.data().xuData.iterate_info,
32774
- );
33555
+ const classes_obj = _.isString(val.value) ? JSON.parse(val.value) : _.defaults(val.value, {});
32775
33556
 
32776
- if (res.result) {
32777
- $elm.addClass(cla);
32778
- } else {
32779
- $elm.removeClass(cla);
32780
- }
33557
+ for (const [cla, cond] of Object.entries(classes_obj)) {
33558
+ const res = await func.expression.get(SESSION_ID, cond, paramsP.dsSessionP, 'UI Attr EXP', xuData.currentRecordId, null, null, null, null, null, xuData.iterate_info);
32781
33559
 
32782
- $elm.data().xuData.debug_info.attribute_stat['xu-class'] = $elm.attr('class');
33560
+ $elm.toggleClass(cla, res.result);
32783
33561
  }
33562
+
33563
+ xuData.debug_info.attribute_stat['xu-class'] = $elm.attr('class');
32784
33564
  return {};
32785
33565
  } catch (e) {
32786
33566
  console.warn('parse error:' + val.value);
32787
33567
  return { abort: true };
32788
33568
  }
32789
33569
  },
32790
- 'xu-exp': async function ($elm, val) {
32791
- let exp = val.value === null ? true : val.value;
32792
-
32793
- let exp_ret = await func.expression.get(SESSION_ID, exp, paramsP.dsSessionP, 'UI Attr EXP', SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP].currentRecordId, null, null, null, null, null, $elm.data().xuData.iterate_info);
32794
33570
 
32795
- let value = func.UI.screen.fix_val_defaults(val.key, exp_ret.result);
33571
+ 'xu-exp': async function ($elm, val) {
33572
+ const exp = val.value === null ? true : val.value;
33573
+ const exp_ret = await func.expression.get(SESSION_ID, exp, paramsP.dsSessionP, 'UI Attr EXP', _ds.currentRecordId, null, null, null, null, null, xuData.iterate_info);
32796
33574
 
32797
- var new_val = {
32798
- key: val.key,
32799
- value,
32800
- };
33575
+ const value = func.UI.screen.fix_val_defaults(val.key, exp_ret.result);
33576
+ const new_val = { key: val.key, value };
32801
33577
 
32802
- if (nodeP.tagName.substr(0, 3) === 'xu-') {
32803
- if (tag_fx[nodeP.tagName][new_val.key]) {
32804
- return await tag_fx[nodeP.tagName][new_val.key]($elm, new_val);
33578
+ if (isXuTag) {
33579
+ if (tag_fx[nodeTag]?.[new_val.key]) {
33580
+ return await tag_fx[nodeTag][new_val.key]($elm, new_val);
32805
33581
  }
32806
- console.warn(`attribute ${new_val.key} not found for ${nodeP.tagName}`);
33582
+ console.warn(`attribute ${new_val.key} not found for ${nodeTag}`);
32807
33583
  return {};
32808
33584
  }
32809
- if (!$elm.data().xuData) return;
32810
33585
 
32811
- $elm.data().xuData.debug_info.attribute_stat[new_val.key] = new_val.value;
32812
-
32813
- // IGNORE UNDEFINED or NULL ATTRIBUTES
32814
- if (typeof new_val.value === 'undefined' || new_val.value === null) {
32815
- return {};
32816
- }
33586
+ if (!xuData) return {};
33587
+ xuData.debug_info.attribute_stat[new_val.key] = new_val.value;
32817
33588
 
32818
- // IGNORE ATTRIBUTES WITH EMPTY VALUES
32819
- if (glb.solid_attributes.includes(new_val.key) && !new_val.value) {
32820
- return {};
32821
- }
33589
+ if (new_val.value === undefined || new_val.value === null) return {};
33590
+ if (glb.solid_attributes.includes(new_val.key) && !new_val.value) return {};
32822
33591
 
32823
- if (new_val.key.substr(0, 2) === 'xu') {
33592
+ if (new_val.key.startsWith('xu')) {
32824
33593
  return await common_fx[new_val.key]($elm, new_val);
32825
33594
  }
32826
33595
 
32827
33596
  $elm.attr(new_val.key, ($elm.attr(new_val.key) || '') + new_val.value);
32828
33597
  return {};
32829
33598
  },
33599
+
32830
33600
  'xu-on': async function ($elm, val) {
32831
33601
  CLIENT_ACTIVITY_TS = Date.now();
32832
33602
  const trigger = val.key.split('xu-on:')[1].toLowerCase();
33603
+
32833
33604
  $elm.on(trigger, async function (evt) {
32834
33605
  const _$elm = $(evt.currentTarget);
32835
- if (_.isEmpty(_$elm.data().xuAttributes)) return;
33606
+ const xuAttributes = _$elm.data().xuAttributes;
33607
+ if (_.isEmpty(xuAttributes)) return;
33608
+
33609
+ const handlers = xuAttributes['xu-on:' + evt.type];
33610
+ if (!handlers) return;
32836
33611
 
32837
- for await (const [key, val] of Object.entries(_$elm.data().xuAttributes['xu-on:' + evt.type])) {
33612
+ for (const [key, val] of Object.entries(handlers)) {
32838
33613
  if (!_.isEmpty(val.props.condition)) {
32839
- const expCond = await func.expression.get(SESSION_ID, val.props.condition, paramsP.dsSessionP, 'condition', paramsP.recordid); // execute expression
33614
+ const expCond = await func.expression.get(SESSION_ID, val.props.condition, paramsP.dsSessionP, 'condition', paramsP.recordid);
32840
33615
  if (!expCond.result) continue;
32841
33616
  }
32842
33617
 
@@ -32844,18 +33619,9 @@ func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $
32844
33619
  evt[val.event_modifiers]();
32845
33620
  }
32846
33621
 
32847
- // if (val.handler === 'custom') {
32848
33622
  if (val.workflow) {
32849
- // do BL
32850
- for await (const [key2, val2] of Object.entries(val.workflow)) {
32851
- // var cond = val2.data.enabled;
32852
- // if (val2.data.enabled && val2.props.condition) {
32853
- // expCond = await func.expression.get(SESSION_ID, val2.props.condition, paramsP.dsSessionP, 'condition', paramsP.recordid); // execute expression
32854
- // cond = expCond.result;
32855
- // }
32856
- // if (!cond) continue;
32857
-
32858
- if (!val2.data.enabled) continue; // added Jul 3, 25 - condition validate on execution
33623
+ for (const [key2, val2] of Object.entries(val.workflow)) {
33624
+ if (!val2.data.enabled) continue;
32859
33625
 
32860
33626
  func.events.add_to_queue(SESSION_ID, 'element event', val2.id, evt.type, val2.data.action, val2.data.name, null, _$elm.attr('xu-ui-id'), null, evt, null, null, null, paramsP.dsSessionP, null, null, null, evt.type, val2.data.name, null, null, val2, null, null, null, null, null, null);
32861
33627
  }
@@ -32864,111 +33630,91 @@ func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $
32864
33630
  });
32865
33631
  return {};
32866
33632
  },
33633
+
32867
33634
  'xu-script': async function ($elm, val) {
32868
- var checkExist = setInterval(async function () {
33635
+ const checkExist = setInterval(async function () {
32869
33636
  if ($elm.is(':visible')) {
32870
33637
  try {
32871
- // var res = eval('(' + val.value + ')');
32872
- // const fn = `(function(el) {
32873
- // ${val.value}
32874
- // })(document.querySelector(\`[xu-ui-id="${$elm.attr('xu-ui-id')}"]\`));`;
32875
-
32876
- const fn = `async (el)=>{${val.value} };`;
32877
-
32878
- var res = eval(fn);
32879
- await res($elm[0]);
32880
- // if (typeof res === 'function') {
32881
- // res($elm[0]);
32882
- // }
33638
+ const fn = eval(`async (el)=>{${val.value}}`);
33639
+ await fn($elm[0]);
32883
33640
  } catch (e) {
32884
33641
  eval(val.value);
32885
33642
  }
32886
-
32887
33643
  clearInterval(checkExist);
32888
33644
  }
32889
- }, 100); // check every 100ms
32890
-
33645
+ }, 100);
32891
33646
  return {};
32892
33647
  },
33648
+
32893
33649
  'xu-style-global': async function ($elm, val) {
32894
33650
  $('head').append(`<style>${val.value}</style>`);
32895
33651
  return {};
32896
33652
  },
32897
- 'xu-style': async function ($elm, val) {
32898
- var cssString = val.value;
32899
-
32900
- var parser = new cssjs();
32901
-
32902
- var parsed = parser.parseCSS(cssString);
32903
- var xuUiId = `[xu-ui-id="${$elm.attr('xu-ui-id')}"]`;
32904
-
32905
- $.each(parsed, function (key, val) {
32906
- var selectors_arr = val.selector.split(',');
32907
33653
 
32908
- $.each(selectors_arr, function (key2, val2) {
32909
- selectors_arr[key2] = `${xuUiId} ${val2}, ${xuUiId}${val2}`;
32910
- // console.log(new_selector);
32911
- });
32912
-
32913
- val.selector = selectors_arr.join(',');
32914
- // console.log(parsed);
33654
+ 'xu-style': async function ($elm, val) {
33655
+ const parser = new cssjs();
33656
+ const parsed = parser.parseCSS(val.value);
33657
+ const xuUiId = `[xu-ui-id="${$elm.attr('xu-ui-id')}"]`;
33658
+
33659
+ parsed.forEach((rule) => {
33660
+ rule.selector = rule.selector
33661
+ .split(',')
33662
+ .map((sel) => `${xuUiId} ${sel}, ${xuUiId}${sel}`)
33663
+ .join(',');
32915
33664
  });
32916
33665
 
32917
- var newCSSString = parser.getCSSForEditor(parsed);
32918
-
32919
- $('head').append(`<style>${newCSSString}</style>`);
33666
+ $('head').append(`<style>${parser.getCSSForEditor(parsed)}</style>`);
32920
33667
  return {};
32921
33668
  },
33669
+
32922
33670
  'xu-cdn': async function ($elm, val) {
32923
- for await (const [key, resource] of Object.entries(val.value)) {
33671
+ for (const resource of Object.values(val.value)) {
32924
33672
  await load_cdn(resource);
32925
33673
  }
32926
-
32927
33674
  return {};
32928
33675
  },
32929
- 'xu-ui-plugin': async function ($elm, val) {
32930
- var _session = SESSION_OBJ[SESSION_ID];
32931
33676
 
32932
- for await (const [plugin_name, value] of Object.entries(val.value)) {
33677
+ 'xu-ui-plugin': async function ($elm, val) {
33678
+ for (const [plugin_name, value] of Object.entries(val.value)) {
32933
33679
  const _plugin = APP_OBJ[_session.app_id]?.app_plugins_purchased?.[plugin_name];
32934
- if (_plugin?.installed && _plugin?.manifest?.['runtime.mjs']?.exist && _plugin?.manifest?.['index.mjs']?.exist && value.enabled) {
32935
- if (_plugin?.manifest?.['runtime.mjs'].dist && _plugin?.manifest?.['runtime.mjs']?.css) {
32936
- const plugin_runtime_css_url = await func.utils.get_plugin_npm_cdn(SESSION_ID, plugin_name, 'dist/runtime.css');
32937
- func.utils.load_css_on_demand(plugin_runtime_css_url);
32938
- }
32939
33680
 
32940
- const plugin_index_src = await func.utils.get_plugin_npm_cdn(SESSION_ID, plugin_name, `${_plugin.manifest['index.mjs'].dist ? 'dist/' : ''}index.mjs`);
33681
+ if (!_plugin?.installed || !_plugin?.manifest?.['runtime.mjs']?.exist || !_plugin?.manifest?.['index.mjs']?.exist || !value.enabled) continue;
32941
33682
 
32942
- const plugin_index_resources = await import(plugin_index_src);
33683
+ if (_plugin.manifest['runtime.mjs'].dist && _plugin.manifest['runtime.mjs'].css) {
33684
+ const css_url = await func.utils.get_plugin_npm_cdn(SESSION_ID, plugin_name, 'dist/runtime.css');
33685
+ func.utils.load_css_on_demand(css_url);
33686
+ }
32943
33687
 
32944
- let properties = _.cloneDeep(plugin_index_resources.properties);
32945
- for await (let [prop_name, prop_val] of Object.entries(properties)) {
32946
- prop_val.value = value?.attributes?.[prop_name];
32947
- if (value?.attributes?.[`xu-exp:${prop_name}`]) {
32948
- const res = await func.expression.get(SESSION_ID, value?.attributes?.[`xu-exp:${prop_name}`], paramsP.dsSessionP, 'UI Attr EXP');
32949
- prop_val.value = res.result;
32950
- }
32951
- }
32952
- // $elm.data().xu_ui_plugin = { properties };
32953
- const plugin_runtime_src = await func.utils.get_plugin_npm_cdn(SESSION_ID, plugin_name, `${_plugin.manifest['runtime.mjs'].dist ? 'dist/' : ''}runtime.mjs`);
33688
+ const plugin_index_src = await func.utils.get_plugin_npm_cdn(SESSION_ID, plugin_name, `${_plugin.manifest['index.mjs'].dist ? 'dist/' : ''}index.mjs`);
32954
33689
 
32955
- const plugin_runtime_resources = await import(plugin_runtime_src);
33690
+ const plugin_index_resources = await import(plugin_index_src);
33691
+ const properties = _.cloneDeep(plugin_index_resources.properties);
32956
33692
 
32957
- if (plugin_runtime_resources.cdn && typeof _.isArray(plugin_runtime_resources.cdn)) {
32958
- for await (const resource of plugin_runtime_resources.cdn) {
32959
- await load_cdn(resource);
32960
- }
33693
+ for (const [prop_name, prop_val] of Object.entries(properties)) {
33694
+ prop_val.value = value?.attributes?.[prop_name];
33695
+ if (value?.attributes?.[`xu-exp:${prop_name}`]) {
33696
+ const res = await func.expression.get(SESSION_ID, value.attributes[`xu-exp:${prop_name}`], paramsP.dsSessionP, 'UI Attr EXP');
33697
+ prop_val.value = res.result;
32961
33698
  }
33699
+ }
33700
+
33701
+ const plugin_runtime_src = await func.utils.get_plugin_npm_cdn(SESSION_ID, plugin_name, `${_plugin.manifest['runtime.mjs'].dist ? 'dist/' : ''}runtime.mjs`);
32962
33702
 
32963
- if (plugin_runtime_resources.fn) {
32964
- await plugin_runtime_resources.fn(plugin_name, $elm?.[0], properties);
32965
- // await plugin_runtime_resources.fn(plugin_name, $elm?.[0], $elm.data().xu_ui_plugin.properties);
33703
+ const plugin_runtime_resources = await import(plugin_runtime_src);
33704
+
33705
+ if (plugin_runtime_resources.cdn && _.isArray(plugin_runtime_resources.cdn)) {
33706
+ for (const resource of plugin_runtime_resources.cdn) {
33707
+ await load_cdn(resource);
32966
33708
  }
32967
33709
  }
32968
- }
32969
33710
 
33711
+ if (plugin_runtime_resources.fn) {
33712
+ await plugin_runtime_resources.fn(plugin_name, $elm?.[0], properties);
33713
+ }
33714
+ }
32970
33715
  return {};
32971
33716
  },
33717
+
32972
33718
  'xu-store': async function ($elm, val) {
32973
33719
  try {
32974
33720
  const fields_obj = JSON5.parse(val.value);
@@ -32980,43 +33726,135 @@ func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $
32980
33726
  }
32981
33727
  return {};
32982
33728
  },
33729
+
32983
33730
  'xu-viewport': async function ($elm, val) {
32984
- // functionality in draw_html_element
32985
33731
  return {};
32986
33732
  },
32987
33733
  };
32988
33734
 
32989
- if (nodeP.tagName.substr(0, 3) === 'xu-') {
33735
+ const tag_fx = {
33736
+ 'xu-panel': {
33737
+ program: async function ($elm, val) {
33738
+ const init_program = async function () {
33739
+ async function render_panel() {
33740
+ const prog_id = val.value?.prog || val.value;
33741
+ const params_obj = await get_params_obj_new(SESSION_ID, prog_id, nodeP, paramsP.dsSessionP);
33742
+ const ret_panel = await func.UI.screen.init(SESSION_ID, prog_id, paramsP.screenId, _ds, $elm, null, _ds.currentRecordId, null, true, params_obj.params_res, 'initXu_panel', undefined, prog_id !== _ds.prog_id ? null : refreshed_ds, params_obj.params_raw);
33743
+
33744
+ const containerData = $container.data();
33745
+ if (containerData.xuData) {
33746
+ containerData.xuData.xuPanelProps = elmData.xuAttributes;
33747
+ containerData.xuData.xuPanelData = ret_panel.data();
33748
+ }
33749
+ return { $new_div: ret_panel };
33750
+ }
33751
+
33752
+ if (!val.value) val.value = '_empty_panel_program';
33753
+ return await render_panel();
33754
+ };
33755
+
33756
+ const alter_program = async function () {
33757
+ async function render_panel() {
33758
+ const program = val.value?.prog || val.value;
33759
+ const $wrapper = $('<div>');
33760
+ const $div = await func.UI.screen.create_container(SESSION_ID, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, nodeP.attributes, null, null, null, $wrapper, '');
33761
+
33762
+ const params_obj = await get_params_obj_new(SESSION_ID, program, nodeP, paramsP.dsSessionP);
33763
+ const ret_init = await func.UI.screen.init(SESSION_ID, program, paramsP.screenId, _ds, $div, null, _ds.currentRecordId, jobNoP, true, params_obj.params_res, 'alterXu_panel', undefined, undefined, params_obj.params_raw);
33764
+
33765
+ await func.UI.screen.panel_post_render_handler(SESSION_ID, $elm, ret_init, nodeP, $div.clone(true), jobNoP);
33766
+
33767
+ return { $new_div: ret_init, abort: true };
33768
+ }
33769
+
33770
+ if (!val.value) return { abort: true };
33771
+ await render_panel();
33772
+ return { abort: true };
33773
+ };
33774
+
33775
+ return is_init ? await init_program() : await alter_program();
33776
+ },
33777
+
33778
+ 'xu-render': async function ($elm, val) {
33779
+ return await common_fx['xu-render']($elm, val, true);
33780
+ },
33781
+
33782
+ 'xu-ref': async function ($elm, val) {
33783
+ return await common_fx['xu-ref']($container, val, $container.data().xuData.xuPanelData.xuData.paramsP.dsSessionP);
33784
+ },
33785
+ },
33786
+
33787
+ 'xu-teleport': {
33788
+ to: async function ($elm, val) {
33789
+ if (!glb.new_xu_render && val.value) {
33790
+ if ($elm?.parent()?.data()?.xuData?.length) {
33791
+ $elm.parent().data('xuTeleportData', []);
33792
+ for (const [key, node] of Object.entries(nodeP.children)) {
33793
+ const $teleport_elm = await func.UI.screen.render_ui_tree(SESSION_ID, $(val.value), node, parent_infoP, paramsP, jobNoP, is_skeleton, Number(key), null, node, null, $root_container);
33794
+ $elm.parent().data().xuTeleportData.push($teleport_elm.attr('xu-ui-id'));
33795
+ $teleport_elm.attr('xu-teleport-parent-id', $elm.parent().attr('xu-ui-id'));
33796
+ }
33797
+ $elm.remove();
33798
+ } else {
33799
+ $elm.data('xuTeleportData', []).attr('hidden', true);
33800
+ for (const [key, node] of Object.entries(nodeP.children)) {
33801
+ const $to_container = $(val.value);
33802
+ if (!$to_container?.length) {
33803
+ return console.error(`container ${val.value} for xuTeleportData not found`);
33804
+ }
33805
+ const $teleport_elm = await func.UI.screen.render_ui_tree(SESSION_ID, $to_container, node, parent_infoP, paramsP, jobNoP, is_skeleton, Number(key), null, node, null, $root_container);
33806
+ $elm.data().xuTeleportData.push($teleport_elm.attr('xu-ui-id'));
33807
+ $teleport_elm.attr('xu-teleport-parent-id', $elm.attr('xu-ui-id'));
33808
+ }
33809
+ }
33810
+ return { abort: true };
33811
+ }
33812
+ return {};
33813
+ },
33814
+
33815
+ 'xu-render': async function ($elm, val) {
33816
+ return await common_fx['xu-render']($elm, val, true);
33817
+ },
33818
+
33819
+ 'xu-show': async function ($elm, val) {
33820
+ return await common_fx['xu-show']($elm, val, true);
33821
+ },
33822
+ },
33823
+ };
33824
+
33825
+ // Main execution logic
33826
+ if (isXuTag) {
32990
33827
  if (xu_func === 'xu-exp') {
32991
33828
  return common_fx[xu_func]($elm, val);
32992
33829
  }
32993
33830
 
32994
- if (tag_fx?.[nodeP.tagName]?.[xu_func]) {
32995
- let ret = await tag_fx[nodeP.tagName][xu_func]($elm, val);
32996
- return ret;
33831
+ if (tag_fx?.[nodeTag]?.[xu_func]) {
33832
+ return await tag_fx[nodeTag][xu_func]($elm, val);
32997
33833
  }
32998
- // if (xu_func !== "tree_id")
32999
- console.warn(`attribute ${xu_func} not found for ${nodeP.tagName}`);
33000
- return {};
33001
- }
33002
- if (_.isEmpty($elm.data())) {
33834
+
33835
+ console.warn(`attribute ${xu_func} not found for ${nodeTag}`);
33003
33836
  return {};
33004
33837
  }
33005
- if (!$elm.data().xuData.debug_info.attribute_stat) {
33006
- $elm.data().xuData.debug_info.attribute_stat = {};
33838
+
33839
+ if (_.isEmpty(elmData)) return {};
33840
+
33841
+ if (!xuData.debug_info.attribute_stat) {
33842
+ xuData.debug_info.attribute_stat = {};
33007
33843
  }
33844
+
33008
33845
  if (xu_func !== 'xu-exp') {
33009
- $elm.data().xuData.debug_info.attribute_stat[xu_func] = val.value;
33846
+ xuData.debug_info.attribute_stat[xu_func] = val.value;
33010
33847
  }
33848
+
33011
33849
  try {
33012
33850
  if (!common_fx[xu_func]) {
33013
- console.warn('invalid xu-tag', xu_func, error);
33851
+ console.warn('invalid xu-tag', xu_func);
33014
33852
  return {};
33015
33853
  }
33016
-
33017
33854
  return await common_fx[xu_func]($elm, val);
33018
33855
  } catch (error) {
33019
- debugger;
33856
+ console.error('execute_xu_functions error:', error);
33857
+ return {};
33020
33858
  }
33021
33859
  };
33022
33860
 
@@ -33644,162 +34482,312 @@ func.UI.screen.panel_post_render_handler = async function (
33644
34482
  return jobNoP;
33645
34483
  };
33646
34484
 
34485
+ // const generate_xu_ui_id = async function (SESSION_ID, nodeP, $container, paramsP, keyP) {
34486
+ // // const _paramsP = _.cloneDeep(paramsP);
34487
+ // const _paramsP = klona.klona(paramsP);
34488
+ // var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[_paramsP.dsSessionP];
34489
+
34490
+ // const currentRecordId = $container?.data?.()?.xuData?.recordid || (_ds ? _ds.currentRecordId : '');
34491
+ // const key_path = `${$container?.data()?.xuData?.key_path || '0'}-${keyP || '0'}`;
34492
+ // const elem_key = `${nodeP.xu_tree_id || nodeP.id}-${key_path}-${currentRecordId}`;
34493
+ // let ui_id = `${nodeP.id}-${elem_key}-${_paramsP?.dsSessionP?.toString() || ''}`; //nodeP.xu_tree_id ||
34494
+
34495
+ // const new_ui_id = await func.common.sha256(ui_id);
34496
+ // return new_ui_id;
34497
+ // };
34498
+
33647
34499
  const generate_xu_ui_id = async function (SESSION_ID, nodeP, $container, paramsP, keyP) {
33648
- // const _paramsP = _.cloneDeep(paramsP);
33649
- const _paramsP = klona.klona(paramsP);
33650
- var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[_paramsP.dsSessionP];
34500
+ // Avoid cloning if we only need dsSessionP
34501
+ const dsSessionP = paramsP.dsSessionP;
34502
+ const _ds = SESSION_OBJ[SESSION_ID].DS_GLB[dsSessionP];
34503
+
34504
+ // Cache container data access
34505
+ const containerXuData = $container?.data?.()?.xuData;
34506
+ const currentRecordId = containerXuData?.recordid || _ds?.currentRecordId || '';
33651
34507
 
33652
- const currentRecordId = $container?.data?.()?.xuData?.recordid || (_ds ? _ds.currentRecordId : '');
33653
- const key_path = `${$container?.data()?.xuData?.key_path || '0'}-${keyP || '0'}`;
33654
- const elem_key = `${nodeP.xu_tree_id || nodeP.id}-${key_path}-${currentRecordId}`;
33655
- let ui_id = `${nodeP.id}-${elem_key}-${_paramsP?.dsSessionP?.toString() || ''}`; //nodeP.xu_tree_id ||
34508
+ // Build strings efficiently
34509
+ const key_path = `${containerXuData?.key_path || '0'}-${keyP || '0'}`;
34510
+ const nodeId = nodeP.xu_tree_id || nodeP.id;
34511
+ const elem_key = `${nodeId}-${key_path}-${currentRecordId}`;
34512
+ const ui_id = `${nodeP.id}-${elem_key}-${dsSessionP?.toString() || ''}`;
33656
34513
 
33657
- const new_ui_id = await func.common.sha256(ui_id);
33658
- return new_ui_id;
34514
+ return await func.common.fastHash(ui_id);
33659
34515
  };
33660
34516
 
34517
+ // func.UI.screen.create_container = async function (SESSION_ID, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, prop, classP, elem_propP, div_typeP, $appendToP, attr_str, is_placeholder) {
34518
+ // // const _paramsP = _.cloneDeep(paramsP);
34519
+ // const _paramsP = klona.klona(paramsP);
34520
+ // var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[_paramsP.dsSessionP];
34521
+ // var $appendTo = $container;
34522
+ // if ($appendToP) $appendTo = $appendToP;
34523
+ // if (!$appendTo || !$appendTo.length) return null; // screen closed or not exist abort build
34524
+ // var div = 'div';
34525
+ // if (div_typeP) div = div_typeP;
34526
+ // var items = [];
34527
+ // if (nodeP.children)
34528
+ // items = nodeP.children.map(function (val) {
34529
+ // return val.xu_tree_id || val.id;
34530
+ // });
34531
+ // var currentRecordId = $container?.data?.()?.xuData?.recordid || (_ds ? _ds.currentRecordId : '');
34532
+ // // var xu_id = (glb.screen_num++).toString();
34533
+ // // xu_id = xu_id += '_' + currentRecordId;
34534
+
34535
+ // try {
34536
+ // const key_path = `${$container?.data()?.xuData?.key_path || '0'}-${keyP || '0'}`;
34537
+ // const elem_key = `${nodeP.xu_tree_id || nodeP.id}-${key_path}-${currentRecordId}`;
34538
+ // // let ui_id = `${nodeP.id}-${elem_key}-${_paramsP?.dsSessionP?.toString() || ''}`; //nodeP.xu_tree_id ||
34539
+
34540
+ // /////////////////////////////////
34541
+
34542
+ // var $div;
34543
+
34544
+ // if (div === 'svg') {
34545
+ // const draw_svg = function (element) {
34546
+ // const get_tag_str = function (element, prop, val) {
34547
+ // let class_str = '';
34548
+ // let attr_str = '';
34549
+ // for (const [key, val] of Object.entries(prop)) {
34550
+ // if (key.substr(0, 2) !== 'xu') {
34551
+ // attr_str += ` ${key}="${val}" `;
34552
+ // }
34553
+ // }
34554
+ // if (element === 'svg') {
34555
+ // return `<${element} ${attr_str} > `;
34556
+ // }
34557
+ // let ret = '';
34558
+ // if (val?.children?.length) {
34559
+ // ret = iterate_svg(val);
34560
+ // }
34561
+
34562
+ // return `<${element} ${class_str} ${attr_str} > ${ret} </${element}>`;
34563
+ // };
34564
+ // let svg_str = get_tag_str(element, prop);
34565
+ // let inner_str = '';
34566
+ // const iterate_svg = function (node) {
34567
+ // let ret = '';
34568
+ // if (node.children) {
34569
+ // for (let val of node.children) {
34570
+ // let prop = val.attributes;
34571
+ // ret += get_tag_str(val.tagName, prop, val);
34572
+ // }
34573
+ // }
34574
+ // return ret;
34575
+ // };
34576
+ // inner_str = iterate_svg(nodeP);
34577
+
34578
+ // $div = $(svg_str + inner_str + '</svg>').appendTo($appendTo);
34579
+ // };
34580
+
34581
+ // draw_svg(div_typeP);
34582
+ // } else {
34583
+ // $div = $(`<${div} ${attr_str ? attr_str : ''}>`);
34584
+ // }
34585
+
34586
+ // // // Returns a 32-bit unsigned integer hash of a string (FNV-1a)
34587
+ // // function hash32(str) {
34588
+ // // let h = 0x811c9dc5; // FNV offset basis
34589
+ // // for (let i = 0; i < str.length; i++) {
34590
+ // // h ^= str.charCodeAt(i);
34591
+ // // // multiply by FNV prime (2^24 + 2^8 + 0x93) with 32-bit overflow
34592
+ // // h += (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24);
34593
+ // // }
34594
+ // // // Convert to unsigned 32-bit
34595
+ // // return h >>> 0;
34596
+ // // }
34597
+
34598
+ // // function hash32hex(str) {
34599
+ // // return (hash32(str) >>> 0).toString(16).padStart(8, '0');
34600
+ // // }
34601
+
34602
+ // // const new_ui_id = hash32hex(ui_id);
34603
+ // // const new_ui_id = await func.common.sha256(ui_id);
34604
+ // const new_ui_id = await generate_xu_ui_id(SESSION_ID, nodeP, $container, paramsP, keyP);
34605
+
34606
+ // $div
34607
+ // .attr('xu-ui-id', new_ui_id)
34608
+ // // .attr('xu-node-id', nodeP.id)
34609
+ // .data({
34610
+ // xuData: {
34611
+ // prog_id: _paramsP.prog_id,
34612
+ // nodeid: nodeP.id,
34613
+ // ui_type: nodeP.tagName,
34614
+ // // xu_id,
34615
+ // recordid: currentRecordId,
34616
+ // paramsP: _paramsP,
34617
+ // key: keyP,
34618
+ // key_path, //:($container?.data()?.xuData?.key || "0") + "-" + (keyP || "0"),
34619
+ // screenId: _paramsP.screenId,
34620
+ // parent_container: $container?.attr('id'),
34621
+ // elem_key,
34622
+ // properties: prop,
34623
+ // node: nodeP,
34624
+ // node_org: _.cloneDeep(nodeP),
34625
+ // is_panelP: _paramsP.is_panelP,
34626
+ // ui_id: new_ui_id,
34627
+ // elem_prop: elem_propP,
34628
+ // debug_info: {
34629
+ // id: nodeP.id,
34630
+ // parent_id: $container?.data()?.xuData?.ui_id,
34631
+ // items: items,
34632
+ // },
34633
+ // parent_node: parent_nodeP,
34634
+ // currentRecordId: currentRecordId,
34635
+ // $root_container: $root_container,
34636
+ // parent_element_ui_id: $container?.data()?.xuData?.ui_id,
34637
+ // },
34638
+ // xuAttributes: {},
34639
+ // });
34640
+ // if (is_placeholder) {
34641
+ // $div.addClass('display_none');
34642
+ // }
34643
+
34644
+ // if (div_typeP !== 'svg') {
34645
+ // $div.appendTo($appendTo);
34646
+ // }
34647
+ // } catch (e) {
34648
+ // console.error(e);
34649
+ // }
34650
+
34651
+ // if (parent_infoP?.iterate_info) {
34652
+ // $div.data().xuData.iterate_info = parent_infoP.iterate_info;
34653
+ // }
34654
+
34655
+ // if (classP) $div.addClass(classP);
34656
+
34657
+ // return $div;
34658
+ // };
34659
+
33661
34660
  func.UI.screen.create_container = async function (SESSION_ID, $root_container, nodeP, $container, paramsP, parent_infoP, jobNoP, keyP, parent_nodeP, prop, classP, elem_propP, div_typeP, $appendToP, attr_str, is_placeholder) {
33662
- // const _paramsP = _.cloneDeep(paramsP);
33663
34661
  const _paramsP = klona.klona(paramsP);
33664
- var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[_paramsP.dsSessionP];
33665
- var $appendTo = $container;
33666
- if ($appendToP) $appendTo = $appendToP;
33667
- if (!$appendTo || !$appendTo.length) return null; // screen closed or not exist abort build
33668
- var div = 'div';
33669
- if (div_typeP) div = div_typeP;
33670
- var items = [];
33671
- if (nodeP.children)
33672
- items = nodeP.children.map(function (val) {
33673
- return val.xu_tree_id || val.id;
33674
- });
33675
- var currentRecordId = $container?.data?.()?.xuData?.recordid || (_ds ? _ds.currentRecordId : '');
33676
- // var xu_id = (glb.screen_num++).toString();
33677
- // xu_id = xu_id += '_' + currentRecordId;
34662
+ const _ds = SESSION_OBJ[SESSION_ID].DS_GLB[_paramsP.dsSessionP];
34663
+ const $appendTo = $appendToP || $container;
34664
+
34665
+ // Early exit if container doesn't exist
34666
+ if (!$appendTo?.length) return null;
34667
+
34668
+ const div = div_typeP || 'div';
34669
+
34670
+ // Cache container data to avoid repeated access
34671
+ const containerData = $container?.data?.();
34672
+ const containerXuData = containerData?.xuData;
34673
+ const currentRecordId = containerXuData?.recordid || (_ds ? _ds.currentRecordId : '');
34674
+
34675
+ // Pre-compute items array
34676
+ const items = nodeP.children ? nodeP.children.map((val) => val.xu_tree_id || val.id) : [];
33678
34677
 
33679
34678
  try {
33680
- const key_path = `${$container?.data()?.xuData?.key_path || '0'}-${keyP || '0'}`;
34679
+ const key_path = `${containerXuData?.key_path || '0'}-${keyP || '0'}`;
33681
34680
  const elem_key = `${nodeP.xu_tree_id || nodeP.id}-${key_path}-${currentRecordId}`;
33682
- // let ui_id = `${nodeP.id}-${elem_key}-${_paramsP?.dsSessionP?.toString() || ''}`; //nodeP.xu_tree_id ||
33683
-
33684
- /////////////////////////////////
33685
34681
 
33686
- var $div;
34682
+ let $div;
33687
34683
 
34684
+ // Handle SVG creation
33688
34685
  if (div === 'svg') {
33689
34686
  const draw_svg = function (element) {
33690
34687
  const get_tag_str = function (element, prop, val) {
33691
- let class_str = '';
33692
- let attr_str = '';
33693
- for (const [key, val] of Object.entries(prop)) {
33694
- if (key.substr(0, 2) !== 'xu') {
33695
- attr_str += ` ${key}="${val}" `;
34688
+ const attrs = [];
34689
+
34690
+ for (const [key, value] of Object.entries(prop)) {
34691
+ if (!key.startsWith('xu')) {
34692
+ attrs.push(`${key}="${value}"`);
33696
34693
  }
33697
34694
  }
34695
+
34696
+ const attr_str = attrs.join(' ');
34697
+
33698
34698
  if (element === 'svg') {
33699
- return `<${element} ${attr_str} > `;
33700
- }
33701
- let ret = '';
33702
- if (val?.children?.length) {
33703
- ret = iterate_svg(val);
34699
+ return `<${element} ${attr_str}>`;
33704
34700
  }
33705
34701
 
33706
- return `<${element} ${class_str} ${attr_str} > ${ret} </${element}>`;
34702
+ const inner = val?.children?.length ? iterate_svg(val) : '';
34703
+ return `<${element} ${attr_str}>${inner}</${element}>`;
33707
34704
  };
33708
- let svg_str = get_tag_str(element, prop);
33709
- let inner_str = '';
34705
+
33710
34706
  const iterate_svg = function (node) {
33711
- let ret = '';
33712
- if (node.children) {
33713
- for (let val of node.children) {
33714
- let prop = val.attributes;
33715
- ret += get_tag_str(val.tagName, prop, val);
33716
- }
33717
- }
33718
- return ret;
34707
+ if (!node.children) return '';
34708
+
34709
+ return node.children.map((val) => get_tag_str(val.tagName, val.attributes, val)).join('');
33719
34710
  };
33720
- inner_str = iterate_svg(nodeP);
34711
+
34712
+ const svg_str = get_tag_str(element, prop);
34713
+ const inner_str = iterate_svg(nodeP);
33721
34714
 
33722
34715
  $div = $(svg_str + inner_str + '</svg>').appendTo($appendTo);
33723
34716
  };
33724
34717
 
33725
34718
  draw_svg(div_typeP);
33726
34719
  } else {
33727
- $div = $(`<${div} ${attr_str ? attr_str : ''}>`);
34720
+ $div = $(`<${div}${attr_str ? ' ' + attr_str : ''}>`);
33728
34721
  }
33729
34722
 
33730
- // // Returns a 32-bit unsigned integer hash of a string (FNV-1a)
33731
- // function hash32(str) {
33732
- // let h = 0x811c9dc5; // FNV offset basis
33733
- // for (let i = 0; i < str.length; i++) {
33734
- // h ^= str.charCodeAt(i);
33735
- // // multiply by FNV prime (2^24 + 2^8 + 0x93) with 32-bit overflow
33736
- // h += (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24);
33737
- // }
33738
- // // Convert to unsigned 32-bit
33739
- // return h >>> 0;
33740
- // }
34723
+ // Generate UI ID
34724
+ const new_ui_id = await generate_xu_ui_id(SESSION_ID, nodeP, $container, paramsP, keyP);
33741
34725
 
33742
- // function hash32hex(str) {
33743
- // return (hash32(str) >>> 0).toString(16).padStart(8, '0');
33744
- // }
34726
+ // Set attributes and data in one go
34727
+ $div.attr('xu-ui-id', new_ui_id);
34728
+
34729
+ // Build xuData object efficiently
34730
+ const xuData = {
34731
+ prog_id: _paramsP.prog_id,
34732
+ nodeid: nodeP.id,
34733
+ ui_type: nodeP.tagName,
34734
+ recordid: currentRecordId,
34735
+ paramsP: _paramsP,
34736
+ key: keyP,
34737
+ key_path,
34738
+ screenId: _paramsP.screenId,
34739
+ parent_container: containerData?.id,
34740
+ elem_key,
34741
+ properties: prop,
34742
+ node: nodeP,
34743
+ node_org: _.cloneDeep(nodeP),
34744
+ is_panelP: _paramsP.is_panelP,
34745
+ ui_id: new_ui_id,
34746
+ elem_prop: elem_propP,
34747
+ debug_info: {
34748
+ id: nodeP.id,
34749
+ parent_id: containerXuData?.ui_id,
34750
+ items: items,
34751
+ },
34752
+ parent_node: parent_nodeP,
34753
+ currentRecordId: currentRecordId,
34754
+ $root_container: $root_container,
34755
+ parent_element_ui_id: containerXuData?.ui_id,
34756
+ };
33745
34757
 
33746
- // const new_ui_id = hash32hex(ui_id);
33747
- // const new_ui_id = await func.common.sha256(ui_id);
33748
- const new_ui_id = await generate_xu_ui_id(SESSION_ID, nodeP, $container, paramsP, keyP);
34758
+ // Add iterate_info if present
34759
+ if (parent_infoP?.iterate_info) {
34760
+ xuData.iterate_info = parent_infoP.iterate_info;
34761
+ }
33749
34762
 
33750
- $div
33751
- .attr('xu-ui-id', new_ui_id)
33752
- // .attr('xu-node-id', nodeP.id)
33753
- .data({
33754
- xuData: {
33755
- prog_id: _paramsP.prog_id,
33756
- nodeid: nodeP.id,
33757
- ui_type: nodeP.tagName,
33758
- // xu_id,
33759
- recordid: currentRecordId,
33760
- paramsP: _paramsP,
33761
- key: keyP,
33762
- key_path, //:($container?.data()?.xuData?.key || "0") + "-" + (keyP || "0"),
33763
- screenId: _paramsP.screenId,
33764
- parent_container: $container?.attr('id'),
33765
- elem_key,
33766
- properties: prop,
33767
- node: nodeP,
33768
- node_org: _.cloneDeep(nodeP),
33769
- is_panelP: _paramsP.is_panelP,
33770
- ui_id: new_ui_id,
33771
- elem_prop: elem_propP,
33772
- debug_info: {
33773
- id: nodeP.id,
33774
- parent_id: $container?.data()?.xuData?.ui_id,
33775
- items: items,
33776
- },
33777
- parent_node: parent_nodeP,
33778
- currentRecordId: currentRecordId,
33779
- $root_container: $root_container,
33780
- parent_element_ui_id: $container?.data()?.xuData?.ui_id,
33781
- },
33782
- xuAttributes: {},
33783
- });
34763
+ // Set data once
34764
+ $div.data({
34765
+ xuData: xuData,
34766
+ xuAttributes: {},
34767
+ });
34768
+
34769
+ // Apply placeholder class if needed
33784
34770
  if (is_placeholder) {
33785
34771
  $div.addClass('display_none');
33786
34772
  }
33787
34773
 
34774
+ // Apply custom class if provided
34775
+ if (classP) {
34776
+ $div.addClass(classP);
34777
+ }
34778
+
34779
+ // Append to DOM (only for non-SVG elements)
33788
34780
  if (div_typeP !== 'svg') {
33789
34781
  $div.appendTo($appendTo);
33790
34782
  }
33791
- } catch (e) {
33792
- console.error(e);
33793
- }
33794
34783
 
33795
- if (parent_infoP?.iterate_info) {
33796
- $div.data().xuData.iterate_info = parent_infoP.iterate_info;
34784
+ return $div;
34785
+ } catch (e) {
34786
+ console.error('create_container error:', e);
34787
+ return null;
33797
34788
  }
33798
-
33799
- if (classP) $div.addClass(classP);
33800
-
33801
- return $div;
33802
34789
  };
34790
+
33803
34791
  func.UI.screen.execute_screen_ready_events = async function (SESSION_ID, paramsP, sourceP, $div, jobNoP, $div_objP) {
33804
34792
  var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP];
33805
34793
  if (!_ds) return;