@saltcorn/data 1.1.3 → 1.1.4-alpha.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.
Files changed (63) hide show
  1. package/dist/base-plugin/index.d.ts +3 -9
  2. package/dist/base-plugin/index.d.ts.map +1 -1
  3. package/dist/base-plugin/viewtemplates/edit.d.ts +1 -3
  4. package/dist/base-plugin/viewtemplates/edit.d.ts.map +1 -1
  5. package/dist/base-plugin/viewtemplates/edit.js +167 -158
  6. package/dist/base-plugin/viewtemplates/edit.js.map +1 -1
  7. package/dist/base-plugin/viewtemplates/filter.d.ts +1 -3
  8. package/dist/base-plugin/viewtemplates/filter.d.ts.map +1 -1
  9. package/dist/base-plugin/viewtemplates/filter.js +46 -43
  10. package/dist/base-plugin/viewtemplates/filter.js.map +1 -1
  11. package/dist/base-plugin/viewtemplates/list.d.ts.map +1 -1
  12. package/dist/base-plugin/viewtemplates/list.js +34 -35
  13. package/dist/base-plugin/viewtemplates/list.js.map +1 -1
  14. package/dist/base-plugin/viewtemplates/show.d.ts +1 -3
  15. package/dist/base-plugin/viewtemplates/show.d.ts.map +1 -1
  16. package/dist/base-plugin/viewtemplates/show.js +20 -21
  17. package/dist/base-plugin/viewtemplates/show.js.map +1 -1
  18. package/dist/db/index.d.ts.map +1 -1
  19. package/dist/db/index.js.map +1 -1
  20. package/dist/models/config.d.ts.map +1 -1
  21. package/dist/models/config.js +7 -0
  22. package/dist/models/config.js.map +1 -1
  23. package/dist/models/discovery.d.ts.map +1 -1
  24. package/dist/models/discovery.js +2 -1
  25. package/dist/models/discovery.js.map +1 -1
  26. package/dist/models/field.d.ts.map +1 -1
  27. package/dist/models/field.js +15 -14
  28. package/dist/models/field.js.map +1 -1
  29. package/dist/models/model.d.ts.map +1 -1
  30. package/dist/models/model.js +6 -2
  31. package/dist/models/model.js.map +1 -1
  32. package/dist/models/page.d.ts +1 -0
  33. package/dist/models/page.d.ts.map +1 -1
  34. package/dist/models/page.js +8 -2
  35. package/dist/models/page.js.map +1 -1
  36. package/dist/models/page_group.d.ts +2 -3
  37. package/dist/models/page_group.d.ts.map +1 -1
  38. package/dist/models/page_group.js +72 -112
  39. package/dist/models/page_group.js.map +1 -1
  40. package/dist/models/page_group_member.d.ts +4 -4
  41. package/dist/models/page_group_member.d.ts.map +1 -1
  42. package/dist/models/page_group_member.js +11 -11
  43. package/dist/models/page_group_member.js.map +1 -1
  44. package/dist/models/table.d.ts +1 -0
  45. package/dist/models/table.d.ts.map +1 -1
  46. package/dist/models/table.js +51 -56
  47. package/dist/models/table.js.map +1 -1
  48. package/dist/models/table_constraints.d.ts.map +1 -1
  49. package/dist/models/table_constraints.js +6 -3
  50. package/dist/models/table_constraints.js.map +1 -1
  51. package/dist/models/trigger.d.ts +2 -0
  52. package/dist/models/trigger.d.ts.map +1 -1
  53. package/dist/models/trigger.js +26 -4
  54. package/dist/models/trigger.js.map +1 -1
  55. package/dist/models/view.d.ts +1 -0
  56. package/dist/models/view.d.ts.map +1 -1
  57. package/dist/models/view.js +9 -3
  58. package/dist/models/view.js.map +1 -1
  59. package/dist/tests/calc.test.js +2 -3
  60. package/dist/tests/calc.test.js.map +1 -1
  61. package/dist/tests/exact_views.test.js +1 -0
  62. package/dist/tests/exact_views.test.js.map +1 -1
  63. package/package.json +8 -8
