@xuda.io/runtime-bundle 1.0.1248 → 1.0.1249

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.
@@ -12164,278 +12164,1203 @@ const get_params_obj_new = async function (SESSION_ID, prog_id, nodeP, dsSession
12164
12164
  return { params_res, params_raw };
12165
12165
  };
12166
12166
 
12167
- 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) {
12168
- if (is_skeleton) return;
12167
+ // 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) {
12168
+ // if (is_skeleton) return;
12169
+
12170
+ // // console.log(nodeP.id, xu_func, val);
12171
+ // var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP];
12172
+ // const tag_fx = {
12173
+ // [`xu-panel`]: {
12174
+ // program: async function ($elm, val) {
12175
+ // var ret = {};
12176
+ // var _session = SESSION_OBJ[SESSION_ID];
12177
+ // var _ds = _session.DS_GLB[paramsP.dsSessionP];
12178
+ // const init_program = async function () {
12179
+ // async function render_panel() {
12180
+ // const prog_id = val.value?.prog || val.value;
12181
+ // const params_obj = await get_params_obj_new(SESSION_ID, prog_id, nodeP, paramsP.dsSessionP);
12182
+ // 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);
12183
+ // ret = { $new_div: ret_panel };
12184
+ // if ($container.data().xuData) {
12185
+ // $container.data().xuData.xuPanelProps = $elm.data().xuAttributes;
12186
+ // $container.data().xuData.xuPanelData = ret_panel.data();
12187
+ // }
12188
+ // return ret;
12189
+ // }
12169
12190
 
12170
- // console.log(nodeP.id, xu_func, val);
12171
- var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP];
12172
- const tag_fx = {
12173
- [`xu-panel`]: {
12174
- program: async function ($elm, val) {
12175
- var ret = {};
12176
- var _session = SESSION_OBJ[SESSION_ID];
12177
- var _ds = _session.DS_GLB[paramsP.dsSessionP];
12178
- const init_program = async function () {
12179
- async function render_panel() {
12180
- const prog_id = val.value?.prog || val.value;
12181
- const params_obj = await get_params_obj_new(SESSION_ID, prog_id, nodeP, paramsP.dsSessionP);
12182
- 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);
12183
- ret = { $new_div: ret_panel };
12184
- if ($container.data().xuData) {
12185
- $container.data().xuData.xuPanelProps = $elm.data().xuAttributes;
12186
- $container.data().xuData.xuPanelData = ret_panel.data();
12187
- }
12188
- return ret;
12189
- }
12191
+ // if (!val.value) {
12192
+ // val.value = '_empty_panel_program';
12193
+ // }
12190
12194
 
12191
- if (!val.value) {
12192
- val.value = '_empty_panel_program';
12193
- }
12195
+ // ret = await render_panel();
12194
12196
 
12195
- ret = await render_panel();
12197
+ // return ret;
12198
+ // };
12199
+ // const alter_program = async function () {
12200
+ // var _session = SESSION_OBJ[SESSION_ID];
12201
+ // var _ds = _session.DS_GLB[paramsP.dsSessionP];
12202
+
12203
+ // /////////////////
12204
+ // async function render_panel() {
12205
+ // // // if (!cache_str) {
12206
+ // // // await update_container(screen_ready_function);
12207
+ // // // }
12208
+ // // // if (cache_str && !CACHE_PROG_UI[cache_str]) {
12209
+ // // // await update_container(screen_ready_function);
12210
+ // // // save_cache();
12211
+ // // // }
12212
+ // // // if (callback) callback($div);
12213
+ // // // $container.data().xuData.node.children =
12214
+ // // // $div.data().xuData.node.children;
12215
+ // // // //swiper-wrapper
12216
+ // // // var restore_slides_elements = async function () {
12217
+ // // // if ($tmp_div.children().length) {
12218
+ // // // $tmp_div
12219
+ // // // .find(".swiper-wrapper")
12220
+ // // // .empty()
12221
+ // // // .append($new_div.children());
12222
+ // // // $new_div.append($tmp_div.children());
12223
+ // // // }
12224
+ // // // };
12225
+ // // // // console.log($tmp_div);
12226
+ // // // await restore_slides_elements();
12227
+ // // // // CHANGE_PANEL_BUSY = false;
12228
+ // // // func.events.delete_job(SESSION_ID, jobNo);
12229
+ // // };
12230
+ // const program = val.value?.prog || val.value;
12231
+ // var $wrapper = $('<div>');
12232
+ // 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, '');
12233
+ // const params_obj = await get_params_obj_new(SESSION_ID, program, nodeP, paramsP.dsSessionP);
12234
+ // 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);
12235
+ // ret = {
12236
+ // $new_div: ret_init,
12237
+ // abort: true,
12238
+ // };
12239
+ // await func.UI.screen.panel_post_render_handler(SESSION_ID, $elm, $new_div, nodeP, $div.clone(true), jobNoP);
12240
+
12241
+ // return ret;
12242
+ // }
12243
+ // if (!val.value) {
12244
+ // return { abort: true };
12245
+ // }
12246
+ // await render_panel();
12247
+ // return ret;
12248
+ // };
12196
12249
 
12197
- return ret;
12198
- };
12199
- const alter_program = async function () {
12200
- var _session = SESSION_OBJ[SESSION_ID];
12201
- var _ds = _session.DS_GLB[paramsP.dsSessionP];
12250
+ // if (is_init) {
12251
+ // let ret = await init_program();
12252
+ // return ret;
12253
+ // }
12254
+ // return alter_program();
12255
+ // },
12202
12256
 
12203
- /////////////////
12204
- async function render_panel() {
12205
- // // if (!cache_str) {
12206
- // // await update_container(screen_ready_function);
12207
- // // }
12208
- // // if (cache_str && !CACHE_PROG_UI[cache_str]) {
12209
- // // await update_container(screen_ready_function);
12210
- // // save_cache();
12211
- // // }
12212
- // // if (callback) callback($div);
12213
- // // $container.data().xuData.node.children =
12214
- // // $div.data().xuData.node.children;
12215
- // // //swiper-wrapper
12216
- // // var restore_slides_elements = async function () {
12217
- // // if ($tmp_div.children().length) {
12218
- // // $tmp_div
12219
- // // .find(".swiper-wrapper")
12220
- // // .empty()
12221
- // // .append($new_div.children());
12222
- // // $new_div.append($tmp_div.children());
12223
- // // }
12224
- // // };
12225
- // // // console.log($tmp_div);
12226
- // // await restore_slides_elements();
12227
- // // // CHANGE_PANEL_BUSY = false;
12228
- // // func.events.delete_job(SESSION_ID, jobNo);
12229
- // };
12230
- const program = val.value?.prog || val.value;
12231
- var $wrapper = $('<div>');
12232
- 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, '');
12233
- const params_obj = await get_params_obj_new(SESSION_ID, program, nodeP, paramsP.dsSessionP);
12234
- 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);
12235
- ret = {
12236
- $new_div: ret_init,
12237
- abort: true,
12238
- };
12239
- await func.UI.screen.panel_post_render_handler(SESSION_ID, $elm, $new_div, nodeP, $div.clone(true), jobNoP);
12257
+ // 'xu-render': async function ($elm, val) {
12258
+ // let ret = await common_fx['xu-render']($elm, val, true);
12259
+ // return ret;
12260
+ // },
12261
+ // 'xu-ref': async function ($elm, val) {
12262
+ // let ret = await common_fx['xu-ref']($container, val, $container.data().xuData.xuPanelData.xuData.paramsP.dsSessionP);
12263
+ // return ret;
12264
+ // },
12265
+ // },
12266
+ // [`xu-teleport`]: {
12267
+ // to: async function ($elm, val) {
12268
+ // if (!glb.new_xu_render) {
12269
+ // if (val.value) {
12270
+ // // parent_infoP.is_xu_teleport;
12271
+ // if ($elm?.parent()?.data()?.xuData?.length) {
12272
+ // $elm.parent().data('xuTeleportData', []);
12273
+ // for (const [key, node] of Object.entries(nodeP.children)) {
12274
+ // 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);
12275
+
12276
+ // $elm.parent().data().xuTeleportData.push($teleport_elm.attr('xu-ui-id'));
12277
+ // $teleport_elm.attr('xu-teleport-parent-id', $elm.parent().attr('xu-ui-id'));
12278
+ // }
12279
+ // $elm.remove();
12280
+ // } else {
12281
+ // $elm.data('xuTeleportData', []).attr('hidden', true);
12282
+ // for (const [key, node] of Object.entries(nodeP.children)) {
12283
+ // const $to_container = $(val.value);
12284
+ // if (!$to_container?.length) {
12285
+ // return console.error(`container ${val.value} for xuTeleportData not found`);
12286
+ // }
12287
+ // 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);
12288
+
12289
+ // $elm.data().xuTeleportData.push($teleport_elm.attr('xu-ui-id'));
12290
+ // $teleport_elm.attr('xu-teleport-parent-id', $elm.attr('xu-ui-id'));
12291
+ // }
12292
+ // }
12293
+ // }
12294
+ // return { abort: true };
12295
+ // }
12240
12296
 
12241
- return ret;
12242
- }
12243
- if (!val.value) {
12244
- return { abort: true };
12245
- }
12246
- await render_panel();
12247
- return ret;
12248
- };
12297
+ // if (val.value) {
12298
+ // // // parent_infoP.is_xu_teleport;
12299
+ // // if ($elm?.parent()?.data()?.xuData?.length) {
12300
+ // // $elm.parent().data('xuTeleportData', []);
12301
+ // // for (const [key, node] of Object.entries(nodeP.children)) {
12302
+ // // 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);
12303
+ // // $elm.parent().data().xuTeleportData.push($teleport_elm.attr('xu-ui-id'));
12304
+ // // $teleport_elm.attr('xu-teleport-parent-id', $elm.parent().attr('xu-ui-id'));
12305
+ // // }
12306
+ // // $elm.remove();
12307
+ // // } else {
12308
+ // // $elm.data('xuTeleportData', []).attr('hidden', true);
12309
+ // // for (const [key, node] of Object.entries(nodeP.children)) {
12310
+ // // const $to_container = $(val.value);
12311
+ // // if (!$to_container?.length) {
12312
+ // // return console.error(`container ${val.value} for xuTeleportData not found`);
12313
+ // // }
12314
+ // // 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);
12315
+ // // $elm.data().xuTeleportData.push($teleport_elm.attr('xu-ui-id'));
12316
+ // // $teleport_elm.attr('xu-teleport-parent-id', $elm.attr('xu-ui-id'));
12317
+ // // }
12318
+ // // }
12319
+ // }
12320
+ // return {};
12321
+ // },
12322
+ // 'xu-render': async function ($elm, val) {
12323
+ // let ret = await common_fx['xu-render']($elm, val, true);
12324
+ // return ret;
12325
+ // },
12326
+ // 'xu-show': async function ($elm, val) {
12327
+ // let ret = await common_fx['xu-show']($elm, val, true);
12328
+ // return ret;
12329
+ // },
12330
+ // },
12331
+ // };
12249
12332
 
12250
- if (is_init) {
12251
- let ret = await init_program();
12252
- return ret;
12253
- }
12254
- return alter_program();
12255
- },
12333
+ // const load_cdn = async function (resource) {
12334
+ // // console.log("loading cdn", resource);
12335
+ // if (!_.isObject(resource) && _.isString(resource)) {
12336
+ // resource = { src: resource, type: 'js' };
12337
+ // }
12338
+ // if (!_.isObject(resource)) {
12339
+ // throw new Error('cdn resource in wrong format');
12340
+ // }
12341
+ // return new Promise(async (resolve) => {
12342
+ // try {
12343
+ // switch (resource.type) {
12344
+ // case 'js':
12345
+ // await func.utils.load_js_on_demand(resource.src);
12346
+ // break;
12347
+ // case 'css':
12348
+ // await func.utils.load_js_on_demand(resource.src);
12349
+ // break;
12350
+ // case 'module':
12351
+ // func.utils.load_js_on_demand(resource.src, 'module');
12352
+ // break;
12353
+
12354
+ // default:
12355
+ // await func.utils.load_js_on_demand(resource.src);
12356
+ // break;
12357
+ // }
12358
+ // resolve();
12359
+ // } catch (error) {
12360
+ // func.utils.debug_report(SESSION_ID, 'xu-cdn', 'Fail to load: ' + resource, 'W');
12361
+ // resolve();
12362
+ // }
12256
12363
 
12257
- 'xu-render': async function ($elm, val) {
12258
- let ret = await common_fx['xu-render']($elm, val, true);
12259
- return ret;
12260
- },
12261
- 'xu-ref': async function ($elm, val) {
12262
- let ret = await common_fx['xu-ref']($container, val, $container.data().xuData.xuPanelData.xuData.paramsP.dsSessionP);
12263
- return ret;
12264
- },
12265
- },
12266
- [`xu-teleport`]: {
12267
- to: async function ($elm, val) {
12268
- if (!glb.new_xu_render) {
12269
- if (val.value) {
12270
- // parent_infoP.is_xu_teleport;
12271
- if ($elm?.parent()?.data()?.xuData?.length) {
12272
- $elm.parent().data('xuTeleportData', []);
12273
- for (const [key, node] of Object.entries(nodeP.children)) {
12274
- 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);
12275
-
12276
- $elm.parent().data().xuTeleportData.push($teleport_elm.attr('xu-ui-id'));
12277
- $teleport_elm.attr('xu-teleport-parent-id', $elm.parent().attr('xu-ui-id'));
12278
- }
12279
- $elm.remove();
12280
- } else {
12281
- $elm.data('xuTeleportData', []).attr('hidden', true);
12282
- for (const [key, node] of Object.entries(nodeP.children)) {
12283
- const $to_container = $(val.value);
12284
- if (!$to_container?.length) {
12285
- return console.error(`container ${val.value} for xuTeleportData not found`);
12286
- }
12287
- 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);
12364
+ // // if (resource.type === "js" || !resource.type) {
12365
+ // // await func.utils.load_js_on_demand(resource.src);
12366
+ // // return resolve();
12367
+ // // }
12368
+ // // if (resource.type === "css") {
12369
+ // // func.utils.load_css_on_demand(resource.src);
12370
+ // // return resolve();
12371
+ // // }
12372
+ // // if (resource.type === "module") {
12373
+ // // func.utils.load_js_on_demand(resource.src, "module");
12374
+ // // return resolve();
12375
+ // // }
12376
+ // // func.utils.debug_report(
12377
+ // // SESSION_ID,
12378
+ // // "xu-cdn",
12379
+ // // "Fail to load: " + resource,
12380
+ // // "W"
12381
+ // // );
12382
+ // // return resolve();
12383
+ // });
12384
+ // };
12288
12385
 
12289
- $elm.data().xuTeleportData.push($teleport_elm.attr('xu-ui-id'));
12290
- $teleport_elm.attr('xu-teleport-parent-id', $elm.attr('xu-ui-id'));
12291
- }
12292
- }
12293
- }
12294
- return { abort: true };
12295
- }
12386
+ // const common_fx = {
12387
+ // 'xu-attrs': async function ($elm, val) {
12388
+ // if (!val.value) return {};
12389
+ // if (!_.isObject(val.value)) throw 'xu-attrs value us not an object';
12390
+ // for (const [attr_key, attr_val] of Object.entries(val.value)) {
12391
+ // nodeP.attributes[attr_key] = attr_val;
12392
+ // }
12296
12393
 
