@saltcorn/data 1.5.0-beta.9 → 1.5.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/base-plugin/actions.d.ts +221 -145
- package/dist/base-plugin/actions.d.ts.map +1 -1
- package/dist/base-plugin/actions.js +80 -12
- package/dist/base-plugin/actions.js.map +1 -1
- package/dist/base-plugin/fileviews.d.ts +3 -3
- package/dist/base-plugin/fileviews.js +20 -9
- package/dist/base-plugin/fileviews.js.map +1 -1
- package/dist/base-plugin/index.d.ts +2 -2
- package/dist/base-plugin/index.d.ts.map +1 -1
- package/dist/base-plugin/types.d.ts.map +1 -1
- package/dist/base-plugin/types.js +8 -5
- package/dist/base-plugin/types.js.map +1 -1
- package/dist/base-plugin/viewtemplates/edit.d.ts +6 -2
- package/dist/base-plugin/viewtemplates/edit.d.ts.map +1 -1
- package/dist/base-plugin/viewtemplates/edit.js +17 -341
- package/dist/base-plugin/viewtemplates/edit.js.map +1 -1
- package/dist/base-plugin/viewtemplates/filter.d.ts.map +1 -1
- package/dist/base-plugin/viewtemplates/filter.js +9 -3
- package/dist/base-plugin/viewtemplates/filter.js.map +1 -1
- package/dist/base-plugin/viewtemplates/show.d.ts.map +1 -1
- package/dist/base-plugin/viewtemplates/show.js +1 -0
- package/dist/base-plugin/viewtemplates/show.js.map +1 -1
- package/dist/base-plugin/viewtemplates/viewable_fields.d.ts +16 -0
- package/dist/base-plugin/viewtemplates/viewable_fields.d.ts.map +1 -1
- package/dist/base-plugin/viewtemplates/viewable_fields.js +340 -3
- package/dist/base-plugin/viewtemplates/viewable_fields.js.map +1 -1
- package/dist/base-plugin/viewtemplates/workflow-room.d.ts.map +1 -1
- package/dist/base-plugin/viewtemplates/workflow-room.js +1 -1
- package/dist/base-plugin/viewtemplates/workflow-room.js.map +1 -1
- package/dist/db/connect.d.ts.map +1 -1
- package/dist/db/connect.js +4 -1
- package/dist/db/connect.js.map +1 -1
- package/dist/db/state.d.ts +11 -7
- package/dist/db/state.d.ts.map +1 -1
- package/dist/db/state.js +78 -12
- package/dist/db/state.js.map +1 -1
- package/dist/mobile-mocks/npm/dockerode.d.ts +1 -0
- package/dist/mobile-mocks/npm/dockerode.d.ts.map +1 -0
- package/dist/mobile-mocks/npm/dockerode.js +2 -0
- package/dist/mobile-mocks/npm/dockerode.js.map +1 -0
- package/dist/models/config.d.ts.map +1 -1
- package/dist/models/config.js +55 -12
- package/dist/models/config.js.map +1 -1
- package/dist/models/email.js.map +1 -1
- package/dist/models/expression.d.ts.map +1 -1
- package/dist/models/expression.js +29 -0
- package/dist/models/expression.js.map +1 -1
- package/dist/models/field.d.ts +5 -3
- package/dist/models/field.d.ts.map +1 -1
- package/dist/models/field.js +8 -2
- package/dist/models/field.js.map +1 -1
- package/dist/models/file.d.ts +18 -1
- package/dist/models/file.d.ts.map +1 -1
- package/dist/models/file.js +361 -43
- package/dist/models/file.js.map +1 -1
- package/dist/models/form.d.ts.map +1 -1
- package/dist/models/form.js.map +1 -1
- package/dist/models/index.d.ts.map +1 -1
- package/dist/models/internal/push_message_helper.d.ts +42 -12
- package/dist/models/internal/push_message_helper.d.ts.map +1 -1
- package/dist/models/internal/push_message_helper.js +117 -50
- package/dist/models/internal/push_message_helper.js.map +1 -1
- package/dist/models/internal/s3_helpers.d.ts +54 -0
- package/dist/models/internal/s3_helpers.d.ts.map +1 -0
- package/dist/models/internal/s3_helpers.js +561 -0
- package/dist/models/internal/s3_helpers.js.map +1 -0
- package/dist/models/model.d.ts +1 -1
- package/dist/models/model.d.ts.map +1 -1
- package/dist/models/model.js.map +1 -1
- package/dist/models/notification.d.ts.map +1 -1
- package/dist/models/notification.js +2 -5
- package/dist/models/notification.js.map +1 -1
- package/dist/models/page.d.ts +1 -0
- package/dist/models/page.d.ts.map +1 -1
- package/dist/models/page.js +27 -24
- package/dist/models/page.js.map +1 -1
- package/dist/models/plugin.d.ts +11 -3
- package/dist/models/plugin.d.ts.map +1 -1
- package/dist/models/plugin.js +51 -12
- package/dist/models/plugin.js.map +1 -1
- package/dist/models/s3_helpers.d.ts +54 -0
- package/dist/models/s3_helpers.d.ts.map +1 -0
- package/dist/models/s3_helpers.js +505 -0
- package/dist/models/s3_helpers.js.map +1 -0
- package/dist/models/scheduler.d.ts.map +1 -1
- package/dist/models/scheduler.js +4 -1
- package/dist/models/scheduler.js.map +1 -1
- package/dist/models/table.d.ts +8 -3
- package/dist/models/table.d.ts.map +1 -1
- package/dist/models/table.js +121 -32
- package/dist/models/table.js.map +1 -1
- package/dist/models/user.d.ts +4 -4
- package/dist/models/user.d.ts.map +1 -1
- package/dist/models/user.js.map +1 -1
- package/dist/models/view.js +1 -1
- package/dist/models/view.js.map +1 -1
- package/dist/models/workflow_run.d.ts +1 -1
- package/dist/models/workflow_run.d.ts.map +1 -1
- package/dist/models/workflow_run.js +8 -2
- package/dist/models/workflow_run.js.map +1 -1
- package/dist/models/workflow_step.js +1 -1
- package/dist/models/workflow_step.js.map +1 -1
- package/dist/plugin-helper.d.ts.map +1 -1
- package/dist/plugin-helper.js +139 -15
- package/dist/plugin-helper.js.map +1 -1
- package/dist/standard-menu.js +2 -2
- package/dist/standard-menu.js.map +1 -1
- package/dist/test-utils/mocks.d.ts +203 -0
- package/dist/test-utils/mocks.d.ts.map +1 -0
- package/dist/test-utils/mocks.js +329 -0
- package/dist/test-utils/mocks.js.map +1 -0
- package/dist/tests/assertions.d.ts.map +1 -1
- package/dist/tests/assertions.js +10 -9
- package/dist/tests/assertions.js.map +1 -1
- package/dist/tests/auth.test.js +0 -68
- package/dist/tests/auth.test.js.map +1 -1
- package/dist/tests/calc.test.js +3 -62
- package/dist/tests/calc.test.js.map +1 -1
- package/dist/tests/exact_views.test.js +14 -14
- package/dist/tests/exact_views.test.js.map +1 -1
- package/dist/tests/show.test.js +1 -1
- package/dist/tests/show.test.js.map +1 -1
- package/dist/tests/table.test.js +0 -37
- package/dist/tests/table.test.js.map +1 -1
- package/dist/tests/table_sync_info.test.d.ts +2 -0
- package/dist/tests/table_sync_info.test.d.ts.map +1 -0
- package/dist/tests/table_sync_info.test.js +62 -0
- package/dist/tests/table_sync_info.test.js.map +1 -0
- package/dist/tests/user.test.js +4 -29
- package/dist/tests/user.test.js.map +1 -1
- package/dist/tests/view.test.js +0 -3
- package/dist/tests/view.test.js.map +1 -1
- package/dist/utils.d.ts +11 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +33 -3
- package/dist/utils.js.map +1 -1
- package/dist/viewable_fields.d.ts +172 -0
- package/dist/viewable_fields.d.ts.map +1 -0
- package/dist/viewable_fields.js +1562 -0
- package/dist/viewable_fields.js.map +1 -0
- package/dist/web-mobile-commons.d.ts +1 -1
- package/dist/web-mobile-commons.d.ts.map +1 -1
- package/dist/web-mobile-commons.js +19 -3
- package/dist/web-mobile-commons.js.map +1 -1
- package/package.json +14 -9
- package/webpack.config.js +3 -0
|
@@ -24,7 +24,7 @@ const { InvalidConfiguration, isNode, isWeb, isTest, mergeIntoWhere, dollarizeOb
|
|
|
24
24
|
const Library = require("../../models/library");
|
|
25
25
|
const { check_view_columns } = require("../../plugin-testing");
|
|
26
26
|
const { initial_config_all_fields, calcfldViewOptions, calcfldViewConfig, get_parent_views, picked_fields_to_query, stateFieldsToWhere, stateFieldsToQuery, getActionConfigFields, run_action_column, add_free_variables_to_joinfields, readState, stateToQueryString, pathToState, displayType, runCollabEvents, } = require("../../plugin-helper");
|
|
27
|
-
const { splitUniques, getForm, fill_presets, parse_view_select, get_view_link_query, objToQueryString, action_url, action_link, view_linker, edit_build_in_actions, } = require("./viewable_fields");
|
|
27
|
+
const { splitUniques, getForm, setDateLocales, transformForm, fill_presets, parse_view_select, get_view_link_query, objToQueryString, action_url, action_link, view_linker, edit_build_in_actions, updateViewSelect, } = require("./viewable_fields");
|
|
28
28
|
const { traverse, getStringsForI18n, translateLayout, traverseSync, splitLayoutContainerFields, findLayoutBranchWith, } = require("../../models/layout");
|
|
29
29
|
const { extractFromLayout } = require("../../diagram/node_extract_utils");
|
|
30
30
|
const db = require("../../db");
|
|
@@ -398,28 +398,6 @@ const get_state_fields = async (table_id, viewname, { columns }) => [
|
|
|
398
398
|
* @param {Form} form
|
|
399
399
|
* @param {string} locale
|
|
400
400
|
*/
|
|
401
|
-
const setDateLocales = (form, locale) => {
|
|
402
|
-
form.fields.forEach((f) => {
|
|
403
|
-
if (f.type && f.type.name === "Date") {
|
|
404
|
-
f.attributes.locale = locale;
|
|
405
|
-
}
|
|
406
|
-
});
|
|
407
|
-
};
|
|
408
|
-
/**
|
|
409
|
-
* update viewSelect so that it looks like a normal ChildList
|
|
410
|
-
*/
|
|
411
|
-
const updateViewSelect = (viewSelect) => {
|
|
412
|
-
if (viewSelect.path.length === 1) {
|
|
413
|
-
viewSelect.field_name = viewSelect.path[0].inboundKey;
|
|
414
|
-
viewSelect.table_name = viewSelect.path[0].table;
|
|
415
|
-
}
|
|
416
|
-
else if (viewSelect.path.length === 2) {
|
|
417
|
-
viewSelect.field_name = viewSelect.path[1].inboundKey;
|
|
418
|
-
viewSelect.table_name = viewSelect.path[1].table;
|
|
419
|
-
viewSelect.throughTable = viewSelect.path[0].inboundKey;
|
|
420
|
-
viewSelect.through = viewSelect.path[0].table;
|
|
421
|
-
}
|
|
422
|
-
};
|
|
423
401
|
/** @type {function} */
|
|
424
402
|
const initial_config = initial_config_all_fields(true);
|
|
425
403
|
/**
|
|
@@ -494,311 +472,6 @@ const runMany = async (table_id, viewname, { columns, layout, auto_save, split_p
|
|
|
494
472
|
* @throws {InvalidConfiguration}
|
|
495
473
|
* @returns {Promise<void>}
|
|
496
474
|
*/
|
|
497
|
-
const transformForm = async ({ form, table, req, row, res, getRowQuery, viewname, optionsQuery, state, }) => {
|
|
498
|
-
let originalState = state;
|
|
499
|
-
let pseudo_row = {};
|
|
500
|
-
if (!row) {
|
|
501
|
-
table.fields.forEach((f) => {
|
|
502
|
-
pseudo_row[f.name] = undefined;
|
|
503
|
-
});
|
|
504
|
-
}
|
|
505
|
-
await traverse(form.layout, {
|
|
506
|
-
container(segment) {
|
|
507
|
-
if (segment.click_action) {
|
|
508
|
-
segment.url = `javascript:view_post(this, 'run_action', {click_action: '${segment.click_action}', ...get_form_record(this) })`;
|
|
509
|
-
}
|
|
510
|
-
},
|
|
511
|
-
async action(segment) {
|
|
512
|
-
if (segment.action_style === "on_page_load") {
|
|
513
|
-
segment.type = "blank";
|
|
514
|
-
segment.style = {};
|
|
515
|
-
if (segment.minRole && segment.minRole != 100) {
|
|
516
|
-
const minRole = +segment.minRole;
|
|
517
|
-
const userRole = req?.user?.role_id || 100;
|
|
518
|
-
if (minRole < userRole)
|
|
519
|
-
return;
|
|
520
|
-
}
|
|
521
|
-
if (req.method === "POST")
|
|
522
|
-
return;
|
|
523
|
-
//run action
|
|
524
|
-
try {
|
|
525
|
-
const actionResult = await run_action_column({
|
|
526
|
-
col: { ...segment },
|
|
527
|
-
referrer: req?.get?.("Referrer"),
|
|
528
|
-
req,
|
|
529
|
-
res,
|
|
530
|
-
table,
|
|
531
|
-
row: row || pseudo_row,
|
|
532
|
-
});
|
|
533
|
-
if (actionResult)
|
|
534
|
-
segment.contents = script(domReady(`common_done(${JSON.stringify(actionResult)}, "${viewname}")`));
|
|
535
|
-
}
|
|
536
|
-
catch (e) {
|
|
537
|
-
getState().log(5, `Error in Edit ${viewname} on page load action: ${e.message}`);
|
|
538
|
-
e.message = `Error in evaluating Run on Page Load action in view ${viewname}: ${e.message}`;
|
|
539
|
-
throw e;
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
if (segment.action_name === "Delete") {
|
|
543
|
-
if (form.values && form.values[table.pk_name]) {
|
|
544
|
-
segment.action_url = table.delete_url(form.values);
|
|
545
|
-
}
|
|
546
|
-
else {
|
|
547
|
-
segment.type = "blank";
|
|
548
|
-
segment.contents = "";
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
else if (segment.action_name === "form_action" &&
|
|
552
|
-
segment.configuration?.form_action === "Save" &&
|
|
553
|
-
table.fields.some((f) => f.type === "File")) {
|
|
554
|
-
let url = action_url(viewname, table, segment.action_name, row, segment.rndid, "rndid", segment.confirm);
|
|
555
|
-
if (url.javascript) {
|
|
556
|
-
//redo to include dynamic row
|
|
557
|
-
const confirmStr = segment.confirm
|
|
558
|
-
? `if(confirm('Are you sure?'))`
|
|
559
|
-
: "";
|
|
560
|
-
url.javascript = `${confirmStr}view_post(this, 'run_action', get_form_data(this, '${segment.rndid}') );`;
|
|
561
|
-
}
|
|
562
|
-
segment.action_link = action_link(url, req, segment);
|
|
563
|
-
}
|
|
564
|
-
else if (!["Sign up", ...edit_build_in_actions].includes(segment.action_name) &&
|
|
565
|
-
!segment.action_name.startsWith("Login")) {
|
|
566
|
-
let url = action_url(viewname, table, segment.action_name, row, segment.rndid, "rndid", segment.confirm, undefined, segment.run_async);
|
|
567
|
-
if (url.javascript) {
|
|
568
|
-
//redo to include dynamic row
|
|
569
|
-
const confirmStr = segment.confirm
|
|
570
|
-
? `if(confirm('Are you sure?'))`
|
|
571
|
-
: "";
|
|
572
|
-
// If this is a Multi-step action or the form/table contains File fields,
|
|
573
|
-
// post multipart FormData so req.files is populated server-side.
|
|
574
|
-
const hasFileFields = table.fields?.some((f) => f.type === "File");
|
|
575
|
-
if (segment.action_name === "Multi-step action" || hasFileFields) {
|
|
576
|
-
url.javascript = `${confirmStr}view_post(this, 'run_action', get_form_data(this, '${segment.rndid}') );`;
|
|
577
|
-
}
|
|
578
|
-
else {
|
|
579
|
-
url.javascript = `${confirmStr}view_post(this, 'run_action', {rndid:'${segment.rndid}', ...get_form_record(this)});`;
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
segment.action_link = action_link(url, req, segment);
|
|
583
|
-
}
|
|
584
|
-
},
|
|
585
|
-
join_field(segment) {
|
|
586
|
-
const qs = objToQueryString(segment.configuration);
|
|
587
|
-
segment.sourceURL = `/field/show-calculated/${table.name}/${segment.join_field}/${segment.fieldview}?${qs}`;
|
|
588
|
-
},
|
|
589
|
-
tabs(segment) {
|
|
590
|
-
const to_delete = new Set();
|
|
591
|
-
(segment.showif || []).forEach((sif, ix) => {
|
|
592
|
-
if (sif) {
|
|
593
|
-
const showit = eval_expression(sif, row || pseudo_row, req.user, "Tab show if formula");
|
|
594
|
-
if (!showit)
|
|
595
|
-
to_delete.add(ix);
|
|
596
|
-
}
|
|
597
|
-
});
|
|
598
|
-
segment.titles = segment.titles.filter((v, ix) => !to_delete.has(ix));
|
|
599
|
-
segment.contents = segment.contents.filter((v, ix) => !to_delete.has(ix));
|
|
600
|
-
(segment.titles || []).forEach((t, ix) => {
|
|
601
|
-
if (typeof t === "string" && t.includes("{{")) {
|
|
602
|
-
segment.titles[ix] = interpolate(t, row, req.user, "Tab titles");
|
|
603
|
-
}
|
|
604
|
-
});
|
|
605
|
-
},
|
|
606
|
-
view_link(segment) {
|
|
607
|
-
segment.type = "blank";
|
|
608
|
-
const view_select = parse_view_select(segment.view);
|
|
609
|
-
if (!row && view_select.type !== "Independent") {
|
|
610
|
-
segment.contents = "";
|
|
611
|
-
}
|
|
612
|
-
else {
|
|
613
|
-
const prefix = req.generate_email && req.get_base_url ? req.get_base_url() : "";
|
|
614
|
-
const { key } = view_linker(segment, table.fields, (s) => s, isWeb(req), req.user, prefix, req.query, req, viewname);
|
|
615
|
-
segment.contents = key(row || {});
|
|
616
|
-
}
|
|
617
|
-
},
|
|
618
|
-
async view(segment) {
|
|
619
|
-
//console.log(segment);
|
|
620
|
-
const view_select = parse_view_select(segment.view, segment.relation);
|
|
621
|
-
//console.log({ view_select });
|
|
622
|
-
const view = View.findOne({ name: view_select.viewname });
|
|
623
|
-
if (!view)
|
|
624
|
-
throw new InvalidConfiguration(`Cannot find embedded view: ${view_select.viewname}`);
|
|
625
|
-
// check if the relation path matches a ChildList relations
|
|
626
|
-
let childListRelPath = false;
|
|
627
|
-
if (segment.relation && view.table_id) {
|
|
628
|
-
const targetTbl = Table.findOne({ id: view.table_id });
|
|
629
|
-
const relation = new Relation(segment.relation, targetTbl.name, displayType(await view.get_state_fields()));
|
|
630
|
-
childListRelPath = relation.type === RelationType.CHILD_LIST;
|
|
631
|
-
}
|
|
632
|
-
// Edit-in-edit
|
|
633
|
-
if (view.viewtemplate === "Edit" &&
|
|
634
|
-
(view_select.type === "ChildList" || childListRelPath)) {
|
|
635
|
-
if (childListRelPath)
|
|
636
|
-
updateViewSelect(view_select);
|
|
637
|
-
const childTable = Table.findOne({ id: view.table_id });
|
|
638
|
-
const childForm = await getForm(childTable, view.name, view.configuration.columns, view.configuration.layout, row?.id, req, !isWeb(req));
|
|
639
|
-
traverseSync(childForm.layout, {
|
|
640
|
-
field(segment) {
|
|
641
|
-
segment.field_name = `${view_select.field_name}.${segment.field_name}`;
|
|
642
|
-
},
|
|
643
|
-
});
|
|
644
|
-
for (const field of childForm.fields) {
|
|
645
|
-
if (field.name === childTable.pk_name) {
|
|
646
|
-
field.class = field.class
|
|
647
|
-
? `${field.class} omit-repeater-clone`
|
|
648
|
-
: "omit-repeater-clone";
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
await childForm.fill_fkey_options(false, optionsQuery, req.user);
|
|
652
|
-
const fr = new FieldRepeat({
|
|
653
|
-
name: view_select.field_name,
|
|
654
|
-
label: view_select.field_name,
|
|
655
|
-
fields: childForm.fields,
|
|
656
|
-
layout: childForm.layout,
|
|
657
|
-
metadata: {
|
|
658
|
-
table_id: childTable.id,
|
|
659
|
-
view: segment.view,
|
|
660
|
-
relation: view_select.field_name,
|
|
661
|
-
relation_path: segment.relation,
|
|
662
|
-
order_field: segment.order_field,
|
|
663
|
-
},
|
|
664
|
-
});
|
|
665
|
-
if (row?.id) {
|
|
666
|
-
const childRows = getRowQuery
|
|
667
|
-
? await getRowQuery(view.table_id, view_select, row.id, segment.order_field)
|
|
668
|
-
: await childTable.getRows({
|
|
669
|
-
[view_select.field_name]: row.id,
|
|
670
|
-
}, segment.order_field ? { orderBy: segment.order_field } : {});
|
|
671
|
-
fr.metadata.rows = childRows;
|
|
672
|
-
if (!fr.fields.map((f) => f.name).includes(childTable.pk_name))
|
|
673
|
-
fr.fields.push({
|
|
674
|
-
name: childTable.pk_name,
|
|
675
|
-
input_type: "hidden",
|
|
676
|
-
});
|
|
677
|
-
}
|
|
678
|
-
form.fields.push(fr);
|
|
679
|
-
segment.type = "field_repeat";
|
|
680
|
-
segment.field_repeat = fr;
|
|
681
|
-
return;
|
|
682
|
-
} // end edit in edit
|
|
683
|
-
const outerState = {};
|
|
684
|
-
Object.entries(originalState || {}).forEach(([k, v]) => {
|
|
685
|
-
if (k.startsWith("_"))
|
|
686
|
-
outerState[k] = v;
|
|
687
|
-
});
|
|
688
|
-
let state = {};
|
|
689
|
-
let urlFormula;
|
|
690
|
-
let needFields = new Set();
|
|
691
|
-
if (view_select.type === "RelationPath" && view.table_id) {
|
|
692
|
-
const pathToUrlFormula = (relation) => {
|
|
693
|
-
const st = pathToState(relation, (k) => `row.` + k);
|
|
694
|
-
return Object.entries(st)
|
|
695
|
-
.map(([k, v]) => {
|
|
696
|
-
needFields.add(v.split(".")[1]);
|
|
697
|
-
return `${k}='+${v}+'`;
|
|
698
|
-
})
|
|
699
|
-
.join("&");
|
|
700
|
-
};
|
|
701
|
-
const targetTbl = Table.findOne({ id: view.table_id });
|
|
702
|
-
if (targetTbl) {
|
|
703
|
-
const relation = new Relation(segment.relation, targetTbl.name, displayType(await view.get_state_fields()));
|
|
704
|
-
const relFmlQS = pathToUrlFormula(relation);
|
|
705
|
-
const type = relation.type;
|
|
706
|
-
if (!row && type == RelationType.OWN) {
|
|
707
|
-
segment.type = "blank";
|
|
708
|
-
urlFormula = `add_extra_state('/view/${view.name}/?${relFmlQS}', ${JSON.stringify(segment.extra_state_fml)}, row, ${JSON.stringify(outerState)})`;
|
|
709
|
-
segment.contents = segment.contents = div({
|
|
710
|
-
class: "d-inline",
|
|
711
|
-
"data-sc-embed-viewname": view.name,
|
|
712
|
-
"data-view-source-need-fields": [...needFields].join(","),
|
|
713
|
-
"data-view-source": encodeURIComponent(urlFormula),
|
|
714
|
-
});
|
|
715
|
-
return;
|
|
716
|
-
}
|
|
717
|
-
else if (!row &&
|
|
718
|
-
type !== RelationType.INDEPENDENT &&
|
|
719
|
-
!relation.isFixedRelation()) {
|
|
720
|
-
urlFormula = `add_extra_state('/view/${view.name}/?${relFmlQS}', ${JSON.stringify(segment.extra_state_fml)}, row, ${JSON.stringify(outerState)})`;
|
|
721
|
-
segment.contents = segment.contents = div({
|
|
722
|
-
class: "d-inline",
|
|
723
|
-
"data-sc-embed-viewname": view.name,
|
|
724
|
-
"data-view-source-need-fields": [...needFields].join(","),
|
|
725
|
-
"data-view-source": encodeURIComponent(urlFormula),
|
|
726
|
-
});
|
|
727
|
-
return;
|
|
728
|
-
}
|
|
729
|
-
const userId = req?.user?.id;
|
|
730
|
-
state = pathToState(relation, relation.isFixedRelation() ? () => userId : (k) => row[k]);
|
|
731
|
-
urlFormula = `add_extra_state('/view/${view.name}?${relFmlQS}', ${JSON.stringify(segment.extra_state_fml)}, row, ${JSON.stringify(outerState)})`;
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
else {
|
|
735
|
-
const isIndependent = view_select.type === "Independent";
|
|
736
|
-
// legacy none check ?
|
|
737
|
-
if (!view)
|
|
738
|
-
throw new InvalidConfiguration(`Edit view incorrectly configured: cannot find embedded view ${view_select.viewname}`);
|
|
739
|
-
switch (view_select.type) {
|
|
740
|
-
case "Own":
|
|
741
|
-
state = { id: row?.id };
|
|
742
|
-
urlFormula = `add_extra_state('/view/${view.name}/?id='+row.id, ${JSON.stringify(segment.extra_state_fml)}, row, ${JSON.stringify(outerState)})`;
|
|
743
|
-
needFields.add("id");
|
|
744
|
-
break;
|
|
745
|
-
case "Independent":
|
|
746
|
-
state = {};
|
|
747
|
-
urlFormula = `add_extra_state('/view/${view.name}/?id='+row.id, ${JSON.stringify(segment.extra_state_fml)}, row, ${JSON.stringify(outerState)})`;
|
|
748
|
-
needFields.add("id");
|
|
749
|
-
break;
|
|
750
|
-
case "ChildList":
|
|
751
|
-
case "OneToOneShow":
|
|
752
|
-
state = { [view_select.field_name]: row?.id };
|
|
753
|
-
urlFormula = `add_extra_state('/view/${view.name}/?${view_select.field_name}='+row.id, ${JSON.stringify(segment.extra_state_fml)}, row, ${JSON.stringify(outerState)})`;
|
|
754
|
-
needFields.add("id");
|
|
755
|
-
break;
|
|
756
|
-
case "ParentShow":
|
|
757
|
-
state = { id: row?.[view_select.field_name] };
|
|
758
|
-
urlFormula = `add_extra_state('/view/${view.name}/?id='+row.${view_select.field_name}, ${JSON.stringify(segment.extra_state_fml)}, row, ${JSON.stringify(outerState)})`;
|
|
759
|
-
needFields.add(view_select.field_name);
|
|
760
|
-
break;
|
|
761
|
-
}
|
|
762
|
-
if (!row && !isIndependent) {
|
|
763
|
-
segment.type = "blank";
|
|
764
|
-
segment.contents = div({
|
|
765
|
-
class: "d-inline",
|
|
766
|
-
"data-sc-embed-viewname": view.name,
|
|
767
|
-
"data-view-source-need-fields": [...needFields].join(","),
|
|
768
|
-
"data-view-source": encodeURIComponent(urlFormula),
|
|
769
|
-
});
|
|
770
|
-
return;
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
const extra_state = segment.extra_state_fml
|
|
774
|
-
? eval_expression(segment.extra_state_fml, {
|
|
775
|
-
...dollarizeObject(req.query),
|
|
776
|
-
session_id: getSessionId(req),
|
|
777
|
-
...(row || pseudo_row),
|
|
778
|
-
}, req.user, `Extra state formula for embedding view ${view.name}`)
|
|
779
|
-
: {};
|
|
780
|
-
const qs = stateToQueryString({ ...state, ...outerState, ...extra_state }, true);
|
|
781
|
-
segment.contents = div({
|
|
782
|
-
class: "d-inline",
|
|
783
|
-
"data-sc-embed-viewname": view.name,
|
|
784
|
-
"data-sc-view-source": `/view/${view.name}${qs}`,
|
|
785
|
-
"data-view-source-current": `/view/${view.name}${qs}`,
|
|
786
|
-
"data-view-source-need-fields": [...needFields].join(","),
|
|
787
|
-
"data-view-source": encodeURIComponent(urlFormula),
|
|
788
|
-
}, view.renderLocally()
|
|
789
|
-
? await view.run({ ...state, ...outerState, ...extra_state }, { req, res }, view.isRemoteTable())
|
|
790
|
-
: await renderServerSide(view.name, {
|
|
791
|
-
...state,
|
|
792
|
-
...outerState,
|
|
793
|
-
...extra_state,
|
|
794
|
-
}));
|
|
795
|
-
},
|
|
796
|
-
});
|
|
797
|
-
translateLayout(form.layout, req.getLocale());
|
|
798
|
-
if (req.headers?.saltcornmodalrequest)
|
|
799
|
-
form.xhrSubmit = true;
|
|
800
|
-
setDateLocales(form, req.getLocale());
|
|
801
|
-
};
|
|
802
475
|
const realTimeScript = (viewname, table_id, row, scriptId) => {
|
|
803
476
|
const view = View.findOne({ name: viewname });
|
|
804
477
|
const table = Table.findOne({ id: table_id });
|
|
@@ -1176,11 +849,12 @@ const runPost = async (table_id, viewname, { columns, layout, fixed, view_when_d
|
|
|
1176
849
|
childRow[order_field] = row_ix;
|
|
1177
850
|
for (const file_field of field.fields.filter((f) => f.type === "File")) {
|
|
1178
851
|
const key = `${file_field.name}_${repeatIx}`;
|
|
1179
|
-
if (req.files?.[key]
|
|
852
|
+
if (req.files?.[key] &&
|
|
853
|
+
(!file_field.fieldviewObj || file_field.fieldviewObj.isEdit)) {
|
|
1180
854
|
const file = await File.from_req_files(req.files[key], req.user ? req.user.id : null, (file_field.attributes &&
|
|
1181
855
|
+file_field.attributes.min_role_read) ||
|
|
1182
856
|
1, file_field?.attributes?.folder);
|
|
1183
|
-
childRow[file_field.name] = file.
|
|
857
|
+
childRow[file_field.name] = file.field_value;
|
|
1184
858
|
}
|
|
1185
859
|
}
|
|
1186
860
|
getState().log(6, `Edit POST ready to insert/update Child row into ${childTable.name} Row=${JSON.stringify(childRow)} ID=${childRow[childTable.pk_name]} Ajax=${!!req.xhr}`);
|
|
@@ -1559,16 +1233,18 @@ const prepare = async (viewname, table, fields, { columns, layout, fixed, auto_s
|
|
|
1559
1233
|
if (body[field.name]) {
|
|
1560
1234
|
if (body[field.name].startsWith("data:")) {
|
|
1561
1235
|
const path_to_serve = await saveFileQuery(body[field.name], field.id, field.fieldview, row);
|
|
1562
|
-
|
|
1563
|
-
|
|
1236
|
+
const storedValue = File.fieldValueFromRelative(path_to_serve);
|
|
1237
|
+
row[field.name] = storedValue;
|
|
1238
|
+
form.values[field.name] = storedValue;
|
|
1564
1239
|
}
|
|
1565
1240
|
}
|
|
1566
1241
|
}
|
|
1567
1242
|
else if (field.fieldviewObj?.editContent) {
|
|
1568
1243
|
if (body[field.name]) {
|
|
1569
1244
|
const path_to_serve = await saveFileFromContentsQuery(body[`_content_${field.name}`], field.id, field.fieldview, row, body[field.name], "utf8");
|
|
1570
|
-
|
|
1571
|
-
|
|
1245
|
+
const storedValue = File.fieldValueFromRelative(path_to_serve);
|
|
1246
|
+
row[field.name] = storedValue;
|
|
1247
|
+
form.values[field.name] = storedValue;
|
|
1572
1248
|
}
|
|
1573
1249
|
}
|
|
1574
1250
|
else if (req.files && req.files[field.name]) {
|
|
@@ -1577,20 +1253,20 @@ const prepare = async (viewname, table, fields, { columns, layout, fixed, auto_s
|
|
|
1577
1253
|
}
|
|
1578
1254
|
if (isWeb(req)) {
|
|
1579
1255
|
const file = await File.from_req_files(req.files[field.name], req.user ? req.user.id : null, (field.attributes && +field.attributes.min_role_read) || 1, field?.attributes?.folder);
|
|
1580
|
-
row[field.name] = file.
|
|
1581
|
-
form.values[field.name] = file.
|
|
1256
|
+
row[field.name] = file.field_value;
|
|
1257
|
+
form.values[field.name] = file.field_value;
|
|
1582
1258
|
}
|
|
1583
1259
|
else {
|
|
1584
1260
|
const file = req.files[field.name];
|
|
1585
1261
|
if (file) {
|
|
1586
1262
|
const serverResp = await File.upload(req.files[field.name]);
|
|
1587
1263
|
if (serverResp?.location)
|
|
1588
|
-
row[field.name] = serverResp.location;
|
|
1264
|
+
row[field.name] = File.normalizeFieldValueInput(serverResp.location);
|
|
1589
1265
|
}
|
|
1590
1266
|
}
|
|
1591
1267
|
}
|
|
1592
1268
|
else if (typeof body[`__exisiting_file_${field.name}`] === "string") {
|
|
1593
|
-
row[field.name] = File.
|
|
1269
|
+
row[field.name] = File.normalizeFieldValueInput(body[`__exisiting_file_${field.name}`]);
|
|
1594
1270
|
form.values[field.name] = row[field.name];
|
|
1595
1271
|
}
|
|
1596
1272
|
else {
|
|
@@ -2071,7 +1747,7 @@ module.exports = {
|
|
|
2071
1747
|
...(column?.configuration || {}),
|
|
2072
1748
|
});
|
|
2073
1749
|
const file = await File.from_contents(filename, mimetype, buffer, req.user?.id, field.attributes.min_role_read || 1, folder);
|
|
2074
|
-
return file.path_to_serve;
|
|
1750
|
+
return File.fieldValueFromRelative(file.path_to_serve);
|
|
2075
1751
|
},
|
|
2076
1752
|
async saveFileFromContentsQuery(fieldVal, fieldId, fieldView, row, filename, encoding = "base64") {
|
|
2077
1753
|
const field = await Field.findOne({ id: fieldId });
|
|
@@ -2095,13 +1771,13 @@ module.exports = {
|
|
|
2095
1771
|
if (existing_file) {
|
|
2096
1772
|
if (existing_file.min_role_read >= (req.user?.role_id || 100)) {
|
|
2097
1773
|
await existing_file.overwrite_contents(buffer);
|
|
2098
|
-
return existing_file.path_to_serve;
|
|
1774
|
+
return File.fieldValueFromRelative(existing_file.path_to_serve);
|
|
2099
1775
|
}
|
|
2100
1776
|
else
|
|
2101
1777
|
throw new Error("Not authorized to write file");
|
|
2102
1778
|
}
|
|
2103
1779
|
const file = await File.from_contents(filename1, mimetype, buffer, req.user?.id, field.attributes.min_role_read || 1);
|
|
2104
|
-
return file.path_to_serve;
|
|
1780
|
+
return File.fieldValueFromRelative(file.path_to_serve);
|
|
2105
1781
|
},
|
|
2106
1782
|
async authorizePostQuery(body, table_id /*overwrites*/) {
|
|
2107
1783
|
return await doAuthPost({ body, table_id, req });
|