@@ -1139,9 +1139,7 @@ export const viewtemplates: ({
1139
1139
  authorizeGetQuery(query: any, table_id: any): Promise<string | number | boolean | null | undefined>;
1140
1140
  getRowQuery(table_id: any, view_select: any, row_id: any, order_field: any): Promise<import("@saltcorn/db-common/internal").Row[]>;
1141
1141
  getRowByIdQuery(id: any): Promise<import("@saltcorn/db-common/internal").Row | null>;
1142
- actionQuery(): Promise<{
1143
- json: any;
1144
- }>;
1142
+ actionQuery(): Promise<any>;
1145
1143
  optionsQuery(reftable_name: any, type: any, attributes: any, where: any): Promise<import("@saltcorn/db-common/internal").Row[]>;
1146
1144
  updateMatchingQuery(where: any, updateVals: any, repeatFields: any, childRows: any): Promise<any[] | {
1147
1145
  rowError: any;
@@ -1262,9 +1260,7 @@ export const viewtemplates: ({
1262
1260
  orderBy: any;
1263
1261
  orderDesc: any;
1264
1262
  }): Promise<import("@saltcorn/db-common/internal").Row[]>;
1265
- actionQuery(): Promise<{
1266
- json: any;
1267
- }>;
1263
+ actionQuery(): Promise<any>;
1268
1264
  };
1269
1265
  configCheck: (view: any) => Promise<{
1270
1266
  errors: string[];
@@ -1375,9 +1371,7 @@ export const viewtemplates: ({
1375
1371
  exttable_name: any;
1376
1372
  }) => {
1377
1373
  optionsQuery(reftable_name: any, type: any, attributes: any, whereWithExisting: any, user: any): Promise<any>;
1378
- actionQuery(state: any, rndid: any): Promise<{
1379
- json: any;
1380
- }>;
1374
+ actionQuery(state: any, rndid: any): Promise<any>;
1381
1375
  distinctValuesQuery(state: any): Promise<{
1382
1376
  distinct_values: {};
1383
1377
  role: any;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../base-plugin/index.js"],"names":[],"mappings":"AAwCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAAsD;AACtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KASE;;;;0CAGW,MAAM"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../base-plugin/index.js"],"names":[],"mappings":"AAwCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAAsD;AACtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KASE;;;;0CAGW,MAAM"}
@@ -209,9 +209,7 @@ export declare function queries({ table_id, name, configuration: { columns, defa
209
209
  authorizeGetQuery(query: any, table_id: any): Promise<string | number | boolean | null | undefined>;
210
210
  getRowQuery(table_id: any, view_select: any, row_id: any, order_field: any): Promise<import("@saltcorn/db-common/internal").Row[]>;
211
211
  getRowByIdQuery(id: any): Promise<import("@saltcorn/db-common/internal").Row | null>;
212
- actionQuery(): Promise<{
213
- json: any;
214
- }>;
212
+ actionQuery(): Promise<any>;
215
213
  optionsQuery(reftable_name: any, type: any, attributes: any, where: any): Promise<import("@saltcorn/db-common/internal").Row[]>;
216
214
  updateMatchingQuery(where: any, updateVals: any, repeatFields: any, childRows: any): Promise<any[] | {
217
215
  rowError: any;
@@ -1 +1 @@
1
- {"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../../base-plugin/viewtemplates/edit.js"],"names":[],"mappings":"AAqGA;;;GAGG;AAEH,4CAJW,MAAM,GACJ,QAAQ,CAgXjB;AA+CJ;;;;;;;;;;;GAWG;AACH,8BAXW,MAAM,YACN,MAAM,mBAIN,MAAM;IAEU,GAAG,EAAnB,MAAM;IACU,GAAG,EAAnB,MAAM;;;IACJ,QAAQ,IAAI,CAAC,CAYzB;AAED;;;;;;;;;GASG;AACH,kCATW,MAAM,YACN,MAAM;IAEE,OAAO;IACP,MAAM;wBAEd,MAAM;;;;IACJ,QAAQ,IAAI,EAAE,CAAC,CA0C3B;AA6jBD;;;;;;;;;;;;;;;;GAgBG;AACH,kCAhBW,MAAM,YACN,MAAM;IAEY,OAAO,EAAzB,MAAM,EAAE;IACQ,MAAM;IACN,KAAK,EAArB,MAAM;IACW,cAAc,EAA/B,OAAO;IACW,oBAAoB,EAAtC,MAAM,EAAE;UACR,MAAM;IAGU,GAAG,EAAnB,MAAM;IACU,GAAG,EAAnB,MAAM;IACU,QAAQ,EAAxB,MAAM;;;;;;;;;iBACJ,QAAQ,IAAI,CAAC,CAuTzB;AA0FD,mKA6BC;AAGD,sHA6BC;AAjpCD;;;;;;GAMG;AACH;IAHmB,OAAO;IACb,QAAQ,MAAM,EAAE,CAAC,CAQ7B;AA6BD,uBAAuB;AACvB,sCAAuD;AA2hCvD;;;;;;GAMG;AACH;IALwB,IAAI,EAAjB,MAAM;IACO,QAAQ,EAArB,MAAM;IACO,GAAG,EAAhB,MAAM;;;IACJ,QAAQ,OAAO,CAAC,CAO5B;;;;AAiED;;;;;;;;;;;GAWG;AACH,sCAXW,MAAM;IAGS,OAAO,EAAtB,MAAM,EAAE;IACA,MAAM;;IAGE,GAAG,EAAnB,MAAM;IACK,GAAG;;;IACZ,QAAQ,MAAM,CAAC,CAe3B;AAED;;;;;;;;;;;;;;;;;;;;;;kBA0GC;;yBAiWY,MAAM;gCAEN,MAAM;AAiBF;;;;;qBAEd;AACD;;;;GAIG;AACH;;aAEC;AACQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+bP;;;;;AAEF,yGAeC;AACY;;;GA2DZ;AACiB,6HAEjB"}
1
+ {"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../../base-plugin/viewtemplates/edit.js"],"names":[],"mappings":"AAqGA;;;GAGG;AAEH,4CAJW,MAAM,GACJ,QAAQ,CAgXjB;AA+CJ;;;;;;;;;;;GAWG;AACH,8BAXW,MAAM,YACN,MAAM,mBAIN,MAAM;IAEU,GAAG,EAAnB,MAAM;IACU,GAAG,EAAnB,MAAM;;;IACJ,QAAQ,IAAI,CAAC,CAYzB;AAED;;;;;;;;;GASG;AACH,kCATW,MAAM,YACN,MAAM;IAEE,OAAO;IACP,MAAM;wBAEd,MAAM;;;;IACJ,QAAQ,IAAI,EAAE,CAAC,CA0C3B;AA6jBD;;;;;;;;;;;;;;;;GAgBG;AACH,kCAhBW,MAAM,YACN,MAAM;IAEY,OAAO,EAAzB,MAAM,EAAE;IACQ,MAAM;IACN,KAAK,EAArB,MAAM;IACW,cAAc,EAA/B,OAAO;IACW,oBAAoB,EAAtC,MAAM,EAAE;UACR,MAAM;IAGU,GAAG,EAAnB,MAAM;IACU,GAAG,EAAnB,MAAM;IACU,QAAQ,EAAxB,MAAM;;;;;;;;;iBACJ,QAAQ,IAAI,CAAC,CAgUzB;AA0FD,mKA6BC;AAGD,sHA6BC;AA1pCD;;;;;;GAMG;AACH;IAHmB,OAAO;IACb,QAAQ,MAAM,EAAE,CAAC,CAQ7B;AA6BD,uBAAuB;AACvB,sCAAuD;AAoiCvD;;;;;;GAMG;AACH;IALwB,IAAI,EAAjB,MAAM;IACO,QAAQ,EAArB,MAAM;IACO,GAAG,EAAhB,MAAM;;;IACJ,QAAQ,OAAO,CAAC,CAO5B;;;;AAiED;;;;;;;;;;;GAWG;AACH,sCAXW,MAAM;IAGS,OAAO,EAAtB,MAAM,EAAE;IACA,MAAM;;IAGE,GAAG,EAAnB,MAAM;IACK,GAAG;;;IACZ,QAAQ,MAAM,CAAC,CAe3B;AAED;;;;;;;;;;;;;;;;;;;;;;kBA0GC;;yBAiWY,MAAM;gCAEN,MAAM;AAiBF;;;;;qBAEd;AACD;;;;GAIG;AACH;;aAEC;AACQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAicP;;;;;AAEF,yGAeC;AACY;;;GA2DZ;AACiB,6HAEjB"}
@@ -952,126 +952,133 @@ const runPost = async (table_id, viewname, { columns, layout, fixed, view_when_d
952
952
  let ins_upd_error;
953
953
  if (!cancel) {
954
954
  getState().log(6, `Edit POST ready to insert/update into ${table.name} Row=${JSON.stringify(row)} ID=${id} Ajax=${!!req.xhr}`);
955
- if (typeof id === "undefined") {
956
- const ins_res = await tryInsertQuery(row);
957
- if (ins_res.success) {
958
- id = ins_res.success;
959
- row[pk.name] = id;
960
- trigger_return = ins_res.trigger_return;
961
- }
962
- else {
963
- ins_upd_error = ins_res.error;
964
- }
965
- }
966
- else {
967
- if (table.getField(table.pk_name).attributes.NonSerial) {
968
- const upd_res = await tryInsertOrUpdateImpl(row, id, table, req.user || { role_id: 100 });
969
- if (upd_res.error) {
970
- ins_upd_error = upd_res.error;
955
+ const doReturn = await db.withTransaction(async (rollback) => {
956
+ if (typeof id === "undefined") {
957
+ const ins_res = await tryInsertQuery(row);
958
+ if (ins_res.success) {
959
+ id = ins_res.success;
960
+ row[pk.name] = id;
961
+ trigger_return = ins_res.trigger_return;
971
962
  }
972
- trigger_return = upd_res.trigger_return;
973
- }
974
- else {
975
- const upd_res = await tryUpdateQuery(row, id);
976
- if (upd_res.error) {
977
- ins_upd_error = upd_res.error;
963
+ else {
964
+ ins_upd_error = ins_res.error;
978
965
  }
979
- trigger_return = upd_res.trigger_return;
980
- }
981
- }
982
- if (ins_upd_error) {
983
- getState().log(6, `Insert or update failure ${JSON.stringify(ins_upd_error)}`);
984
- res.status(422);
985
- if (req.xhr) {
986
- res.json({ error: ins_upd_error });
987
966
  }
988
967
  else {
989
- await form.fill_fkey_options(false, optionsQuery, req.user);
990
- req.flash("error", text_attr(ins_upd_error));
991
- res.sendWrap(pagetitle, renderForm(form, req.csrfToken()));
992
- }
993
- return;
994
- }
995
- //Edit-in-edit
996
- for (const field of form.fields.filter((f) => f.isRepeat)) {
997
- const view_select = parse_view_select(field.metadata.view, field.metadata.relation_path);
998
- const order_field = field.metadata.order_field;
999
- const childView = View.findOne({ name: view_select.viewname });
1000
- if (!childView)
1001
- throw new InvalidConfiguration(`Cannot find embedded view: ${view_select.viewname}`);
1002
- if (field.metadata.relation_path &&
1003
- view_select.type === "RelationPath") {
1004
- const targetTbl = Table.findOne({ id: childView.table_id });
1005
- const relation = new Relation(field.metadata.relation_path, targetTbl.name, displayType(await childView.get_state_fields()));
1006
- if (relation.type === RelationType.CHILD_LIST)
1007
- updateViewSelect(view_select);
1008
- }
1009
- const childTable = Table.findOne({ id: field.metadata?.table_id });
1010
- const submitted_row_ids = new Set((form.values[field.name] || []).map((srow) => `${srow[childTable.pk_name]}`));
1011
- const childFields = new Set(childTable.fields.map((f) => f.name));
1012
- let repeatIx = 0;
1013
- for (const [childRow, row_ix] of form.values[field.name].map((r, ix) => [r, ix])) {
1014
- // set fixed here
1015
- childRow[field.metadata?.relation] = id;
1016
- for (const [k, v] of Object.entries(childView?.configuration?.fixed || {})) {
1017
- if (typeof childRow[k] === "undefined" &&
1018
- !k.startsWith("_block_") &&
1019
- childFields.has(k) &&
1020
- (v || v === 0) //no nulls or empty string, but allow 0
1021
- )
1022
- childRow[k] = v;
1023
- }
1024
- if (order_field && !childRow[order_field])
1025
- childRow[order_field] = row_ix;
1026
- for (const file_field of field.fields.filter((f) => f.type === "File")) {
1027
- const key = `${file_field.name}_${repeatIx}`;
1028
- if (req.files?.[key]) {
1029
- const file = await File.from_req_files(req.files[key], req.user ? req.user.id : null, (file_field.attributes &&
1030
- +file_field.attributes.min_role_read) ||
1031
- 1, file_field?.attributes?.folder);
1032
- childRow[file_field.name] = file.path_to_serve;
968
+ if (table.getField(table.pk_name).attributes.NonSerial) {
969
+ const upd_res = await tryInsertOrUpdateImpl(row, id, table, req.user || { role_id: 100 });
970
+ if (upd_res.error) {
971
+ ins_upd_error = upd_res.error;
1033
972
  }
973
+ trigger_return = upd_res.trigger_return;
1034
974
  }
1035
- 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}`);
1036
- if (childRow[childTable.pk_name]) {
1037
- const upd_res = await childTable.tryUpdateRow(childRow, childRow[childTable.pk_name], req.user || { role_id: 100 });
975
+ else {
976
+ const upd_res = await tryUpdateQuery(row, id);
1038
977
  if (upd_res.error) {
1039
- getState().log(6, `Update child row failure ${JSON.stringify(upd_res)}`);
1040
- req.flash("error", text_attr(upd_res.error));
1041
- res.sendWrap(pagetitle, renderForm(form, req.csrfToken()));
1042
- return;
978
+ ins_upd_error = upd_res.error;
1043
979
  }
980
+ trigger_return = upd_res.trigger_return;
981
+ }
982
+ }
983
+ if (ins_upd_error) {
984
+ await rollback();
985
+ getState().log(6, `Insert or update failure ${JSON.stringify(ins_upd_error)}`);
986
+ res.status(422);
987
+ if (req.xhr) {
988
+ res.json({ error: ins_upd_error });
1044
989
  }
1045
990
  else {
1046
- const ins_res = await childTable.tryInsertRow(childRow, req.user || { role_id: 100 });
1047
- if (ins_res.error) {
1048
- getState().log(6, `Insert child row failure ${JSON.stringify(ins_res)}`);
1049
- req.flash("error", text_attr(ins_res.error));
1050
- res.sendWrap(pagetitle, renderForm(form, req.csrfToken()));
1051
- return;
991
+ await form.fill_fkey_options(false, optionsQuery, req.user);
992
+ req.flash("error", text_attr(ins_upd_error));
993
+ res.sendWrap(pagetitle, renderForm(form, req.csrfToken()));
994
+ }
995
+ return true;
996
+ }
997
+ for (const field of form.fields.filter((f) => f.isRepeat)) {
998
+ const view_select = parse_view_select(field.metadata.view, field.metadata.relation_path);
999
+ const order_field = field.metadata.order_field;
1000
+ const childView = View.findOne({ name: view_select.viewname });
1001
+ if (!childView)
1002
+ throw new InvalidConfiguration(`Cannot find embedded view: ${view_select.viewname}`);
1003
+ if (field.metadata.relation_path &&
1004
+ view_select.type === "RelationPath") {
1005
+ const targetTbl = Table.findOne({ id: childView.table_id });
1006
+ const relation = new Relation(field.metadata.relation_path, targetTbl.name, displayType(await childView.get_state_fields()));
1007
+ if (relation.type === RelationType.CHILD_LIST)
1008
+ updateViewSelect(view_select);
1009
+ }
1010
+ const childTable = Table.findOne({ id: field.metadata?.table_id });
1011
+ const submitted_row_ids = new Set((form.values[field.name] || []).map((srow) => `${srow[childTable.pk_name]}`));
1012
+ const childFields = new Set(childTable.fields.map((f) => f.name));
1013
+ let repeatIx = 0;
1014
+ for (const [childRow, row_ix] of form.values[field.name].map((r, ix) => [r, ix])) {
1015
+ // set fixed here
1016
+ childRow[field.metadata?.relation] = id;
1017
+ for (const [k, v] of Object.entries(childView?.configuration?.fixed || {})) {
1018
+ if (typeof childRow[k] === "undefined" &&
1019
+ !k.startsWith("_block_") &&
1020
+ childFields.has(k) &&
1021
+ (v || v === 0) //no nulls or empty string, but allow 0
1022
+ )
1023
+ childRow[k] = v;
1024
+ }
1025
+ if (order_field && !childRow[order_field])
1026
+ childRow[order_field] = row_ix;
1027
+ for (const file_field of field.fields.filter((f) => f.type === "File")) {
1028
+ const key = `${file_field.name}_${repeatIx}`;
1029
+ if (req.files?.[key]) {
1030
+ const file = await File.from_req_files(req.files[key], req.user ? req.user.id : null, (file_field.attributes &&
1031
+ +file_field.attributes.min_role_read) ||
1032
+ 1, file_field?.attributes?.folder);
1033
+ childRow[file_field.name] = file.path_to_serve;
1034
+ }
1052
1035
  }
1053
- else if (ins_res.success) {
1054
- submitted_row_ids.add(`${ins_res.success}`);
1036
+ 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}`);
1037
+ if (childRow[childTable.pk_name]) {
1038
+ const upd_res = await childTable.tryUpdateRow(childRow, childRow[childTable.pk_name], req.user || { role_id: 100 });
1039
+ if (upd_res.error) {
1040
+ await rollback();
1041
+ getState().log(6, `Update child row failure ${JSON.stringify(upd_res)}`);
1042
+ req.flash("error", text_attr(upd_res.error));
1043
+ res.sendWrap(pagetitle, renderForm(form, req.csrfToken()));
1044
+ return true;
1045
+ }
1055
1046
  }
1047
+ else {
1048
+ const ins_res = await childTable.tryInsertRow(childRow, req.user || { role_id: 100 });
1049
+ if (ins_res.error) {
1050
+ await rollback();
1051
+ getState().log(6, `Insert child row failure ${JSON.stringify(ins_res)}`);
1052
+ req.flash("error", text_attr(ins_res.error));
1053
+ res.sendWrap(pagetitle, renderForm(form, req.csrfToken()));
1054
+ return true;
1055
+ }
1056
+ else if (ins_res.success) {
1057
+ submitted_row_ids.add(`${ins_res.success}`);
1058
+ }
1059
+ }
1060
+ repeatIx += 1;
1056
1061
  }
1057
- repeatIx += 1;
1058
- }
1059
- //need to delete any rows that are missing
1060
- if (originalID && field.metadata) {
1061
- const childRows = getRowQuery
1062
- ? await getRowQuery(field.metadata.table_id, view_select, originalID)
1063
- : await childTable.getRows({
1064
- [view_select.field_name]: originalID,
1065
- });
1066
- for (const db_child_row of childRows) {
1067
- if (!submitted_row_ids.has(`${db_child_row[childTable.pk_name]}`)) {
1068
- await childTable.deleteRows({
1069
- [childTable.pk_name]: db_child_row[childTable.pk_name],
1070
- }, req.user || { role_id: 100 });
1062
+ //need to delete any rows that are missing
1063
+ if (originalID && field.metadata) {
1064
+ const childRows = getRowQuery
1065
+ ? await getRowQuery(field.metadata.table_id, view_select, originalID)
1066
+ : await childTable.getRows({
1067
+ [view_select.field_name]: originalID,
1068
+ });
1069
+ for (const db_child_row of childRows) {
1070
+ if (!submitted_row_ids.has(`${db_child_row[childTable.pk_name]}`)) {
1071
+ await childTable.deleteRows({
1072
+ [childTable.pk_name]: db_child_row[childTable.pk_name],
1073
+ }, req.user || { role_id: 100 });
1074
+ }
1071
1075
  }
1072
1076
  }
1073
1077
  }
1074
- }
1078
+ });
1079
+ if (doReturn)
1080
+ return;
1081
+ //Edit-in-edit
1075
1082
  }
1076
1083
  trigger_return = trigger_return || {};
1077
1084
  if (trigger_return.notify && trigger_return.details)
@@ -1855,60 +1862,62 @@ module.exports = {
1855
1862
  });
1856
1863
  }
1857
1864
  try {
1858
- if (click_action) {
1859
- let container;
1860
- traverseSync(layout, {
1861
- container(segment) {
1862
- if (segment.click_action === click_action)
1863
- container = segment;
1864
- },
1865
- });
1866
- if (!container)
1867
- return { json: { error: "Action not found" } };
1868
- const trigger = Trigger.findOne({ name: click_action });
1869
- if (!trigger)
1870
- throw new Error(`View ${name}: Container click action ${click_action} not found`);
1871
- const result = await trigger.runWithoutRow({
1872
- table,
1873
- Table,
1874
- req,
1875
- row,
1876
- referrer: req?.get?.("Referrer"),
1877
- user: req.user,
1878
- });
1879
- return { json: { success: "ok", ...(result || {}) } };
1880
- }
1881
- else if (onchange_action && !rndid) {
1882
- const fldCol = columns.find((c) => c.field_name === onchange_field &&
1883
- c.onchange_action === onchange_action);
1884
- if (!fldCol)
1885
- return { json: { error: "Field not found" } };
1886
- const trigger = Trigger.findOne({ name: onchange_action });
1887
- if (!trigger)
1888
- throw new Error(`View ${name}: On change action ${onchange_action} for field ${onchange_field} not found`);
1889
- const result = await trigger.runWithoutRow({
1890
- table,
1891
- Table,
1892
- req,
1893
- row,
1894
- referrer: req?.get?.("Referrer"),
1895
- user: req.user,
1896
- });
1897
- return { json: { success: "ok", ...(result || {}) } };
1898
- }
1899
- else {
1900
- const col = columns.find((c) => c.type === "Action" && c.rndid === rndid && rndid);
1901
- const result = await run_action_column({
1902
- col,
1903
- req,
1904
- table,
1905
- row,
1906
- res,
1907
- referrer: req?.get?.("Referrer"),
1908
- });
1909
- //console.log("result", result);
1910
- return { json: { success: "ok", ...(result || {}) } };
1911
- }
1865
+ return await db.withTransaction(async () => {
1866
+ if (click_action) {
1867
+ let container;
1868
+ traverseSync(layout, {
1869
+ container(segment) {
1870
+ if (segment.click_action === click_action)
1871
+ container = segment;
1872
+ },
1873
+ });
1874
+ if (!container)
1875
+ return { json: { error: "Action not found" } };
1876
+ const trigger = Trigger.findOne({ name: click_action });
1877
+ if (!trigger)
1878
+ throw new Error(`View ${name}: Container click action ${click_action} not found`);
1879
+ const result = await trigger.runWithoutRow({
1880
+ table,
1881
+ Table,
1882
+ req,
1883
+ row,
1884
+ referrer: req?.get?.("Referrer"),
1885
+ user: req.user,
1886
+ });
1887
+ return { json: { success: "ok", ...(result || {}) } };
1888
+ }
1889
+ else if (onchange_action && !rndid) {
1890
+ const fldCol = columns.find((c) => c.field_name === onchange_field &&
1891
+ c.onchange_action === onchange_action);
1892
+ if (!fldCol)
1893
+ return { json: { error: "Field not found" } };
1894
+ const trigger = Trigger.findOne({ name: onchange_action });
1895
+ if (!trigger)
1896
+ throw new Error(`View ${name}: On change action ${onchange_action} for field ${onchange_field} not found`);
1897
+ const result = await trigger.runWithoutRow({
1898
+ table,
1899
+ Table,
1900
+ req,
1901
+ row,
1902
+ referrer: req?.get?.("Referrer"),
1903
+ user: req.user,
1904
+ });
1905
+ return { json: { success: "ok", ...(result || {}) } };
1906
+ }
1907
+ else {
1908
+ const col = columns.find((c) => c.type === "Action" && c.rndid === rndid && rndid);
1909
+ const result = await run_action_column({
1910
+ col,
1911
+ req,
1912
+ table,
1913
+ row,
1914
+ res,
1915
+ referrer: req?.get?.("Referrer"),
1916
+ });
1917
+ //console.log("result", result);
1918
+ return { json: { success: "ok", ...(result || {}) } };
1919
+ }
1920
+ });
1912
1921
  }
1913
1922
  catch (e) {
1914
1923
  console.error(e);