12297
- if (val.value) {
12298
- // // parent_infoP.is_xu_teleport;
12299
- // if ($elm?.parent()?.data()?.xuData?.length) {
12300
- // $elm.parent().data('xuTeleportData', []);
12301
- // for (const [key, node] of Object.entries(nodeP.children)) {
12302
- // 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);
12303
- // $elm.parent().data().xuTeleportData.push($teleport_elm.attr('xu-ui-id'));
12304
- // $teleport_elm.attr('xu-teleport-parent-id', $elm.parent().attr('xu-ui-id'));
12305
- // }
12306
- // $elm.remove();
12307
- // } else {
12308
- // $elm.data('xuTeleportData', []).attr('hidden', true);
12309
- // for (const [key, node] of Object.entries(nodeP.children)) {
12310
- // const $to_container = $(val.value);
12311
- // if (!$to_container?.length) {
12312
- // return console.error(`container ${val.value} for xuTeleportData not found`);
12313
- // }
12314
- // 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);
12315
- // $elm.data().xuTeleportData.push($teleport_elm.attr('xu-ui-id'));
12316
- // $teleport_elm.attr('xu-teleport-parent-id', $elm.attr('xu-ui-id'));
12317
- // }
12318
- // }
12319
- }
12320
- return {};
12321
- },
12322
- 'xu-render': async function ($elm, val) {
12323
- let ret = await common_fx['xu-render']($elm, val, true);
12324
- return ret;
12325
- },
12326
- 'xu-show': async function ($elm, val) {
12327
- let ret = await common_fx['xu-show']($elm, val, true);
12328
- return ret;
12329
- },
12330
- },
12331
- };
12394
+ // return {};
12395
+ // },
12396
+ // 'xu-ref': async function ($elm, val, dsSession) {
12397
+ // if (!val.value) return {};
12398
+
12399
+ // func.UI.update_xu_ref(SESSION_ID, dsSession || paramsP.dsSessionP, val.value, $elm);
12400
+
12401
+ // // Select the node that will be observed for mutations
12402
+ // const targetNode = $elm[0];
12403
+
12404
+ // if (!targetNode) return;
12405
+
12406
+ // // Options for the observer (which mutations to observe)
12407
+ // const config = { attributes: true, childList: true, subtree: true };
12408
+
12409
+ // // Callback function to execute when mutations are observed
12410
+ // const callback = (mutationList, observer) => {
12411
+ // func.UI.screen.refresh_xu_attributes(SESSION_ID, [val.value]);
12412
+ // };
12413
+
12414
+ // // Create an observer instance linked to the callback function
12415
+ // const observer = new MutationObserver(callback);
12416
+
12417
+ // // Start observing the target node for configured mutations
12418
+ // observer.observe(targetNode, config);
12419
+
12420
+ // // Later, you can stop observing
12421
+ // // observer.disconnect();
12422
+
12423
+ // return {};
12424
+ // },
12425
+ // 'xu-bind': async function ($elm, val) {
12426
+ // if (is_skeleton) return;
12427
+
12428
+ // let val_is_reference_field = false;
12429
+
12430
+ // let _prog_id = $elm.data().xuData.paramsP.prog_id;
12431
+ // let _dsP = $elm.data().xuData.paramsP.dsSessionP;
12432
+ // const view_ret = await func.utils.VIEWS_OBJ.get(SESSION_ID, _prog_id);
12433
+ // if (!view_ret) return {};
12434
+
12435
+ // let is_dynamic_field = false;
12436
+ // let field_prop;
12437
+ // let bind_field_id;
12438
+
12439
+ // const input_field_type = $elm.attr('type');
12440
+
12441
+ // const get_bind_field = async function (field_id) {
12442
+ // if (['_FOR_VAL', '_FOR_KEY'].includes(field_id)) {
12443
+ // is_dynamic_field = true;
12444
+ // field_prop = _ds.dynamic_fields[field_id];
12445
+ // } else {
12446
+ // field_prop = func.common.find_item_by_key(view_ret.progFields, 'field_id', field_id);
12447
+ // if (!field_prop) {
12448
+ // /// find the field everywhere in the chain Aug 30 2024
12449
+ // const ret_get_value = await func.datasource.get_value(SESSION_ID, field_id, _dsP);
12450
+
12451
+ // if (ret_get_value.found) {
12452
+ // _dsP = ret_get_value.dsSessionP;
12453
+ // let _ds = SESSION_OBJ[SESSION_ID].DS_GLB[_dsP];
12454
+ // _prog_id = _ds.prog_id;
12455
+ // const view_ret = await func.utils.VIEWS_OBJ.get(SESSION_ID, _prog_id);
12456
+ // if (!view_ret) return {};
12457
+ // field_prop = func.common.find_item_by_key(view_ret.progFields, 'field_id', field_id);
12458
+ // }
12459
+ // if (!field_prop) {
12460
+ // throw `field ${field_id} not found in the program scope`;
12461
+ // }
12462
+ // }
12463
+ // }
12464
+ // return field_id;
12465
+ // };
12466
+
12467
+ // try {
12468
+ // bind_field_id = await get_bind_field(val.value.split('.')[0]);
12469
+ // val_is_reference_field = true;
12470
+ // } catch (err) {
12471
+ // console.error(err?.message || err);
12472
+ // return {};
12473
+ // }
12474
+
12475
+ // const field_changed = async function (e) {
12476
+ // var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[_dsP];
12477
+
12478
+ // // update array for checkbox that not in xu-for
12479
+ // if (field_prop.props.fieldType === 'array' && input_field_type === 'checkbox' && val_is_reference_field) {
12480
+ // let arr_value_before_cast = _.clone((await func.datasource.get_value(SESSION_ID, bind_field_id, _dsP, _ds.currentRecordId)).ret.value);
12481
+ // let value_from_getter = bind.getter($elm[0]);
12482
+ // let value;
12483
+ // if (arr_value_before_cast.includes(value_from_getter)) {
12484
+ // value = arr_value_before_cast.filter((item) => !_.isEqual(item, value_from_getter));
12485
+ // } else {
12486
+ // arr_value_before_cast.push(value_from_getter);
12487
+ // value = arr_value_before_cast;
12488
+ // }
12489
+
12490
+ // let datasource_changes = {
12491
+ // [_dsP]: {
12492
+ // [_ds.currentRecordId]: {
12493
+ // [bind_field_id]: value,
12494
+ // },
12495
+ // },
12496
+ // };
12497
+
12498
+ // return await func.datasource.update(SESSION_ID, datasource_changes);
12499
+ // }
12500
+
12501
+ // // update array for radio that not in xu-for
12502
+ // if (field_prop.props.fieldType === 'array' && input_field_type === 'radio' && val_is_reference_field) {
12503
+ // let value_from_getter = bind.getter($elm[0]);
12504
+
12505
+ // let datasource_changes = {
12506
+ // [_dsP]: {
12507
+ // [_ds.currentRecordId]: {
12508
+ // [bind_field_id]: [value_from_getter],
12509
+ // },
12510
+ // },
12511
+ // };
12512
+
12513
+ // return await func.datasource.update(SESSION_ID, datasource_changes);
12514
+ // }
12515
+
12516
+ // var value = await func.common.get_cast_val(SESSION_ID, 'xu-bind', 'value', field_prop.props.fieldType, bind.getter($elm[0]));
12517
+
12518
+ // if (field_prop.props.fieldType === 'object') {
12519
+ // value = await func.common.get_cast_val(SESSION_ID, 'xu-bind', 'value', input_field_type, bind.getter($elm[0]));
12520
+ // }
12521
+
12522
+ // if (!_ds.currentRecordId) return;
12523
+
12524
+ // let datasource_changes = {
12525
+ // [_dsP]: {
12526
+ // [_ds.currentRecordId]: {
12527
+ // [bind_field_id]: value,
12528
+ // },
12529
+ // },
12530
+ // };
12531
+
12532
+ // await func.datasource.update(SESSION_ID, datasource_changes);
12533
+ // const iterate_info = $elm?.data()?.xuData?.iterate_info;
12534
+ // const reference_source_obj = iterate_info?.reference_source_obj;
12535
+ // if (reference_source_obj) {
12536
+ // if (reference_source_obj.ret.type === 'array') {
12537
+ // if (iterate_info.iterator_val === bind_field_id) {
12538
+ // const arr_idx = Number($elm?.data()?.xuData?.iterate_info._key);
12539
+
12540
+ // const dataset_arr = await func.datasource.get_value(SESSION_ID, reference_source_obj.fieldIdP, _dsP, reference_source_obj.currentRecordId);
12541
+ // let new_arr = _.cloneDeep(dataset_arr.ret.value);
12542
+
12543
+ // if (field_prop.props.fieldType === 'object' && val_is_reference_field) {
12544
+ // let obj_item = new_arr[arr_idx];
12545
+
12546
+ // let e_exp = val.value.replace(bind_field_id, 'obj_item');
12547
+
12548
+ // let new_val = eval(e_exp + (input_field_type === 'string' ? `="${value}"` : `=${value}`));
12549
+
12550
+ // new_arr[arr_idx] = obj_item;
12551
+ // } else {
12552
+ // new_arr[arr_idx] = value;
12553
+ // }
12554
+ // // datasource_changes[_dsP][_ds.currentRecordId][reference_source_obj.fieldIdP] = new_arr;
12555
+
12556
+ // let datasource_changes = {
12557
+ // [_dsP]: {
12558
+ // [_ds.currentRecordId]: {
12559
+ // [reference_source_obj.fieldIdP]: new_arr,
12560
+ // },
12561
+ // },
12562
+ // };
12563
+
12564
+ // await func.datasource.update(SESSION_ID, datasource_changes, null, true);
12565
+ // }
12566
+ // }
12567
+ // }
12568
+
12569
+ // await func.datasource.update_changes_for_out_parameter(SESSION_ID, _dsP, _ds.parentDataSourceNo);
12570
+ // };
12571
+
12572
+ // const bind = new UI_FRAMEWORK_PLUGIN.bind();
12573
+
12574
+ // bind.listener($elm[0], field_changed);
12575
+
12576
+ // const set_value = function () {
12577
+ // let _ds = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP];
12578
+ // if (!_ds.currentRecordId) return;
12579
+ // let value;
12580
+ // try {
12581
+ // if (val_is_reference_field) {
12582
+ // if (is_dynamic_field) {
12583
+ // value = _ds.dynamic_fields[bind_field_id].value;
12584
+ // } else {
12585
+ // const row_idx = func.common.find_ROWID_idx(_ds, _ds.currentRecordId);
12586
+ // value = _ds.data_feed.rows?.[row_idx]?.[bind_field_id];
12587
+ // }
12588
+ // if (field_prop.props.fieldType === 'array' && $elm.attr('type') === 'checkbox' && $elm.attr('value')) {
12589
+ // if (value.includes($elm.attr('value'))) {
12590
+ // value = true;
12591
+ // } else {
12592
+ // value = false;
12593
+ // }
12594
+ // } else if (field_prop.props.fieldType === 'array' && $elm.attr('type') === 'radio' && $elm.attr('value')) {
12595
+ // if (value.includes($elm.attr('value'))) {
12596
+ // value = $elm.attr('value');
12597
+ // } else {
12598
+ // value = false;
12599
+ // }
12600
+ // } else if (field_prop.props.fieldType === 'object' && val.value.split('.').length > 1) {
12601
+ // let str = val.value.replace(bind_field_id, '(' + JSON.stringify(value) + ')');
12602
+ // value = eval(str);
12603
+ // }
12604
+ // } else {
12605
+ // value = val.value;
12606
+ // }
12607
+ // if (typeof value === 'undefined') return;
12608
+ // bind.setter($elm[0], value);
12609
+ // } catch (err) {
12610
+ // console.error(err);
12611
+ // }
12612
+ // };
12613
+ // /// init value from ds
12614
+ // $('body').on('xu-bind-refresh.' + _ds.dsSession.toString(), () => {
12615
+ // set_value();
12616
+ // });
12617
+
12618
+ // set_value();
12619
+ // return {};
12620
+ // },
12621
+ // 'xu-render': async function ($elm, val, from_panel) {
12622
+ // const old_render = async function () {
12623
+ // var value = await func.common.get_cast_val(SESSION_ID, 'common fx', 'xu-render', 'bool', val.value);
12624
+ // const init_render = function () {
12625
+ // if (!value) {
12626
+ // var cloned_$div = $elm.clone(true);
12627
+
12628
+ // let $xurender = $('<xurender>').attr('xu-ui-id', $elm.attr('xu-ui-id')).attr('hidden', true).appendTo($container); //.hide();
12629
+ // let original_data_obj = {
12630
+ // $container: cloned_$div,
12631
+ // nodeP: _.cloneDeep(nodeP),
12632
+ // parent_infoP,
12633
+ // paramsP,
12634
+ // keyP,
12635
+ // parent_nodeP,
12636
+ // $root_container,
12637
+ // };
12638
+ // $xurender.data('xuData', cloned_$div.data().xuData);
12639
+ // $xurender.data().xuData.original_data_obj = original_data_obj;
12640
+ // $xurender.data().xuData.xurender_node = cloned_$div;
12641
+ // $xurender.data().xuAttributes = nodeP.attributes || {};
12642
+ // // $xurender.hide();
12643
+
12644
+ // $elm.remove();
12645
+ // return { abort: true };
12646
+ // }
12647
+ // return {};
12648
+ // };
12649
+
12650
+ // const post_render = async function () {
12651
+ // if (value) {
12652
+ // try {
12653
+ // // abort if already rended
12654
+ // if ($elm[0].tagName !== 'XURENDER' && $elm?.length) {
12655
+ // return func.events.delete_job(SESSION_ID, jobNoP);
12656
+ // }
12657
+
12658
+ // let original_data_obj = $elm.data().xuData.original_data_obj;
12659
+
12660
+ // if (!original_data_obj) {
12661
+ // func.events.delete_job(SESSION_ID, jobNoP);
12662
+ // return { delete_job: jobNoP };
12663
+ // }
12664
+
12665
+ // const new_$div = await func.UI.screen.render_ui_tree(
12666
+ // SESSION_ID,
12667
+ // $elm, //original_data_obj.$container,
12668
+ // _.cloneDeep(original_data_obj.nodeP),
12669
+ // original_data_obj.parent_infoP,
12670
+ // original_data_obj.paramsP,
12671
+ // jobNoP,
12672
+ // null,
12673
+ // original_data_obj.keyP,
12674
+ // null,
12675
+ // original_data_obj.parent_nodeP,
12676
+ // null,
12677
+ // original_data_obj.$root_container,
12678
+ // );
12679
+
12680
+ // new_$div.data().xuData.original_data_obj = original_data_obj;
12681
+ // new_$div.data().xuData.xurender_node = $elm.clone(true);
12682
+ // new_$div.data().xuAttributes = $elm.data().xuAttributes || {};
12683
+
12684
+ // const replace = async function () {
12685
+ // $elm.replaceWith(new_$div);
12686
+ // if (from_panel) {
12687
+ // const xuPanelWrapper = _.clone(new_$div.data().xuPanelWrapper);
12688
+ // $elm.parent().data().xuPanelWrapper = xuPanelWrapper;
12689
+ // $elm.replaceWith(new_$div.children());
12690
+ // }
12691
+
12692
+ // if (val.fields_arr) {
12693
+ // return await func.UI.screen.refresh_xu_attributes(SESSION_ID, val.fields_arr, val.jobNoP, new_$div);
12694
+ // }
12695
+ // func.events.delete_job(SESSION_ID, jobNoP);
12696
+ // };
12697
+ // // if ($elm && func.UI.utils.find_in_element_data('xuData', $(SESSION_OBJ[SESSION_ID].root_element), 'xu_id', $elm.data().xuData.xu_id).length) {
12698
+ // if ($elm && $(`[xu-ui-id="${$elm.attr('xu-ui-id')}"]`).length) {
12699
+ // if (new_$div.data().xuData.paramsP) {
12700
+ // return await replace();
12701
+ // }
12702
+
12703
+ // func.events.delete_job(SESSION_ID, jobNoP);
12704
+ // }
12705
+ // } catch (error) {
12706
+ // func.events.delete_job(SESSION_ID, jobNoP);
12707
+ // }
12708
+ // return;
12709
+ // }
12710
+ // // if (!value) {
12711
+ // if ($elm.prop('tagName') === 'XURENDER') {
12712
+ // func.events.delete_job(SESSION_ID, jobNoP);
12713
+ // return;
12714
+ // }
12715
+
12716
+ // let tmp_$div = $('<div>');
12717
+
12718
+ // let $xurender = $('<xurender>').attr('xu-ui-id', $elm.attr('xu-ui-id')).appendTo(tmp_$div); //.hide();
12719
+ // // was true before
12720
+ // if ($elm.data().xuData.xurender_node) {
12721
+ // $xurender.data({
12722
+ // xuAttributes: $elm.data().xuData.xurender_node.data().xuAttributes || {},
12723
+ // xuData: $elm.data().xuData.xurender_node.data().xuData || {},
12724
+ // });
12725
+ // } else {
12726
+ // // default new state
12727
+
12728
+ // $xurender.data({
12729
+ // xuAttributes: $elm.data().xuAttributes || {},
12730
+ // xuData: $elm.data().xuData || {},
12731
+ // });
12732
+ // const original_data_obj = {
12733
+ // nodeP: _.cloneDeep($elm.data().xuData.node_org),
12734
+ // paramsP: $elm.data().xuData.paramsP,
12735
+ // $container: $elm.clone(true),
12736
+ // parent_infoP: parent_infoP,
12737
+ // };
12738
+
12739
+ // $xurender.data().xuData.original_data_obj = original_data_obj;
12740
+ // }
12741
+
12742
+ // //remove xu-teleport trace
12743
+ // $.each($elm.find('xu-teleport'), (key, val) => {
12744
+ // const xuTeleportData = $(val).data().xuTeleportData || [];
12745
+ // for (const teleported_elm_id of xuTeleportData) {
12746
+ // $(`[xu-ui-id="${teleported_elm_id}"]`).remove();
12747
+ // }
12748
+ // });
12749
+
12750
+ // $elm.replaceWith(tmp_$div.children());
12751
+ // func.events.delete_job(SESSION_ID, jobNoP);
12752
+ // // }
12753
+ // };
12754
+ // if (is_init) {
12755
+ // return init_render();
12756
+ // }
12757
+ // return await post_render();
12758
+ // };
12759
+
12760
+ // const new_render = async function () {
12761
+ // var value = await func.common.get_cast_val(SESSION_ID, 'common fx', 'xu-render', 'bool', val.value);
12762
+ // const has_xu_render_attribute = true;
12763
+ // const has_xu_exp_render_attribute = $elm.data()?.xuData?.attr_exp_info?.['xu-render'] ? true : false;
12764
+ // const init_render = async function () {
12765
+ // nodeP.xu_render_made = value;
12766
+ // if (!value) {
12767
+ // if (has_xu_exp_render_attribute) {
12768
+ // return { has_xu_exp_render_attribute, has_xu_render_attribute, xu_render_background_processing: true };
12769
+ // }
12770
+ // return { has_xu_render_attribute, abort: true };
12771
+ // }
12772
+ // return { has_xu_exp_render_attribute, has_xu_render_attribute };
12773
+ // };
12774
+
12775
+ // const post_render = async function () {
12776
+ // // always come from refresh
12777
+ // let nodeP = $container.data().xuData.node.children[keyP];
12778
+ // nodeP.xu_render_made = value;
12779
+ // if (value) {
12780
+ // try {
12781
+ // 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 || {}));
12782
+ // const xu_ui_id = $elm.attr('xu-ui-id');
12783
+ // let new_$div = UI_WORKER_OBJ?.xu_render_cache?.[xu_ui_id + xu_render_cache_id]?.$div.clone(true);
12784
+ // let found_parent_vars = false;
12785
+ // if (new_$div) {
12786
+ // // validate if $div contains fields from parent ds
12787
+ // const parent_data = get_parent_ds_fields(SESSION_ID, paramsP.dsSessionP);
12788
+ // const parent_fields = Object.keys(parent_data);
12789
+
12790
+ // $.each(new_$div.find('*'), (key, val) => {
12791
+ // const _xuAttributes = $(val)?.data()?.xuAttributes;
12792
+ // if (found_parent_vars || !_xuAttributes) return;
12793
+ // for (const [attr_key, attr_val] of Object.entries(_xuAttributes)) {
12794
+ // if (found_parent_vars) break;
12795
+ // for (const [key, val] of Object.entries(parent_fields)) {
12796
+ // if (attr_val.includes('@' + key)) {
12797
+ // found_parent_vars = true;
12798
+ // break;
12799
+ // }
12800
+ // }
12801
+ // }
12802
+ // });
12803
+ // }
12804
+
12805
+ // if (!new_$div || found_parent_vars) {
12806
+ // UI_WORKER_OBJ.xu_render_cache[xu_ui_id + xu_render_cache_id] = { paramsP };
12807
+ // nodeP.xu_render_xu_ui_id = xu_ui_id;
12808
+ // nodeP.xu_render_cache_id = xu_render_cache_id;
12809
+ // 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);
12810
+ // const _$div = new_$div.clone(true);
12811
+ // UI_WORKER_OBJ.xu_render_cache[xu_ui_id + xu_render_cache_id].$div = _$div;
12812
+ // UI_WORKER_OBJ.xu_render_cache[xu_ui_id + xu_render_cache_id].data = _$div.data();
12813
+ // }
12814
+ // // append order handling
12815
+
12816
+ // if (!$container.children().length) {
12817
+ // new_$div.appendTo($container);
12818
+ // } else {
12819
+ // // iterate the container node
12820
+ // let $last_elm_found = [];
12821
+ // $.each($container.data().xuData.node.children, (item_key, item_val) => {
12822
+ // // const $elm = $(`[xu-node-id="${item_val.id}"]`);
12823
+ // const $elm = func.UI.utils.find_in_element_data('xuData', $(SESSION_OBJ[SESSION_ID].root_element), 'nodeid', item_val.id);
12824
+ // if ($elm.length) {
12825
+ // $last_elm_found = $elm;
12826
+ // }
12827
+ // if (keyP == item_key) {
12828
+ // if ($last_elm_found.length) {
12829
+ // new_$div.after($last_elm_found);
12830
+ // } else {
12831
+ // $container.prepend(new_$div);
12832
+ // }
12833
+ // }
12834
+ // });
12835
+ // }
12836
+ // } catch (error) {
12837
+ // func.events.delete_job(SESSION_ID, jobNoP);
12838
+ // }
12839
+ // return;
12840
+ // }
12841
+
12842
+ // /////////// !value ///////////
12843
+
12844
+ // const xu_ui_id = $elm.attr('xu-ui-id');
12845
+
12846
+ // const cache_str = await get_xu_render_cache_str(SESSION_ID, paramsP.dsSessionP, Object.keys($elm.data()?.xuData?.attr_exp_info?.['xu-render']?.fields || {}));
12847
+ // const _$div = $elm.clone(true);
12848
+ // UI_WORKER_OBJ.xu_render_cache[xu_ui_id + cache_str] = { $div: _$div, data: _$div.data(), paramsP };
12849
+ // $elm.remove();
12850
+ // func.events.delete_job(SESSION_ID, jobNoP);
12851
+ // };
12852
+ // if (is_init) {
12853
+ // return await init_render();
12854
+ // }
12855
+ // return await post_render();
12856
+ // };
12857
+
12858
+ // if (glb.new_xu_render) {
12859
+ // return new_render();
12860
+ // }
12861
+ // return old_render();
12862
+ // },
12863
+ // 'xu-show': async function ($elm, val) {
12864
+ // var value = await func.common.get_cast_val(SESSION_ID, 'common fx', 'xu-show', 'bool', val.value);
12865
+ // if (value) {
12866
+ // $elm.show();
12867
+ // }
12868
+ // if (!value) {
12869
+ // $elm.hide();
12870
+ // }
12871
+ // return {};
12872
+ // },
12873
+ // 'xu-content': async function ($elm, val) {
12874
+ // try {
12875
+ // $elm.html(val.value);
12876
+ // } catch (error) {
12877
+ // console.warn(e);
12878
+ // }
12879
+ // return;
12880
+ // },
12881
+ // 'xu-text': async function ($elm, val) {
12882
+ // try {
12883
+ // $elm.text(val.value);
12884
+ // } catch (error) {
12885
+ // console.warn(e);
12886
+ // }
12887
+ // return;
12888
+ // },
12889
+ // 'xu-html': async function ($elm, val) {
12890
+ // try {
12891
+ // $elm.html(val.value);
12892
+ // } catch (error) {
12893
+ // console.warn(e);
12894
+ // }
12895
+ // return;
12896
+ // },
12897
+ // 'xu-for': async function ($elm, data) {
12898
+ // // exit if call from rendered xu-for item to prevent infante loop (parent_infoP?.iterate_info indicate call from rendered item)
12899
+ // if (parent_infoP?.iterate_info) return {};
12900
+ // if (!data.value) return {};
12901
+ // try {
12902
+ // // 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.
12903
+ // let arr = data.value;
12904
+
12905
+ // // find reference source field
12906
+ // let reference_source_obj;
12907
+
12908
+ // const _progFields = await func.datasource.get_progFields(SESSION_ID, paramsP.dsSessionP);
12909
+
12910
+ // let view_field_obj = func.common.find_item_by_key(_progFields, 'field_id', data.value);
12911
+ // // detect if data.value (xu-for) is reference field_id by checking if exist in the dataset
12912
+ // if (view_field_obj) {
12913
+ // // xu-for is reference field_id
12914
+ // reference_source_obj = await func.datasource.get_value(SESSION_ID, data.value, paramsP.dsSessionP);
12915
+ // arr = reference_source_obj?.ret?.value;
12916
+ // } else {
12917
+ // // xu-for is actual data
12918
+ // if (typeof data.value === 'string') {
12919
+ // arr = eval(data.value.replaceAll('\\', ''));
12920
+ // }
12921
+ // if (typeof arr === 'number') {
12922
+ // arr = Array.from(Array(arr).keys());
12923
+ // }
12924
+ // }
12925
+
12926
+ // const custom_iterator_key = $elm.data().xuData.iterator_key;
12927
+ // const custom_iterator_val = $elm.data().xuData.iterator_val;
12928
+
12929
+ // let iterator_key = custom_iterator_key;
12930
+ // let iterator_val = custom_iterator_val;
12931
+ // let is_key_dynamic_field, is_val_dynamic_field;
12932
+
12933
+ // // custom FOR_VAL name or namespaced default name
12934
+ // if (!custom_iterator_key) {
12935
+ // is_key_dynamic_field = true;
12936
+
12937
+ // iterator_key = '_FOR_KEY';
12938
+ // }
12939
+
12940
+ // if (!custom_iterator_val) {
12941
+ // is_val_dynamic_field = true;
12942
+
12943
+ // iterator_val = '_FOR_VAL';
12944
+ // }
12945
+
12946
+ // var i = 0;
12947
+ // for await (let [_key, _val] of Object.entries(arr)) {
12948
+ // if (_.isArray(arr)) {
12949
+ // _key = Number(_key);
12950
+ // }
12951
+
12952
+ // const set_value = async function (is_dynamic_field, currentRecordId, field_id, value) {
12953
+ // if (is_dynamic_field) {
12954
+ // func.datasource.add_dynamic_field_to_ds(SESSION_ID, paramsP.dsSessionP, field_id, value);
12955
+ // } else {
12956
+ // const _progFields = await func.datasource.get_progFields(SESSION_ID, paramsP.dsSessionP);
12957
+
12958
+ // let view_field_obj = func.common.find_item_by_key(_progFields, 'field_id', field_id);
12959
+ // if (view_field_obj) {
12960
+ // let _ds = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP];
12961
+ // try {
12962
+ // const row_idx = func.common.find_ROWID_idx(_ds, currentRecordId);
12963
+ // _ds.data_feed.rows[row_idx][field_id] = value;
12964
+ // } catch (err) {
12965
+ // console.error(err);
12966
+ // }
12967
+ // } else {
12968
+ // console.error('field not exist in dataset for xu-for method');
12969
+ // }
12970
+ // }
12971
+ // };
12972
+
12973
+ // var currentRecordId = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP].currentRecordId.toString();
12974
+
12975
+ // await set_value(is_key_dynamic_field, currentRecordId, iterator_key, _key);
12976
+ // await set_value(is_val_dynamic_field, currentRecordId, iterator_val, _val);
12977
+
12978
+ // var iterate_info = {
12979
+ // _val,
12980
+ // _key,
12981
+ // iterator_key,
12982
+ // iterator_val,
12983
+ // is_key_dynamic_field,
12984
+ // is_val_dynamic_field,
12985
+ // reference_source_obj,
12986
+ // };
12987
+ // // let _parent_info = _.cloneDeep(parent_infoP) || {};
12988
+ // let _parent_info = klona.klona(parent_infoP) || {};
12989
+ // _parent_info.iterate_info = iterate_info;
12990
+
12991
+ // const $divP = await func.UI.screen.render_ui_tree(
12992
+ // SESSION_ID,
12993
+ // $container,
12994
+ // nodeP,
12995
+ // _parent_info, //parent_infoP ? _.cloneDeep(_parent_info) : null,
12996
+ // paramsP,
12997
+ // jobNoP,
12998
+ // null,
12999
+ // i,
13000
+ // null,
13001
+ // nodeP,
13002
+ // null,
13003
+ // $root_container,
13004
+ // );
13005
+
13006
+ // $.each($divP.children(), function (key, val) {
13007
+ // if ($(val)?.data()?.xuData) {
13008
+ // $(val).data().xuData.iterate_info = iterate_info;
13009
+ // }
13010
+ // });
13011
+
13012
+ // i++;
13013
+ // }
13014
+ // $elm.remove();
13015
+ // return { abort: true };
13016
+ // } catch (e) {
13017
+ // console.error(' Iterator Arr parse error');
13018
+ // return { abort: true };
13019
+ // }
13020
+ // },
13021
+ // 'xu-for-key': async function ($elm, val) {
13022
+ // $elm.data().xuData.iterator_key = val.value;
13023
+ // return {};
13024
+ // },
13025
+ // 'xu-for-val': async function ($elm, val) {
13026
+ // $elm.data().xuData.iterator_val = val.value;
13027
+ // return {};
13028
+ // },
13029
+ // 'xu-class': async function ($elm, val) {
13030
+ // try {
13031
+ // const classes_string = val.value;
13032
+ // // let obj = _.isString(classes_string) ? JSON.parse(classes_string) : _.defaults(classes_string, {});
13033
+
13034
+ // const classes_obj = _.isString(classes_string) ? JSON.parse(classes_string) : _.defaults(classes_string, {});
13035
+ // for await (const [cla, cond] of Object.entries(classes_obj)) {
13036
+ // let res = await func.expression.get(
13037
+ // SESSION_ID,
13038
+ // cond,
13039
+ // paramsP.dsSessionP,
13040
+ // 'UI Attr EXP',
13041
+ // $elm.data().xuData.currentRecordId, // SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP].currentRecordId
13042
+ // null,
13043
+ // null,
13044
+ // null,
13045
+ // null,
13046
+ // null,
13047
+ // $elm.data().xuData.iterate_info,
13048
+ // );
13049
+
13050
+ // if (res.result) {
13051
+ // $elm.addClass(cla);
13052
+ // } else {
13053
+ // $elm.removeClass(cla);
13054
+ // }
13055
+
13056
+ // $elm.data().xuData.debug_info.attribute_stat['xu-class'] = $elm.attr('class');
13057
+ // }
13058
+ // return {};
13059
+ // } catch (e) {
13060
+ // console.warn('parse error:' + val.value);
13061
+ // return { abort: true };
13062
+ // }
13063
+ // },
13064
+ // 'xu-exp': async function ($elm, val) {
13065
+ // let exp = val.value === null ? true : val.value;
13066
+
13067
+ // 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);
13068
+
13069
+ // let value = func.UI.screen.fix_val_defaults(val.key, exp_ret.result);
13070
+
13071
+ // var new_val = {
13072
+ // key: val.key,
13073
+ // value,
13074
+ // };
13075
+
13076
+ // if (nodeP.tagName.substr(0, 3) === 'xu-') {
13077
+ // if (tag_fx[nodeP.tagName][new_val.key]) {
13078
+ // return await tag_fx[nodeP.tagName][new_val.key]($elm, new_val);
13079
+ // }
13080
+ // console.warn(`attribute ${new_val.key} not found for ${nodeP.tagName}`);
13081
+ // return {};
13082
+ // }
13083
+ // if (!$elm.data().xuData) return;
13084
+
13085
+ // $elm.data().xuData.debug_info.attribute_stat[new_val.key] = new_val.value;
13086
+
13087
+ // // IGNORE UNDEFINED or NULL ATTRIBUTES
13088
+ // if (typeof new_val.value === 'undefined' || new_val.value === null) {
13089
+ // return {};
13090
+ // }
13091
+
13092
+ // // IGNORE ATTRIBUTES WITH EMPTY VALUES
13093
+ // if (glb.solid_attributes.includes(new_val.key) && !new_val.value) {
13094
+ // return {};
13095
+ // }
13096
+
13097
+ // if (new_val.key.substr(0, 2) === 'xu') {
13098
+ // return await common_fx[new_val.key]($elm, new_val);
13099
+ // }
13100
+
13101
+ // $elm.attr(new_val.key, ($elm.attr(new_val.key) || '') + new_val.value);
13102
+ // return {};
13103
+ // },
13104
+ // 'xu-on': async function ($elm, val) {
13105
+ // CLIENT_ACTIVITY_TS = Date.now();
13106
+ // const trigger = val.key.split('xu-on:')[1].toLowerCase();
13107
+ // $elm.on(trigger, async function (evt) {
13108
+ // const _$elm = $(evt.currentTarget);
13109
+ // if (_.isEmpty(_$elm.data().xuAttributes)) return;
13110
+
13111
+ // for await (const [key, val] of Object.entries(_$elm.data().xuAttributes['xu-on:' + evt.type])) {
13112
+ // if (!_.isEmpty(val.props.condition)) {
13113
+ // const expCond = await func.expression.get(SESSION_ID, val.props.condition, paramsP.dsSessionP, 'condition', paramsP.recordid); // execute expression
13114
+ // if (!expCond.result) continue;
13115
+ // }
13116
+
13117
+ // if (val.event_modifiers && evt[val.event_modifiers]) {
13118
+ // evt[val.event_modifiers]();
13119
+ // }
13120
+
13121
+ // // if (val.handler === 'custom') {
13122
+ // if (val.workflow) {
13123
+ // // do BL
13124
+ // for await (const [key2, val2] of Object.entries(val.workflow)) {
13125
+ // // var cond = val2.data.enabled;
13126
+ // // if (val2.data.enabled && val2.props.condition) {
13127
+ // // expCond = await func.expression.get(SESSION_ID, val2.props.condition, paramsP.dsSessionP, 'condition', paramsP.recordid); // execute expression
13128
+ // // cond = expCond.result;
13129
+ // // }
13130
+ // // if (!cond) continue;
13131
+
13132
+ // if (!val2.data.enabled) continue; // added Jul 3, 25 - condition validate on execution
13133
+
13134
+ // 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);
13135
+ // }
13136
+ // }
13137
+ // }
13138
+ // });
13139
+ // return {};
13140
+ // },
13141
+ // 'xu-script': async function ($elm, val) {
13142
+ // var checkExist = setInterval(async function () {
13143
+ // if ($elm.is(':visible')) {
13144
+ // try {
13145
+ // // var res = eval('(' + val.value + ')');
13146
+ // // const fn = `(function(el) {
13147
+ // // ${val.value}
13148
+ // // })(document.querySelector(\`[xu-ui-id="${$elm.attr('xu-ui-id')}"]\`));`;
13149
+
13150
+ // const fn = `async (el)=>{${val.value} };`;
13151
+
13152
+ // var res = eval(fn);
13153
+ // await res($elm[0]);
13154
+ // // if (typeof res === 'function') {
13155
+ // // res($elm[0]);
13156
+ // // }
13157
+ // } catch (e) {
13158
+ // eval(val.value);
13159
+ // }
13160
+
13161
+ // clearInterval(checkExist);
13162
+ // }
13163
+ // }, 100); // check every 100ms
13164
+
13165
+ // return {};
13166
+ // },
13167
+ // 'xu-style-global': async function ($elm, val) {
13168
+ // $('head').append(`<style>${val.value}</style>`);
13169
+ // return {};
13170
+ // },
13171
+ // 'xu-style': async function ($elm, val) {
13172
+ // var cssString = val.value;
13173
+
13174
+ // var parser = new cssjs();
13175
+
13176
+ // var parsed = parser.parseCSS(cssString);
13177
+ // var xuUiId = `[xu-ui-id="${$elm.attr('xu-ui-id')}"]`;
13178
+
13179
+ // $.each(parsed, function (key, val) {
13180
+ // var selectors_arr = val.selector.split(',');
13181
+
13182
+ // $.each(selectors_arr, function (key2, val2) {
13183
+ // selectors_arr[key2] = `${xuUiId} ${val2}, ${xuUiId}${val2}`;
13184
+ // // console.log(new_selector);
13185
+ // });
13186
+
13187
+ // val.selector = selectors_arr.join(',');
13188
+ // // console.log(parsed);
13189
+ // });
13190
+
13191
+ // var newCSSString = parser.getCSSForEditor(parsed);
13192
+
13193
+ // $('head').append(`<style>${newCSSString}</style>`);
13194
+ // return {};
13195
+ // },
13196
+ // 'xu-cdn': async function ($elm, val) {
13197
+ // for await (const [key, resource] of Object.entries(val.value)) {
13198
+ // await load_cdn(resource);
13199
+ // }
13200
+
13201
+ // return {};
13202
+ // },
13203
+ // 'xu-ui-plugin': async function ($elm, val) {
13204
+ // var _session = SESSION_OBJ[SESSION_ID];
13205
+
13206
+ // for await (const [plugin_name, value] of Object.entries(val.value)) {
13207
+ // const _plugin = APP_OBJ[_session.app_id]?.app_plugins_purchased?.[plugin_name];
13208
+ // if (_plugin?.installed && _plugin?.manifest?.['runtime.mjs']?.exist && _plugin?.manifest?.['index.mjs']?.exist && value.enabled) {
13209
+ // if (_plugin?.manifest?.['runtime.mjs'].dist && _plugin?.manifest?.['runtime.mjs']?.css) {
13210
+ // const plugin_runtime_css_url = await func.utils.get_plugin_npm_cdn(SESSION_ID, plugin_name, 'dist/runtime.css');
13211
+ // func.utils.load_css_on_demand(plugin_runtime_css_url);
13212
+ // }
13213
+
13214
+ // const plugin_index_src = await func.utils.get_plugin_npm_cdn(SESSION_ID, plugin_name, `${_plugin.manifest['index.mjs'].dist ? 'dist/' : ''}index.mjs`);
13215
+
13216
+ // const plugin_index_resources = await import(plugin_index_src);
13217
+
13218
+ // let properties = _.cloneDeep(plugin_index_resources.properties);
13219
+ // for await (let [prop_name, prop_val] of Object.entries(properties)) {
13220
+ // prop_val.value = value?.attributes?.[prop_name];
13221
+ // if (value?.attributes?.[`xu-exp:${prop_name}`]) {
13222
+ // const res = await func.expression.get(SESSION_ID, value?.attributes?.[`xu-exp:${prop_name}`], paramsP.dsSessionP, 'UI Attr EXP');
13223
+ // prop_val.value = res.result;
13224
+ // }
13225
+ // }
13226
+ // // $elm.data().xu_ui_plugin = { properties };
13227
+ // const plugin_runtime_src = await func.utils.get_plugin_npm_cdn(SESSION_ID, plugin_name, `${_plugin.manifest['runtime.mjs'].dist ? 'dist/' : ''}runtime.mjs`);
13228
+
13229
+ // const plugin_runtime_resources = await import(plugin_runtime_src);
13230
+
13231
+ // if (plugin_runtime_resources.cdn && typeof _.isArray(plugin_runtime_resources.cdn)) {
13232
+ // for await (const resource of plugin_runtime_resources.cdn) {
13233
+ // await load_cdn(resource);
13234
+ // }
13235
+ // }
13236
+
13237
+ // if (plugin_runtime_resources.fn) {
13238
+ // await plugin_runtime_resources.fn(plugin_name, $elm?.[0], properties);
13239
+ // // await plugin_runtime_resources.fn(plugin_name, $elm?.[0], $elm.data().xu_ui_plugin.properties);
13240
+ // }
13241
+ // }
13242
+ // }
13243
+
13244
+ // return {};
13245
+ // },
13246
+ // 'xu-store': async function ($elm, val) {
13247
+ // try {
13248
+ // const fields_obj = JSON5.parse(val.value);
13249
+ // for (const [field_id, value] of Object.entries(fields_obj)) {
13250
+ // func.datasource.add_dynamic_field_to_ds(SESSION_ID, paramsP.dsSessionP, field_id, value);
13251
+ // }
13252
+ // } catch (err) {
13253
+ // console.error(err);
13254
+ // }
13255
+ // return {};
13256
+ // },
13257
+ // 'xu-viewport': async function ($elm, val) {
13258
+ // // functionality in draw_html_element
13259
+ // return {};
13260
+ // },
13261
+ // };
13262
+
13263
+ // if (nodeP.tagName.substr(0, 3) === 'xu-') {
13264
+ // if (xu_func === 'xu-exp') {
13265
+ // return common_fx[xu_func]($elm, val);
13266
+ // }
13267
+
13268
+ // if (tag_fx?.[nodeP.tagName]?.[xu_func]) {
13269
+ // let ret = await tag_fx[nodeP.tagName][xu_func]($elm, val);
13270
+ // return ret;
13271
+ // }
13272
+ // // if (xu_func !== "tree_id")
13273
+ // console.warn(`attribute ${xu_func} not found for ${nodeP.tagName}`);
13274
+ // return {};
13275
+ // }
13276
+ // if (_.isEmpty($elm.data())) {
13277
+ // return {};
13278
+ // }
13279
+ // if (!$elm.data().xuData.debug_info.attribute_stat) {
13280
+ // $elm.data().xuData.debug_info.attribute_stat = {};
13281
+ // }
13282
+ // if (xu_func !== 'xu-exp') {
13283
+ // $elm.data().xuData.debug_info.attribute_stat[xu_func] = val.value;
13284
+ // }
13285
+ // try {
13286
+ // if (!common_fx[xu_func]) {
13287
+ // console.warn('invalid xu-tag', xu_func, error);
13288
+ // return {};
13289
+ // }
13290
+
13291
+ // return await common_fx[xu_func]($elm, val);
13292
+ // } catch (error) {
13293
+ // debugger;
13294
+ // }
13295
+ // };
13296
+
13297
+ 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) {
13298
+ if (is_skeleton) return;
13299
+
13300
+ // Cache frequently accessed values
13301
+ const _session = SESSION_OBJ[SESSION_ID];
13302
+ const _ds = _session.DS_GLB[paramsP.dsSessionP];
13303
+ const elmData = $elm.data();
13304
+ const xuData = elmData.xuData;
13305
+ const nodeTag = nodeP.tagName;
13306
+ const isXuTag = nodeTag && nodeTag.startsWith('xu-');
12332
13307
 
12333
13308
  const load_cdn = async function (resource) {
12334
- // console.log("loading cdn", resource);
12335
- if (!_.isObject(resource) && _.isString(resource)) {
12336
- resource = { src: resource, type: 'js' };
12337
- }
12338
13309
  if (!_.isObject(resource)) {
13310
+ resource = _.isString(resource) ? { src: resource, type: 'js' } : null;
13311
+ }
13312
+ if (!resource) {
12339
13313
  throw new Error('cdn resource in wrong format');
12340
13314
  }
12341
- return new Promise(async (resolve) => {
12342
- try {
12343
- switch (resource.type) {
12344
- case 'js':
12345
- await func.utils.load_js_on_demand(resource.src);
12346
- break;
12347
- case 'css':
12348
- await func.utils.load_js_on_demand(resource.src);
12349
- break;
12350
- case 'module':
12351
- func.utils.load_js_on_demand(resource.src, 'module');
12352
- break;
12353
13315
 
12354
- default:
12355
- await func.utils.load_js_on_demand(resource.src);
12356
- break;
12357
- }
12358
- resolve();
12359
- } catch (error) {
12360
- func.utils.debug_report(SESSION_ID, 'xu-cdn', 'Fail to load: ' + resource, 'W');
12361
- resolve();
12362
- }
12363
-
12364
- // if (resource.type === "js" || !resource.type) {
12365
- // await func.utils.load_js_on_demand(resource.src);
12366
- // return resolve();
12367
- // }
12368
- // if (resource.type === "css") {
12369
- // func.utils.load_css_on_demand(resource.src);
12370
- // return resolve();
12371
- // }
12372
- // if (resource.type === "module") {
12373
- // func.utils.load_js_on_demand(resource.src, "module");
12374
- // return resolve();
12375
- // }
12376
- // func.utils.debug_report(
12377
- // SESSION_ID,
12378
- // "xu-cdn",
12379
- // "Fail to load: " + resource,
12380
- // "W"
12381
- // );
12382
- // return resolve();
12383
- });
13316
+ try {
13317
+ const loadFn = resource.type === 'css' ? func.utils.load_css_on_demand : func.utils.load_js_on_demand;
13318
+ const moduleArg = resource.type === 'module' ? 'module' : undefined;
13319
+ await loadFn(resource.src, moduleArg);
13320
+ } catch (error) {
13321
+ func.utils.debug_report(SESSION_ID, 'xu-cdn', 'Fail to load: ' + resource.src, 'W');
13322
+ }
12384
13323
  };
12385
13324
 
12386
13325
  const common_fx = {
12387
13326
  'xu-attrs': async function ($elm, val) {
12388
- if (!val.value) return {};
12389
- if (!_.isObject(val.value)) throw 'xu-attrs value us not an object';
12390
- for (const [attr_key, attr_val] of Object.entries(val.value)) {
12391
- nodeP.attributes[attr_key] = attr_val;
13327
+ if (!val.value || !_.isObject(val.value)) {
13328
+ if (val.value) throw 'xu-attrs value is not an object';
13329
+ return {};
12392
13330
  }
12393
-
13331
+ Object.assign(nodeP.attributes, val.value);
12394
13332
  return {};
12395
13333
  },
13334
+
12396
13335
  'xu-ref': async function ($elm, val, dsSession) {
12397
13336
  if (!val.value) return {};
12398
13337
 
12399
13338
  func.UI.update_xu_ref(SESSION_ID, dsSession || paramsP.dsSessionP, val.value, $elm);
12400
13339
 
12401
- // Select the node that will be observed for mutations
12402
13340
  const targetNode = $elm[0];
13341
+ if (!targetNode) return {};
12403
13342
 
12404
- if (!targetNode) return;
12405
-
12406
- // Options for the observer (which mutations to observe)
12407
- const config = { attributes: true, childList: true, subtree: true };
12408
-
12409
- // Callback function to execute when mutations are observed
12410
- const callback = (mutationList, observer) => {
13343
+ const observer = new MutationObserver(() => {
12411
13344
  func.UI.screen.refresh_xu_attributes(SESSION_ID, [val.value]);
12412
- };
12413
-
12414
- // Create an observer instance linked to the callback function
12415
- const observer = new MutationObserver(callback);
12416
-
12417
- // Start observing the target node for configured mutations
12418
- observer.observe(targetNode, config);
12419
-
12420
- // Later, you can stop observing
12421
- // observer.disconnect();
13345
+ });
12422
13346
 
13347
+ observer.observe(targetNode, { attributes: true, childList: true, subtree: true });
12423
13348
  return {};
12424
13349
  },
13350
+
12425
13351
  'xu-bind': async function ($elm, val) {
12426
- if (is_skeleton) return;
13352
+ if (is_skeleton) return {};
12427
13353
 
12428
13354
  let val_is_reference_field = false;
13355
+ let _prog_id = xuData.paramsP.prog_id;
13356
+ let _dsP = xuData.paramsP.dsSessionP;
12429
13357
 
12430
- let _prog_id = $elm.data().xuData.paramsP.prog_id;
12431
- let _dsP = $elm.data().xuData.paramsP.dsSessionP;
12432
13358
  const view_ret = await func.utils.VIEWS_OBJ.get(SESSION_ID, _prog_id);
12433
13359
  if (!view_ret) return {};
12434
13360
 
12435
13361
  let is_dynamic_field = false;
12436
13362
  let field_prop;
12437
13363
  let bind_field_id;
12438
-
12439
13364
  const input_field_type = $elm.attr('type');
12440
13365
 
12441
13366
  const get_bind_field = async function (field_id) {
@@ -12445,16 +13370,14 @@ func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $
12445
13370
  } else {
12446
13371
  field_prop = func.common.find_item_by_key(view_ret.progFields, 'field_id', field_id);
12447
13372
  if (!field_prop) {
12448
- /// find the field everywhere in the chain Aug 30 2024
12449
13373
  const ret_get_value = await func.datasource.get_value(SESSION_ID, field_id, _dsP);
12450
-
12451
13374
  if (ret_get_value.found) {
12452
13375
  _dsP = ret_get_value.dsSessionP;
12453
- let _ds = SESSION_OBJ[SESSION_ID].DS_GLB[_dsP];
12454
- _prog_id = _ds.prog_id;
12455
- const view_ret = await func.utils.VIEWS_OBJ.get(SESSION_ID, _prog_id);
12456
- if (!view_ret) return {};
12457
- field_prop = func.common.find_item_by_key(view_ret.progFields, 'field_id', field_id);
13376
+ const ds = _session.DS_GLB[_dsP];
13377
+ _prog_id = ds.prog_id;
13378
+ const new_view_ret = await func.utils.VIEWS_OBJ.get(SESSION_ID, _prog_id);
13379
+ if (!new_view_ret) return {};
13380
+ field_prop = func.common.find_item_by_key(new_view_ret.progFields, 'field_id', field_id);
12458
13381
  }
12459
13382
  if (!field_prop) {
12460
13383
  throw `field ${field_id} not found in the program scope`;
@@ -12473,160 +13396,125 @@ func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $
12473
13396
  }
12474
13397
 
12475
13398
  const field_changed = async function (e) {
12476
- var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[_dsP];
12477
-
12478
- // update array for checkbox that not in xu-for
12479
- if (field_prop.props.fieldType === 'array' && input_field_type === 'checkbox' && val_is_reference_field) {
12480
- let arr_value_before_cast = _.clone((await func.datasource.get_value(SESSION_ID, bind_field_id, _dsP, _ds.currentRecordId)).ret.value);
12481
- let value_from_getter = bind.getter($elm[0]);
12482
- let value;
12483
- if (arr_value_before_cast.includes(value_from_getter)) {
12484
- value = arr_value_before_cast.filter((item) => !_.isEqual(item, value_from_getter));
12485
- } else {
12486
- arr_value_before_cast.push(value_from_getter);
12487
- value = arr_value_before_cast;
12488
- }
12489
-
12490
- let datasource_changes = {
12491
- [_dsP]: {
12492
- [_ds.currentRecordId]: {
12493
- [bind_field_id]: value,
12494
- },
12495
- },
12496
- };
12497
-
12498
- return await func.datasource.update(SESSION_ID, datasource_changes);
13399
+ const ds = _session.DS_GLB[_dsP];
13400
+ const fieldType = field_prop.props.fieldType;
13401
+ const isCheckbox = input_field_type === 'checkbox';
13402
+ const isRadio = input_field_type === 'radio';
13403
+
13404
+ // Handle array field with checkbox
13405
+ if (fieldType === 'array' && isCheckbox && val_is_reference_field) {
13406
+ const arr_value = _.clone((await func.datasource.get_value(SESSION_ID, bind_field_id, _dsP, ds.currentRecordId)).ret.value);
13407
+ const value_from_getter = bind.getter($elm[0]);
13408
+ const value = arr_value.includes(value_from_getter) ? arr_value.filter((item) => !_.isEqual(item, value_from_getter)) : [...arr_value, value_from_getter];
13409
+
13410
+ return await func.datasource.update(SESSION_ID, {
13411
+ [_dsP]: { [ds.currentRecordId]: { [bind_field_id]: value } },
13412
+ });
12499
13413
  }
12500
13414
 
12501
- // update array for radio that not in xu-for
12502
- if (field_prop.props.fieldType === 'array' && input_field_type === 'radio' && val_is_reference_field) {
12503
- let value_from_getter = bind.getter($elm[0]);
12504
-
12505
- let datasource_changes = {
12506
- [_dsP]: {
12507
- [_ds.currentRecordId]: {
12508
- [bind_field_id]: [value_from_getter],
12509
- },
12510
- },
12511
- };
12512
-
12513
- return await func.datasource.update(SESSION_ID, datasource_changes);
13415
+ // Handle array field with radio
13416
+ if (fieldType === 'array' && isRadio && val_is_reference_field) {
13417
+ return await func.datasource.update(SESSION_ID, {
13418
+ [_dsP]: { [ds.currentRecordId]: { [bind_field_id]: [bind.getter($elm[0])] } },
13419
+ });
12514
13420
  }
12515
13421
 
12516
- var value = await func.common.get_cast_val(SESSION_ID, 'xu-bind', 'value', field_prop.props.fieldType, bind.getter($elm[0]));
13422
+ let value = await func.common.get_cast_val(SESSION_ID, 'xu-bind', 'value', fieldType, bind.getter($elm[0]));
12517
13423
 
12518
- if (field_prop.props.fieldType === 'object') {
13424
+ if (fieldType === 'object') {
12519
13425
  value = await func.common.get_cast_val(SESSION_ID, 'xu-bind', 'value', input_field_type, bind.getter($elm[0]));
12520
13426
  }
12521
13427
 
12522
- if (!_ds.currentRecordId) return;
13428
+ if (!ds.currentRecordId) return;
12523
13429
 
12524
- let datasource_changes = {
12525
- [_dsP]: {
12526
- [_ds.currentRecordId]: {
12527
- [bind_field_id]: value,
12528
- },
12529
- },
12530
- };
13430
+ await func.datasource.update(SESSION_ID, {
13431
+ [_dsP]: { [ds.currentRecordId]: { [bind_field_id]: value } },
13432
+ });
12531
13433
 
12532
- await func.datasource.update(SESSION_ID, datasource_changes);
12533
- const iterate_info = $elm?.data()?.xuData?.iterate_info;
13434
+ const iterate_info = xuData?.iterate_info;
12534
13435
  const reference_source_obj = iterate_info?.reference_source_obj;
12535
- if (reference_source_obj) {
12536
- if (reference_source_obj.ret.type === 'array') {
12537
- if (iterate_info.iterator_val === bind_field_id) {
12538
- const arr_idx = Number($elm?.data()?.xuData?.iterate_info._key);
12539
13436
 
12540
- const dataset_arr = await func.datasource.get_value(SESSION_ID, reference_source_obj.fieldIdP, _dsP, reference_source_obj.currentRecordId);
12541
- let new_arr = _.cloneDeep(dataset_arr.ret.value);
13437
+ if (reference_source_obj?.ret?.type === 'array' && iterate_info.iterator_val === bind_field_id) {
13438
+ const arr_idx = Number(iterate_info._key);
13439
+ const dataset_arr = await func.datasource.get_value(SESSION_ID, reference_source_obj.fieldIdP, _dsP, reference_source_obj.currentRecordId);
13440
+ const new_arr = _.cloneDeep(dataset_arr.ret.value);
12542
13441
 
12543
- if (field_prop.props.fieldType === 'object' && val_is_reference_field) {
12544
- let obj_item = new_arr[arr_idx];
12545
-
12546
- let e_exp = val.value.replace(bind_field_id, 'obj_item');
12547
-
12548
- let new_val = eval(e_exp + (input_field_type === 'string' ? `="${value}"` : `=${value}`));
12549
-
12550
- new_arr[arr_idx] = obj_item;
12551
- } else {
12552
- new_arr[arr_idx] = value;
12553
- }
12554
- // datasource_changes[_dsP][_ds.currentRecordId][reference_source_obj.fieldIdP] = new_arr;
12555
-
12556
- let datasource_changes = {
12557
- [_dsP]: {
12558
- [_ds.currentRecordId]: {
12559
- [reference_source_obj.fieldIdP]: new_arr,
12560
- },
12561
- },
12562
- };
12563
-
12564
- await func.datasource.update(SESSION_ID, datasource_changes, null, true);
12565
- }
13442
+ if (fieldType === 'object' && val_is_reference_field) {
13443
+ let obj_item = new_arr[arr_idx];
13444
+ const e_exp = val.value.replace(bind_field_id, 'obj_item');
13445
+ eval(e_exp + (input_field_type === 'string' ? `="${value}"` : `=${value}`));
13446
+ new_arr[arr_idx] = obj_item;
13447
+ } else {
13448
+ new_arr[arr_idx] = value;
12566
13449
  }
13450
+
13451
+ await func.datasource.update(
13452
+ SESSION_ID,
13453
+ {
13454
+ [_dsP]: { [ds.currentRecordId]: { [reference_source_obj.fieldIdP]: new_arr } },
13455
+ },
13456
+ null,
13457
+ true,
13458
+ );
12567
13459
  }
12568
13460
 
12569
- await func.datasource.update_changes_for_out_parameter(SESSION_ID, _dsP, _ds.parentDataSourceNo);
13461
+ await func.datasource.update_changes_for_out_parameter(SESSION_ID, _dsP, ds.parentDataSourceNo);
12570
13462
  };
12571
13463
 
12572
13464
  const bind = new UI_FRAMEWORK_PLUGIN.bind();
12573
-
12574
13465
  bind.listener($elm[0], field_changed);
12575
13466
 
12576
13467
  const set_value = function () {
12577
- let _ds = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP];
12578
- if (!_ds.currentRecordId) return;
12579
- let value;
13468
+ const ds = _session.DS_GLB[paramsP.dsSessionP];
13469
+ if (!ds.currentRecordId) return;
13470
+
12580
13471
  try {
13472
+ let value;
12581
13473
  if (val_is_reference_field) {
12582
13474
  if (is_dynamic_field) {
12583
- value = _ds.dynamic_fields[bind_field_id].value;
13475
+ value = ds.dynamic_fields[bind_field_id].value;
12584
13476
  } else {
12585
- const row_idx = func.common.find_ROWID_idx(_ds, _ds.currentRecordId);
12586
- value = _ds.data_feed.rows?.[row_idx]?.[bind_field_id];
13477
+ const row_idx = func.common.find_ROWID_idx(ds, ds.currentRecordId);
13478
+ value = ds.data_feed.rows?.[row_idx]?.[bind_field_id];
12587
13479
  }
12588
- if (field_prop.props.fieldType === 'array' && $elm.attr('type') === 'checkbox' && $elm.attr('value')) {
12589
- if (value.includes($elm.attr('value'))) {
12590
- value = true;
12591
- } else {
12592
- value = false;
12593
- }
12594
- } else if (field_prop.props.fieldType === 'array' && $elm.attr('type') === 'radio' && $elm.attr('value')) {
12595
- if (value.includes($elm.attr('value'))) {
12596
- value = $elm.attr('value');
12597
- } else {
12598
- value = false;
12599
- }
12600
- } else if (field_prop.props.fieldType === 'object' && val.value.split('.').length > 1) {
12601
- let str = val.value.replace(bind_field_id, '(' + JSON.stringify(value) + ')');
12602
- value = eval(str);
13480
+
13481
+ const fieldType = field_prop.props.fieldType;
13482
+ const elmValue = $elm.attr('value');
13483
+
13484
+ if (fieldType === 'array' && input_field_type === 'checkbox' && elmValue) {
13485
+ value = value.includes(elmValue);
13486
+ } else if (fieldType === 'array' && input_field_type === 'radio' && elmValue) {
13487
+ value = value.includes(elmValue) ? elmValue : false;
13488
+ } else if (fieldType === 'object' && val.value.split('.').length > 1) {
13489
+ value = eval(val.value.replace(bind_field_id, '(' + JSON.stringify(value) + ')'));
12603
13490
  }
12604
13491
  } else {
12605
13492
  value = val.value;
12606
13493
  }
12607
- if (typeof value === 'undefined') return;
12608
- bind.setter($elm[0], value);
13494
+
13495
+ if (value !== undefined) {
13496
+ bind.setter($elm[0], value);
13497
+ }
12609
13498
  } catch (err) {
12610
13499
  console.error(err);
12611
13500
  }
12612
13501
  };
12613
- /// init value from ds
12614
- $('body').on('xu-bind-refresh.' + _ds.dsSession.toString(), () => {
12615
- set_value();
12616
- });
12617
13502
 
13503
+ $('body').on('xu-bind-refresh.' + _ds.dsSession, set_value);
12618
13504
  set_value();
12619
13505
  return {};
12620
13506
  },
13507
+
12621
13508
  'xu-render': async function ($elm, val, from_panel) {
12622
- const old_render = async function () {
12623
- var value = await func.common.get_cast_val(SESSION_ID, 'common fx', 'xu-render', 'bool', val.value);
13509
+ const value = await func.common.get_cast_val(SESSION_ID, 'common fx', 'xu-render', 'bool', val.value);
13510
+
13511
+ if (!glb.new_xu_render) {
13512
+ // Old render logic (kept as is for compatibility)
12624
13513
  const init_render = function () {
12625
13514
  if (!value) {
12626
- var cloned_$div = $elm.clone(true);
12627
-
12628
- let $xurender = $('<xurender>').attr('xu-ui-id', $elm.attr('xu-ui-id')).attr('hidden', true).appendTo($container); //.hide();
12629
- let original_data_obj = {
13515
+ const cloned_$div = $elm.clone(true);
13516
+ const $xurender = $('<xurender>').attr('xu-ui-id', $elm.attr('xu-ui-id')).attr('hidden', true).appendTo($container);
13517
+ const original_data_obj = {
12630
13518
  $container: cloned_$div,
12631
13519
  nodeP: _.cloneDeep(nodeP),
12632
13520
  parent_infoP,
@@ -12639,8 +13527,6 @@ func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $
12639
13527
  $xurender.data().xuData.original_data_obj = original_data_obj;
12640
13528
  $xurender.data().xuData.xurender_node = cloned_$div;
12641
13529
  $xurender.data().xuAttributes = nodeP.attributes || {};
12642
- // $xurender.hide();
12643
-
12644
13530
  $elm.remove();
12645
13531
  return { abort: true };
12646
13532
  }
@@ -12650,271 +13536,207 @@ func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $
12650
13536
  const post_render = async function () {
12651
13537
  if (value) {
12652
13538
  try {
12653
- // abort if already rended
12654
- if ($elm[0].tagName !== 'XURENDER' && $elm?.length) {
13539
+ if ($elm[0].tagName !== 'XURENDER' || !$elm?.length) {
12655
13540
  return func.events.delete_job(SESSION_ID, jobNoP);
12656
13541
  }
12657
13542
 
12658
- let original_data_obj = $elm.data().xuData.original_data_obj;
12659
-
13543
+ const original_data_obj = $elm.data().xuData.original_data_obj;
12660
13544
  if (!original_data_obj) {
12661
13545
  func.events.delete_job(SESSION_ID, jobNoP);
12662
13546
  return { delete_job: jobNoP };
12663
13547
  }
12664
13548
 
12665
- const new_$div = await func.UI.screen.render_ui_tree(
12666
- SESSION_ID,
12667
- $elm, //original_data_obj.$container,
12668
- _.cloneDeep(original_data_obj.nodeP),
12669
- original_data_obj.parent_infoP,
12670
- original_data_obj.paramsP,
12671
- jobNoP,
12672
- null,
12673
- original_data_obj.keyP,
12674
- null,
12675
- original_data_obj.parent_nodeP,
12676
- null,
12677
- original_data_obj.$root_container,
12678
- );
13549
+ 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);
12679
13550
 
12680
13551
  new_$div.data().xuData.original_data_obj = original_data_obj;
12681
13552
  new_$div.data().xuData.xurender_node = $elm.clone(true);
12682
13553
  new_$div.data().xuAttributes = $elm.data().xuAttributes || {};
12683
13554
 
12684
13555
  const replace = async function () {
12685
- $elm.replaceWith(new_$div);
13556
+ $elm.replaceWith(from_panel ? new_$div.children() : new_$div);
12686
13557
  if (from_panel) {
12687
- const xuPanelWrapper = _.clone(new_$div.data().xuPanelWrapper);
12688
- $elm.parent().data().xuPanelWrapper = xuPanelWrapper;
12689
- $elm.replaceWith(new_$div.children());
13558
+ $elm.parent().data().xuPanelWrapper = _.clone(new_$div.data().xuPanelWrapper);
12690
13559
  }
12691
-
12692
13560
  if (val.fields_arr) {
12693
13561
  return await func.UI.screen.refresh_xu_attributes(SESSION_ID, val.fields_arr, val.jobNoP, new_$div);
12694
13562
  }
12695
13563
  func.events.delete_job(SESSION_ID, jobNoP);
12696
13564
  };
12697
- // if ($elm && func.UI.utils.find_in_element_data('xuData', $(SESSION_OBJ[SESSION_ID].root_element), 'xu_id', $elm.data().xuData.xu_id).length) {
12698
- if ($elm && $(`[xu-ui-id="${$elm.attr('xu-ui-id')}"]`).length) {
12699
- if (new_$div.data().xuData.paramsP) {
12700
- return await replace();
12701
- }
12702
13565
 
12703
- func.events.delete_job(SESSION_ID, jobNoP);
13566
+ if ($elm && $(`[xu-ui-id="${$elm.attr('xu-ui-id')}"]`).length && new_$div.data().xuData.paramsP) {
13567
+ return await replace();
12704
13568
  }
13569
+ func.events.delete_job(SESSION_ID, jobNoP);
12705
13570
  } catch (error) {
12706
13571
  func.events.delete_job(SESSION_ID, jobNoP);
12707
13572
  }
12708
13573
  return;
12709
13574
  }
12710
- // if (!value) {
13575
+
12711
13576
  if ($elm.prop('tagName') === 'XURENDER') {
12712
13577
  func.events.delete_job(SESSION_ID, jobNoP);
12713
13578
  return;
12714
13579
  }
12715
13580
 
12716
- let tmp_$div = $('<div>');
13581
+ const $xurender = $('<xurender>').attr('xu-ui-id', $elm.attr('xu-ui-id'));
12717
13582
 
12718
- let $xurender = $('<xurender>').attr('xu-ui-id', $elm.attr('xu-ui-id')).appendTo(tmp_$div); //.hide();
12719
- // was true before
12720
13583
  if ($elm.data().xuData.xurender_node) {
12721
13584
  $xurender.data({
12722
13585
  xuAttributes: $elm.data().xuData.xurender_node.data().xuAttributes || {},
12723
13586
  xuData: $elm.data().xuData.xurender_node.data().xuData || {},
12724
13587
  });
12725
13588
  } else {
12726
- // default new state
12727
-
12728
13589
  $xurender.data({
12729
13590
  xuAttributes: $elm.data().xuAttributes || {},
12730
13591
  xuData: $elm.data().xuData || {},
12731
13592
  });
12732
- const original_data_obj = {
13593
+ $xurender.data().xuData.original_data_obj = {
12733
13594
  nodeP: _.cloneDeep($elm.data().xuData.node_org),
12734
13595
  paramsP: $elm.data().xuData.paramsP,
12735
13596
  $container: $elm.clone(true),
12736
13597
  parent_infoP: parent_infoP,
12737
13598
  };
12738
-
12739
- $xurender.data().xuData.original_data_obj = original_data_obj;
12740
13599
  }
12741
13600
 
12742
- //remove xu-teleport trace
12743
13601
  $.each($elm.find('xu-teleport'), (key, val) => {
12744
13602
  const xuTeleportData = $(val).data().xuTeleportData || [];
12745
- for (const teleported_elm_id of xuTeleportData) {
12746
- $(`[xu-ui-id="${teleported_elm_id}"]`).remove();
12747
- }
13603
+ xuTeleportData.forEach((id) => $(`[xu-ui-id="${id}"]`).remove());
12748
13604
  });
12749
13605
 
12750
- $elm.replaceWith(tmp_$div.children());
13606
+ $elm.replaceWith($xurender);
12751
13607
  func.events.delete_job(SESSION_ID, jobNoP);
12752
- // }
12753
13608
  };
12754
- if (is_init) {
12755
- return init_render();
12756
- }
12757
- return await post_render();
12758
- };
12759
13609
 
12760
- const new_render = async function () {
12761
- var value = await func.common.get_cast_val(SESSION_ID, 'common fx', 'xu-render', 'bool', val.value);
12762
- const has_xu_render_attribute = true;
12763
- const has_xu_exp_render_attribute = $elm.data()?.xuData?.attr_exp_info?.['xu-render'] ? true : false;
12764
- const init_render = async function () {
12765
- nodeP.xu_render_made = value;
12766
- if (!value) {
12767
- if (has_xu_exp_render_attribute) {
12768
- return { has_xu_exp_render_attribute, has_xu_render_attribute, xu_render_background_processing: true };
12769
- }
12770
- return { has_xu_render_attribute, abort: true };
12771
- }
12772
- return { has_xu_exp_render_attribute, has_xu_render_attribute };
12773
- };
13610
+ return is_init ? init_render() : await post_render();
13611
+ }
12774
13612
 
12775
- const post_render = async function () {
12776
- // always come from refresh
12777
- let nodeP = $container.data().xuData.node.children[keyP];
12778
- nodeP.xu_render_made = value;
12779
- if (value) {
12780
- try {
12781
- 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 || {}));
12782
- const xu_ui_id = $elm.attr('xu-ui-id');
12783
- let new_$div = UI_WORKER_OBJ?.xu_render_cache?.[xu_ui_id + xu_render_cache_id]?.$div.clone(true);
12784
- let found_parent_vars = false;
12785
- if (new_$div) {
12786
- // validate if $div contains fields from parent ds
12787
- const parent_data = get_parent_ds_fields(SESSION_ID, paramsP.dsSessionP);
12788
- const parent_fields = Object.keys(parent_data);
12789
-
12790
- $.each(new_$div.find('*'), (key, val) => {
12791
- const _xuAttributes = $(val)?.data()?.xuAttributes;
12792
- if (found_parent_vars || !_xuAttributes) return;
12793
- for (const [attr_key, attr_val] of Object.entries(_xuAttributes)) {
12794
- if (found_parent_vars) break;
12795
- for (const [key, val] of Object.entries(parent_fields)) {
12796
- if (attr_val.includes('@' + key)) {
12797
- found_parent_vars = true;
12798
- break;
12799
- }
12800
- }
12801
- }
12802
- });
12803
- }
13613
+ // New render logic
13614
+ const has_xu_render_attribute = true;
13615
+ const has_xu_exp_render_attribute = !!xuData?.attr_exp_info?.['xu-render'];
12804
13616
 
12805
- if (!new_$div || found_parent_vars) {
12806
- UI_WORKER_OBJ.xu_render_cache[xu_ui_id + xu_render_cache_id] = { paramsP };
12807
- nodeP.xu_render_xu_ui_id = xu_ui_id;
12808
- nodeP.xu_render_cache_id = xu_render_cache_id;
12809
- 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);
12810
- const _$div = new_$div.clone(true);
12811
- UI_WORKER_OBJ.xu_render_cache[xu_ui_id + xu_render_cache_id].$div = _$div;
12812
- UI_WORKER_OBJ.xu_render_cache[xu_ui_id + xu_render_cache_id].data = _$div.data();
12813
- }
12814
- // append order handling
13617
+ const init_render = async function () {
13618
+ nodeP.xu_render_made = value;
13619
+ if (!value) {
13620
+ 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 };
13621
+ }
13622
+ return { has_xu_exp_render_attribute, has_xu_render_attribute };
13623
+ };
12815
13624
 
12816
- if (!$container.children().length) {
12817
- new_$div.appendTo($container);
12818
- } else {
12819
- // iterate the container node
12820
- let $last_elm_found = [];
12821
- $.each($container.data().xuData.node.children, (item_key, item_val) => {
12822
- // const $elm = $(`[xu-node-id="${item_val.id}"]`);
12823
- const $elm = func.UI.utils.find_in_element_data('xuData', $(SESSION_OBJ[SESSION_ID].root_element), 'nodeid', item_val.id);
12824
- if ($elm.length) {
12825
- $last_elm_found = $elm;
12826
- }
12827
- if (keyP == item_key) {
12828
- if ($last_elm_found.length) {
12829
- new_$div.after($last_elm_found);
12830
- } else {
12831
- $container.prepend(new_$div);
12832
- }
13625
+ const post_render = async function () {
13626
+ const containerNodeP = $container.data().xuData.node.children[keyP];
13627
+ containerNodeP.xu_render_made = value;
13628
+
13629
+ if (value) {
13630
+ try {
13631
+ const xu_render_cache_id = await get_xu_render_cache_str(SESSION_ID, paramsP.dsSessionP, Object.keys(xuData?.attr_exp_info?.['xu-render']?.fields || {}));
13632
+ const xu_ui_id = $elm.attr('xu-ui-id');
13633
+ const cache_key = xu_ui_id + xu_render_cache_id;
13634
+ let new_$div = UI_WORKER_OBJ?.xu_render_cache?.[cache_key]?.$div?.clone(true);
13635
+ let found_parent_vars = false;
13636
+
13637
+ if (new_$div) {
13638
+ const parent_data = get_parent_ds_fields(SESSION_ID, paramsP.dsSessionP);
13639
+ const parent_fields = Object.keys(parent_data);
13640
+
13641
+ $.each(new_$div.find('*'), (key, val) => {
13642
+ if (found_parent_vars) return;
13643
+ const _xuAttributes = $(val)?.data()?.xuAttributes;
13644
+ if (!_xuAttributes) return;
13645
+
13646
+ for (const attr_val of Object.values(_xuAttributes)) {
13647
+ if (parent_fields.some((field) => attr_val.includes('@' + field))) {
13648
+ found_parent_vars = true;
13649
+ break;
12833
13650
  }
12834
- });
12835
- }
12836
- } catch (error) {
12837
- func.events.delete_job(SESSION_ID, jobNoP);
13651
+ }
13652
+ });
12838
13653
  }
12839
- return;
12840
- }
12841
13654
 
12842
- /////////// !value ///////////
13655
+ if (!new_$div || found_parent_vars) {
13656
+ UI_WORKER_OBJ.xu_render_cache[cache_key] = { paramsP };
13657
+ containerNodeP.xu_render_xu_ui_id = xu_ui_id;
13658
+ containerNodeP.xu_render_cache_id = xu_render_cache_id;
12843
13659
 
12844
- const xu_ui_id = $elm.attr('xu-ui-id');
13660
+ 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);
12845
13661
 
12846
- const cache_str = await get_xu_render_cache_str(SESSION_ID, paramsP.dsSessionP, Object.keys($elm.data()?.xuData?.attr_exp_info?.['xu-render']?.fields || {}));
12847
- const _$div = $elm.clone(true);
12848
- UI_WORKER_OBJ.xu_render_cache[xu_ui_id + cache_str] = { $div: _$div, data: _$div.data(), paramsP };
12849
- $elm.remove();
12850
- func.events.delete_job(SESSION_ID, jobNoP);
12851
- };
12852
- if (is_init) {
12853
- return await init_render();
13662
+ const _$div = new_$div.clone(true);
13663
+ UI_WORKER_OBJ.xu_render_cache[cache_key] = { $div: _$div, data: _$div.data(), paramsP };
13664
+ }
13665
+
13666
+ // Append order handling
13667
+ if (!$container.children().length) {
13668
+ new_$div.appendTo($container);
13669
+ } else {
13670
+ let $last_elm_found = [];
13671
+ $.each($container.data().xuData.node.children, (item_key, item_val) => {
13672
+ const $elm = func.UI.utils.find_in_element_data('xuData', $(_session.root_element), 'nodeid', item_val.id);
13673
+ if ($elm.length) $last_elm_found = $elm;
13674
+ if (keyP == item_key) {
13675
+ $last_elm_found.length ? new_$div.after($last_elm_found) : $container.prepend(new_$div);
13676
+ }
13677
+ });
13678
+ }
13679
+ } catch (error) {
13680
+ func.events.delete_job(SESSION_ID, jobNoP);
13681
+ }
13682
+ return;
12854
13683
  }
12855
- return await post_render();
13684
+
13685
+ // !value
13686
+ const xu_ui_id = $elm.attr('xu-ui-id');
13687
+ const cache_str = await get_xu_render_cache_str(SESSION_ID, paramsP.dsSessionP, Object.keys(xuData?.attr_exp_info?.['xu-render']?.fields || {}));
13688
+ const _$div = $elm.clone(true);
13689
+ UI_WORKER_OBJ.xu_render_cache[xu_ui_id + cache_str] = { $div: _$div, data: _$div.data(), paramsP };
13690
+ $elm.remove();
13691
+ func.events.delete_job(SESSION_ID, jobNoP);
12856
13692
  };
12857
13693
 
12858
- if (glb.new_xu_render) {
12859
- return new_render();
12860
- }
12861
- return old_render();
13694
+ return is_init ? await init_render() : await post_render();
12862
13695
  },
13696
+
12863
13697
  'xu-show': async function ($elm, val) {
12864
- var value = await func.common.get_cast_val(SESSION_ID, 'common fx', 'xu-show', 'bool', val.value);
12865
- if (value) {
12866
- $elm.show();
12867
- }
12868
- if (!value) {
12869
- $elm.hide();
12870
- }
13698
+ const value = await func.common.get_cast_val(SESSION_ID, 'common fx', 'xu-show', 'bool', val.value);
13699
+ $elm.toggle(value);
12871
13700
  return {};
12872
13701
  },
13702
+
12873
13703
  'xu-content': async function ($elm, val) {
12874
13704
  try {
12875
13705
  $elm.html(val.value);
12876
13706
  } catch (error) {
12877
- console.warn(e);
13707
+ console.warn(error);
12878
13708
  }
12879
- return;
12880
13709
  },
13710
+
12881
13711
  'xu-text': async function ($elm, val) {
12882
13712
  try {
12883
13713
  $elm.text(val.value);
12884
13714
  } catch (error) {
12885
- console.warn(e);
13715
+ console.warn(error);
12886
13716
  }
12887
- return;
12888
13717
  },
13718
+
12889
13719
  'xu-html': async function ($elm, val) {
12890
13720
  try {
12891
13721
  $elm.html(val.value);
12892
13722
  } catch (error) {
12893
- console.warn(e);
13723
+ console.warn(error);
12894
13724
  }
12895
- return;
12896
13725
  },
13726
+
12897
13727
  'xu-for': async function ($elm, data) {
12898
- // exit if call from rendered xu-for item to prevent infante loop (parent_infoP?.iterate_info indicate call from rendered item)
12899
- if (parent_infoP?.iterate_info) return {};
12900
- if (!data.value) return {};
13728
+ if (parent_infoP?.iterate_info || !data.value) return {};
13729
+
12901
13730
  try {
12902
- // 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.
12903
13731
  let arr = data.value;
12904
-
12905
- // find reference source field
12906
13732
  let reference_source_obj;
12907
-
12908
13733
  const _progFields = await func.datasource.get_progFields(SESSION_ID, paramsP.dsSessionP);
13734
+ const view_field_obj = func.common.find_item_by_key(_progFields, 'field_id', data.value);
12909
13735
 
12910
- let view_field_obj = func.common.find_item_by_key(_progFields, 'field_id', data.value);
12911
- // detect if data.value (xu-for) is reference field_id by checking if exist in the dataset
12912
13736
  if (view_field_obj) {
12913
- // xu-for is reference field_id
12914
13737
  reference_source_obj = await func.datasource.get_value(SESSION_ID, data.value, paramsP.dsSessionP);
12915
13738
  arr = reference_source_obj?.ret?.value;
12916
13739
  } else {
12917
- // xu-for is actual data
12918
13740
  if (typeof data.value === 'string') {
12919
13741
  arr = eval(data.value.replaceAll('\\', ''));
12920
13742
  }
@@ -12923,59 +13745,44 @@ func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $
12923
13745
  }
12924
13746
  }
12925
13747
 
12926
- const custom_iterator_key = $elm.data().xuData.iterator_key;
12927
- const custom_iterator_val = $elm.data().xuData.iterator_val;
12928
-
12929
- let iterator_key = custom_iterator_key;
12930
- let iterator_val = custom_iterator_val;
12931
- let is_key_dynamic_field, is_val_dynamic_field;
12932
-
12933
- // custom FOR_VAL name or namespaced default name
12934
- if (!custom_iterator_key) {
12935
- is_key_dynamic_field = true;
12936
-
12937
- iterator_key = '_FOR_KEY';
12938
- }
12939
-
12940
- if (!custom_iterator_val) {
12941
- is_val_dynamic_field = true;
13748
+ const custom_iterator_key = xuData.iterator_key;
13749
+ const custom_iterator_val = xuData.iterator_val;
13750
+ const iterator_key = custom_iterator_key || '_FOR_KEY';
13751
+ const iterator_val = custom_iterator_val || '_FOR_VAL';
13752
+ const is_key_dynamic_field = !custom_iterator_key;
13753
+ const is_val_dynamic_field = !custom_iterator_val;
12942
13754
 
12943
- iterator_val = '_FOR_VAL';
12944
- }
12945
-
12946
- var i = 0;
12947
- for await (let [_key, _val] of Object.entries(arr)) {
12948
- if (_.isArray(arr)) {
12949
- _key = Number(_key);
12950
- }
13755
+ const set_value = async function (is_dynamic_field, currentRecordId, field_id, value) {
13756
+ if (is_dynamic_field) {
13757
+ func.datasource.add_dynamic_field_to_ds(SESSION_ID, paramsP.dsSessionP, field_id, value);
13758
+ } else {
13759
+ const _progFields = await func.datasource.get_progFields(SESSION_ID, paramsP.dsSessionP);
13760
+ const view_field_obj = func.common.find_item_by_key(_progFields, 'field_id', field_id);
12951
13761
 
12952
- const set_value = async function (is_dynamic_field, currentRecordId, field_id, value) {
12953
- if (is_dynamic_field) {
12954
- func.datasource.add_dynamic_field_to_ds(SESSION_ID, paramsP.dsSessionP, field_id, value);
12955
- } else {
12956
- const _progFields = await func.datasource.get_progFields(SESSION_ID, paramsP.dsSessionP);
12957
-
12958
- let view_field_obj = func.common.find_item_by_key(_progFields, 'field_id', field_id);
12959
- if (view_field_obj) {
12960
- let _ds = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP];
12961
- try {
12962
- const row_idx = func.common.find_ROWID_idx(_ds, currentRecordId);
12963
- _ds.data_feed.rows[row_idx][field_id] = value;
12964
- } catch (err) {
12965
- console.error(err);
12966
- }
12967
- } else {
12968
- console.error('field not exist in dataset for xu-for method');
13762
+ if (view_field_obj) {
13763
+ const ds = _session.DS_GLB[paramsP.dsSessionP];
13764
+ try {
13765
+ const row_idx = func.common.find_ROWID_idx(ds, currentRecordId);
13766
+ ds.data_feed.rows[row_idx][field_id] = value;
13767
+ } catch (err) {
13768
+ console.error(err);
12969
13769
  }
13770
+ } else {
13771
+ console.error('field not exist in dataset for xu-for method');
12970
13772
  }
12971
- };
13773
+ }
13774
+ };
13775
+
13776
+ const currentRecordId = _ds.currentRecordId.toString();
13777
+ let i = 0;
12972
13778
 
12973
- var currentRecordId = SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP].currentRecordId.toString();
13779
+ for (let [_key, _val] of Object.entries(arr)) {
13780
+ if (_.isArray(arr)) _key = Number(_key);
12974
13781
 
12975
13782
  await set_value(is_key_dynamic_field, currentRecordId, iterator_key, _key);
12976
13783
  await set_value(is_val_dynamic_field, currentRecordId, iterator_val, _val);
12977
13784
 
12978
- var iterate_info = {
13785
+ const iterate_info = {
12979
13786
  _val,
12980
13787
  _key,
12981
13788
  iterator_key,
@@ -12984,26 +13791,13 @@ func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $
12984
13791
  is_val_dynamic_field,
12985
13792
  reference_source_obj,
12986
13793
  };
12987
- // let _parent_info = _.cloneDeep(parent_infoP) || {};
12988
- let _parent_info = klona.klona(parent_infoP) || {};
13794
+
13795
+ const _parent_info = klona.klona(parent_infoP) || {};
12989
13796
  _parent_info.iterate_info = iterate_info;
12990
13797
 
12991
- const $divP = await func.UI.screen.render_ui_tree(
12992
- SESSION_ID,
12993
- $container,
12994
- nodeP,
12995
- _parent_info, //parent_infoP ? _.cloneDeep(_parent_info) : null,
12996
- paramsP,
12997
- jobNoP,
12998
- null,
12999
- i,
13000
- null,
13001
- nodeP,
13002
- null,
13003
- $root_container,
13004
- );
13798
+ const $divP = await func.UI.screen.render_ui_tree(SESSION_ID, $container, nodeP, _parent_info, paramsP, jobNoP, null, i, null, nodeP, null, $root_container);
13005
13799
 
13006
- $.each($divP.children(), function (key, val) {
13800
+ $.each($divP.children(), (key, val) => {
13007
13801
  if ($(val)?.data()?.xuData) {
13008
13802
  $(val).data().xuData.iterate_info = iterate_info;
13009
13803
  }
@@ -13011,106 +13805,87 @@ func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $
13011
13805
 
13012
13806
  i++;
13013
13807
  }
13808
+
13014
13809
  $elm.remove();
13015
13810
  return { abort: true };
13016
13811
  } catch (e) {
13017
- console.error(' Iterator Arr parse error');
13812
+ console.error('Iterator Arr parse error', e);
13018
13813
  return { abort: true };
13019
13814
  }
13020
13815
  },
13816
+
13021
13817
  'xu-for-key': async function ($elm, val) {
13022
- $elm.data().xuData.iterator_key = val.value;
13818
+ xuData.iterator_key = val.value;
13023
13819
  return {};
13024
13820
  },
13821
+
13025
13822
  'xu-for-val': async function ($elm, val) {
13026
- $elm.data().xuData.iterator_val = val.value;
13823
+ xuData.iterator_val = val.value;
13027
13824
  return {};
13028
13825
  },
13826
+
13029
13827
  'xu-class': async function ($elm, val) {
13030
13828
  try {
13031
- const classes_string = val.value;
13032
- // let obj = _.isString(classes_string) ? JSON.parse(classes_string) : _.defaults(classes_string, {});
13033
-
13034
- const classes_obj = _.isString(classes_string) ? JSON.parse(classes_string) : _.defaults(classes_string, {});
13035
- for await (const [cla, cond] of Object.entries(classes_obj)) {
13036
- let res = await func.expression.get(
13037
- SESSION_ID,
13038
- cond,
13039
- paramsP.dsSessionP,
13040
- 'UI Attr EXP',
13041
- $elm.data().xuData.currentRecordId, // SESSION_OBJ[SESSION_ID].DS_GLB[paramsP.dsSessionP].currentRecordId
13042
- null,
13043
- null,
13044
- null,
13045
- null,
13046
- null,
13047
- $elm.data().xuData.iterate_info,
13048
- );
13829
+ const classes_obj = _.isString(val.value) ? JSON.parse(val.value) : _.defaults(val.value, {});
13049
13830
 
13050
- if (res.result) {
13051
- $elm.addClass(cla);
13052
- } else {
13053
- $elm.removeClass(cla);
13054
- }
13831
+ for (const [cla, cond] of Object.entries(classes_obj)) {
13832
+ const res = await func.expression.get(SESSION_ID, cond, paramsP.dsSessionP, 'UI Attr EXP', xuData.currentRecordId, null, null, null, null, null, xuData.iterate_info);
13055
13833
 
13056
- $elm.data().xuData.debug_info.attribute_stat['xu-class'] = $elm.attr('class');
13834
+ $elm.toggleClass(cla, res.result);
13057
13835
  }
13836
+
13837
+ xuData.debug_info.attribute_stat['xu-class'] = $elm.attr('class');
13058
13838
  return {};
13059
13839
  } catch (e) {
13060
13840
  console.warn('parse error:' + val.value);
13061
13841
  return { abort: true };
13062
13842
  }
13063
13843
  },
13064
- 'xu-exp': async function ($elm, val) {
13065
- let exp = val.value === null ? true : val.value;
13066
13844
 
13067
- 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);
13068
-
13069
- let value = func.UI.screen.fix_val_defaults(val.key, exp_ret.result);
13845
+ 'xu-exp': async function ($elm, val) {
13846
+ const exp = val.value === null ? true : val.value;
13847
+ 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);
13070
13848
 
13071
- var new_val = {
13072
- key: val.key,
13073
- value,
13074
- };
13849
+ const value = func.UI.screen.fix_val_defaults(val.key, exp_ret.result);
13850
+ const new_val = { key: val.key, value };
13075
13851
 
13076
- if (nodeP.tagName.substr(0, 3) === 'xu-') {
13077
- if (tag_fx[nodeP.tagName][new_val.key]) {
13078
- return await tag_fx[nodeP.tagName][new_val.key]($elm, new_val);
13852
+ if (isXuTag) {
13853
+ if (tag_fx[nodeTag]?.[new_val.key]) {
13854
+ return await tag_fx[nodeTag][new_val.key]($elm, new_val);
13079
13855
  }
13080
- console.warn(`attribute ${new_val.key} not found for ${nodeP.tagName}`);
13856
+ console.warn(`attribute ${new_val.key} not found for ${nodeTag}`);
13081
13857
  return {};
13082
13858
  }
13083
- if (!$elm.data().xuData) return;
13084
-
13085
- $elm.data().xuData.debug_info.attribute_stat[new_val.key] = new_val.value;
13086
13859
 
13087
- // IGNORE UNDEFINED or NULL ATTRIBUTES
13088
- if (typeof new_val.value === 'undefined' || new_val.value === null) {
13089
- return {};
13090
- }
13860
+ if (!xuData) return {};
13861
+ xuData.debug_info.attribute_stat[new_val.key] = new_val.value;
13091
13862
 
13092
- // IGNORE ATTRIBUTES WITH EMPTY VALUES
13093
- if (glb.solid_attributes.includes(new_val.key) && !new_val.value) {
13094
- return {};
13095
- }
13863
+ if (new_val.value === undefined || new_val.value === null) return {};
13864
+ if (glb.solid_attributes.includes(new_val.key) && !new_val.value) return {};
13096
13865
 
13097
- if (new_val.key.substr(0, 2) === 'xu') {
13866
+ if (new_val.key.startsWith('xu')) {
13098
13867
  return await common_fx[new_val.key]($elm, new_val);
13099
13868
  }
13100
13869
 
13101
13870
  $elm.attr(new_val.key, ($elm.attr(new_val.key) || '') + new_val.value);
13102
13871
  return {};
13103
13872
  },
13873
+
13104
13874
  'xu-on': async function ($elm, val) {
13105
13875
  CLIENT_ACTIVITY_TS = Date.now();
13106
13876
  const trigger = val.key.split('xu-on:')[1].toLowerCase();
13877
+
13107
13878
  $elm.on(trigger, async function (evt) {
13108
13879
  const _$elm = $(evt.currentTarget);
13109
- if (_.isEmpty(_$elm.data().xuAttributes)) return;
13880
+ const xuAttributes = _$elm.data().xuAttributes;
13881
+ if (_.isEmpty(xuAttributes)) return;
13110
13882
 
13111
- for await (const [key, val] of Object.entries(_$elm.data().xuAttributes['xu-on:' + evt.type])) {
13883
+ const handlers = xuAttributes['xu-on:' + evt.type];
13884
+ if (!handlers) return;
13885
+
13886
+ for (const [key, val] of Object.entries(handlers)) {
13112
13887
  if (!_.isEmpty(val.props.condition)) {
13113
- const expCond = await func.expression.get(SESSION_ID, val.props.condition, paramsP.dsSessionP, 'condition', paramsP.recordid); // execute expression
13888
+ const expCond = await func.expression.get(SESSION_ID, val.props.condition, paramsP.dsSessionP, 'condition', paramsP.recordid);
13114
13889
  if (!expCond.result) continue;
13115
13890
  }
13116
13891
 
@@ -13118,18 +13893,9 @@ func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $
13118
13893
  evt[val.event_modifiers]();
13119
13894
  }
13120
13895
 
13121
- // if (val.handler === 'custom') {
13122
13896
  if (val.workflow) {
13123
- // do BL
13124
- for await (const [key2, val2] of Object.entries(val.workflow)) {
13125
- // var cond = val2.data.enabled;
13126
- // if (val2.data.enabled && val2.props.condition) {
13127
- // expCond = await func.expression.get(SESSION_ID, val2.props.condition, paramsP.dsSessionP, 'condition', paramsP.recordid); // execute expression
13128
- // cond = expCond.result;
13129
- // }
13130
- // if (!cond) continue;
13131
-
13132
- if (!val2.data.enabled) continue; // added Jul 3, 25 - condition validate on execution
13897
+ for (const [key2, val2] of Object.entries(val.workflow)) {
13898
+ if (!val2.data.enabled) continue;
13133
13899
 
13134
13900
  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);
13135
13901
  }
@@ -13138,111 +13904,91 @@ func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $
13138
13904
  });
13139
13905
  return {};
13140
13906
  },
13907
+
13141
13908
  'xu-script': async function ($elm, val) {
13142
- var checkExist = setInterval(async function () {
13909
+ const checkExist = setInterval(async function () {
13143
13910
  if ($elm.is(':visible')) {
13144
13911
  try {
13145
- // var res = eval('(' + val.value + ')');
13146
- // const fn = `(function(el) {
13147
- // ${val.value}
13148
- // })(document.querySelector(\`[xu-ui-id="${$elm.attr('xu-ui-id')}"]\`));`;
13149
-
13150
- const fn = `async (el)=>{${val.value} };`;
13151
-
13152
- var res = eval(fn);
13153
- await res($elm[0]);
13154
- // if (typeof res === 'function') {
13155
- // res($elm[0]);
13156
- // }
13912
+ const fn = eval(`async (el)=>{${val.value}}`);
13913
+ await fn($elm[0]);
13157
13914
  } catch (e) {
13158
13915
  eval(val.value);
13159
13916
  }
13160
-
13161
13917
  clearInterval(checkExist);
13162
13918
  }
13163
- }, 100); // check every 100ms
13164
-
13919
+ }, 100);
13165
13920
  return {};
13166
13921
  },
13922
+
13167
13923
  'xu-style-global': async function ($elm, val) {
13168
13924
  $('head').append(`<style>${val.value}</style>`);
13169
13925
  return {};
13170
13926
  },
13171
- 'xu-style': async function ($elm, val) {
13172
- var cssString = val.value;
13173
-
13174
- var parser = new cssjs();
13175
-
13176
- var parsed = parser.parseCSS(cssString);
13177
- var xuUiId = `[xu-ui-id="${$elm.attr('xu-ui-id')}"]`;
13178
-
13179
- $.each(parsed, function (key, val) {
13180
- var selectors_arr = val.selector.split(',');
13181
-
13182
- $.each(selectors_arr, function (key2, val2) {
13183
- selectors_arr[key2] = `${xuUiId} ${val2}, ${xuUiId}${val2}`;
13184
- // console.log(new_selector);
13185
- });
13186
13927
 
13187
- val.selector = selectors_arr.join(',');
13188
- // console.log(parsed);
13928
+ 'xu-style': async function ($elm, val) {
13929
+ const parser = new cssjs();
13930
+ const parsed = parser.parseCSS(val.value);
13931
+ const xuUiId = `[xu-ui-id="${$elm.attr('xu-ui-id')}"]`;
13932
+
13933
+ parsed.forEach((rule) => {
13934
+ rule.selector = rule.selector
13935
+ .split(',')
13936
+ .map((sel) => `${xuUiId} ${sel}, ${xuUiId}${sel}`)
13937
+ .join(',');
13189
13938
  });
13190
13939
 
13191
- var newCSSString = parser.getCSSForEditor(parsed);
13192
-
13193
- $('head').append(`<style>${newCSSString}</style>`);
13940
+ $('head').append(`<style>${parser.getCSSForEditor(parsed)}</style>`);
13194
13941
  return {};
13195
13942
  },
13943
+
13196
13944
  'xu-cdn': async function ($elm, val) {
13197
- for await (const [key, resource] of Object.entries(val.value)) {
13945
+ for (const resource of Object.values(val.value)) {
13198
13946
  await load_cdn(resource);
13199
13947
  }
13200
-
13201
13948
  return {};
13202
13949
  },
13203
- 'xu-ui-plugin': async function ($elm, val) {
13204
- var _session = SESSION_OBJ[SESSION_ID];
13205
13950
 
13206
- for await (const [plugin_name, value] of Object.entries(val.value)) {
13951
+ 'xu-ui-plugin': async function ($elm, val) {
13952
+ for (const [plugin_name, value] of Object.entries(val.value)) {
13207
13953
  const _plugin = APP_OBJ[_session.app_id]?.app_plugins_purchased?.[plugin_name];
13208
- if (_plugin?.installed && _plugin?.manifest?.['runtime.mjs']?.exist && _plugin?.manifest?.['index.mjs']?.exist && value.enabled) {
13209
- if (_plugin?.manifest?.['runtime.mjs'].dist && _plugin?.manifest?.['runtime.mjs']?.css) {
13210
- const plugin_runtime_css_url = await func.utils.get_plugin_npm_cdn(SESSION_ID, plugin_name, 'dist/runtime.css');
13211
- func.utils.load_css_on_demand(plugin_runtime_css_url);
13212
- }
13213
13954
 
13214
- const plugin_index_src = await func.utils.get_plugin_npm_cdn(SESSION_ID, plugin_name, `${_plugin.manifest['index.mjs'].dist ? 'dist/' : ''}index.mjs`);
13955
+ if (!_plugin?.installed || !_plugin?.manifest?.['runtime.mjs']?.exist || !_plugin?.manifest?.['index.mjs']?.exist || !value.enabled) continue;
13215
13956
 
13216
- const plugin_index_resources = await import(plugin_index_src);
13957
+ if (_plugin.manifest['runtime.mjs'].dist && _plugin.manifest['runtime.mjs'].css) {
13958
+ const css_url = await func.utils.get_plugin_npm_cdn(SESSION_ID, plugin_name, 'dist/runtime.css');
13959
+ func.utils.load_css_on_demand(css_url);
13960
+ }
13217
13961
 
13218
- let properties = _.cloneDeep(plugin_index_resources.properties);
13219
- for await (let [prop_name, prop_val] of Object.entries(properties)) {
13220
- prop_val.value = value?.attributes?.[prop_name];
13221
- if (value?.attributes?.[`xu-exp:${prop_name}`]) {
13222
- const res = await func.expression.get(SESSION_ID, value?.attributes?.[`xu-exp:${prop_name}`], paramsP.dsSessionP, 'UI Attr EXP');
13223
- prop_val.value = res.result;
13224
- }
13225
- }
13226
- // $elm.data().xu_ui_plugin = { properties };
13227
- const plugin_runtime_src = await func.utils.get_plugin_npm_cdn(SESSION_ID, plugin_name, `${_plugin.manifest['runtime.mjs'].dist ? 'dist/' : ''}runtime.mjs`);
13962
+ const plugin_index_src = await func.utils.get_plugin_npm_cdn(SESSION_ID, plugin_name, `${_plugin.manifest['index.mjs'].dist ? 'dist/' : ''}index.mjs`);
13228
13963
 
13229
- const plugin_runtime_resources = await import(plugin_runtime_src);
13964
+ const plugin_index_resources = await import(plugin_index_src);
13965
+ const properties = _.cloneDeep(plugin_index_resources.properties);
13230
13966
 
13231
- if (plugin_runtime_resources.cdn && typeof _.isArray(plugin_runtime_resources.cdn)) {
13232
- for await (const resource of plugin_runtime_resources.cdn) {
13233
- await load_cdn(resource);
13234
- }
13967
+ for (const [prop_name, prop_val] of Object.entries(properties)) {
13968
+ prop_val.value = value?.attributes?.[prop_name];
13969
+ if (value?.attributes?.[`xu-exp:${prop_name}`]) {
13970
+ const res = await func.expression.get(SESSION_ID, value.attributes[`xu-exp:${prop_name}`], paramsP.dsSessionP, 'UI Attr EXP');
13971
+ prop_val.value = res.result;
13235
13972
  }
13973
+ }
13236
13974
 
13237
- if (plugin_runtime_resources.fn) {
13238
- await plugin_runtime_resources.fn(plugin_name, $elm?.[0], properties);
13239
- // await plugin_runtime_resources.fn(plugin_name, $elm?.[0], $elm.data().xu_ui_plugin.properties);
13975
+ const plugin_runtime_src = await func.utils.get_plugin_npm_cdn(SESSION_ID, plugin_name, `${_plugin.manifest['runtime.mjs'].dist ? 'dist/' : ''}runtime.mjs`);
13976
+
13977
+ const plugin_runtime_resources = await import(plugin_runtime_src);
13978
+
13979
+ if (plugin_runtime_resources.cdn && _.isArray(plugin_runtime_resources.cdn)) {
13980
+ for (const resource of plugin_runtime_resources.cdn) {
13981
+ await load_cdn(resource);
13240
13982
  }
13241
13983
  }
13242
- }
13243
13984
 
13985
+ if (plugin_runtime_resources.fn) {
13986
+ await plugin_runtime_resources.fn(plugin_name, $elm?.[0], properties);
13987
+ }
13988
+ }
13244
13989
  return {};
13245
13990
  },
13991
+
13246
13992
  'xu-store': async function ($elm, val) {
13247
13993
  try {
13248
13994
  const fields_obj = JSON5.parse(val.value);
@@ -13254,43 +14000,135 @@ func.UI.screen.execute_xu_functions = async function (SESSION_ID, is_skeleton, $
13254
14000
  }
13255
14001
  return {};
13256
14002
  },
14003
+
13257
14004
  'xu-viewport': async function ($elm, val) {
13258
- // functionality in draw_html_element
13259
14005
  return {};
13260
14006
  },
13261
14007
  };
13262
14008
 
13263
- if (nodeP.tagName.substr(0, 3) === 'xu-') {
14009
+ const tag_fx = {
14010
+ 'xu-panel': {
14011
+ program: async function ($elm, val) {
14012
+ const init_program = async function () {
14013
+ async function render_panel() {
14014
+ const prog_id = val.value?.prog || val.value;
14015
+ const params_obj = await get_params_obj_new(SESSION_ID, prog_id, nodeP, paramsP.dsSessionP);
14016
+ 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);
14017
+
14018
+ const containerData = $container.data();
14019
+ if (containerData.xuData) {
14020
+ containerData.xuData.xuPanelProps = elmData.xuAttributes;
14021
+ containerData.xuData.xuPanelData = ret_panel.data();
14022
+ }
14023
+ return { $new_div: ret_panel };
14024
+ }
14025
+
14026
+ if (!val.value) val.value = '_empty_panel_program';
14027
+ return await render_panel();
14028
+ };
14029
+
14030
+ const alter_program = async function () {
14031
+ async function render_panel() {
14032
+ const program = val.value?.prog || val.value;
14033
+ const $wrapper = $('<div>');
14034
+ 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, '');
14035
+
14036
+ const params_obj = await get_params_obj_new(SESSION_ID, program, nodeP, paramsP.dsSessionP);
14037
+ 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);
14038
+
14039
+ await func.UI.screen.panel_post_render_handler(SESSION_ID, $elm, ret_init, nodeP, $div.clone(true), jobNoP);
14040
+
14041
+ return { $new_div: ret_init, abort: true };
14042
+ }
14043
+
14044
+ if (!val.value) return { abort: true };
14045
+ await render_panel();
14046
+ return { abort: true };
14047
+ };
14048
+
14049
+ return is_init ? await init_program() : await alter_program();
14050
+ },
14051
+
14052
+ 'xu-render': async function ($elm, val) {
14053
+ return await common_fx['xu-render']($elm, val, true);
14054
+ },
14055
+
14056
+ 'xu-ref': async function ($elm, val) {
14057
+ return await common_fx['xu-ref']($container, val, $container.data().xuData.xuPanelData.xuData.paramsP.dsSessionP);
14058
+ },
14059
+ },
14060
+
14061
+ 'xu-teleport': {
14062
+ to: async function ($elm, val) {
14063
+ if (!glb.new_xu_render && val.value) {
14064
+ if ($elm?.parent()?.data()?.xuData?.length) {
14065
+ $elm.parent().data('xuTeleportData', []);
14066
+ for (const [key, node] of Object.entries(nodeP.children)) {
14067
+ 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);
14068
+ $elm.parent().data().xuTeleportData.push($teleport_elm.attr('xu-ui-id'));
14069
+ $teleport_elm.attr('xu-teleport-parent-id', $elm.parent().attr('xu-ui-id'));
14070
+ }
14071
+ $elm.remove();
14072
+ } else {
14073
+ $elm.data('xuTeleportData', []).attr('hidden', true);
14074
+ for (const [key, node] of Object.entries(nodeP.children)) {
14075
+ const $to_container = $(val.value);
14076
+ if (!$to_container?.length) {
14077
+ return console.error(`container ${val.value} for xuTeleportData not found`);
14078
+ }
14079
+ 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);
14080
+ $elm.data().xuTeleportData.push($teleport_elm.attr('xu-ui-id'));
14081
+ $teleport_elm.attr('xu-teleport-parent-id', $elm.attr('xu-ui-id'));
14082
+ }
14083
+ }
14084
+ return { abort: true };
14085
+ }
14086
+ return {};
14087
+ },
14088
+
14089
+ 'xu-render': async function ($elm, val) {
14090
+ return await common_fx['xu-render']($elm, val, true);
14091
+ },
14092
+
14093
+ 'xu-show': async function ($elm, val) {
14094
+ return await common_fx['xu-show']($elm, val, true);
14095
+ },
14096
+ },
14097
+ };
14098
+
14099
+ // Main execution logic
14100
+ if (isXuTag) {
13264
14101
  if (xu_func === 'xu-exp') {
13265
14102
  return common_fx[xu_func]($elm, val);
13266
14103
  }
13267
14104
 
13268
- if (tag_fx?.[nodeP.tagName]?.[xu_func]) {
13269
- let ret = await tag_fx[nodeP.tagName][xu_func]($elm, val);
13270
- return ret;
14105
+ if (tag_fx?.[nodeTag]?.[xu_func]) {
14106
+ return await tag_fx[nodeTag][xu_func]($elm, val);
13271
14107
  }
13272
- // if (xu_func !== "tree_id")
13273
- console.warn(`attribute ${xu_func} not found for ${nodeP.tagName}`);
13274
- return {};
13275
- }
13276
- if (_.isEmpty($elm.data())) {
14108
+
14109
+ console.warn(`attribute ${xu_func} not found for ${nodeTag}`);
13277
14110
  return {};
13278
14111
  }
13279
- if (!$elm.data().xuData.debug_info.attribute_stat) {
13280
- $elm.data().xuData.debug_info.attribute_stat = {};
14112
+
14113
+ if (_.isEmpty(elmData)) return {};
14114
+
14115
+ if (!xuData.debug_info.attribute_stat) {
14116
+ xuData.debug_info.attribute_stat = {};
13281
14117
  }
14118
+
13282
14119
  if (xu_func !== 'xu-exp') {
13283
- $elm.data().xuData.debug_info.attribute_stat[xu_func] = val.value;
14120
+ xuData.debug_info.attribute_stat[xu_func] = val.value;
13284
14121
  }
14122
+
13285
14123
  try {
13286
14124
  if (!common_fx[xu_func]) {
13287
- console.warn('invalid xu-tag', xu_func, error);
14125
+ console.warn('invalid xu-tag', xu_func);
13288
14126
  return {};
13289
14127
  }
13290
-
13291
14128
  return await common_fx[xu_func]($elm, val);
13292
14129
  } catch (error) {
13293
- debugger;
14130
+ console.error('execute_xu_functions error:', error);
14131
+ return {};
13294
14132
  }
13295
14133
  };
13296
14134