@saltcorn/data 0.7.1-beta.3 → 0.7.2-beta.2
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/app-locales/en.json +6 -0
- package/dist/app-locales/public/da.json +3 -0
- package/dist/app-locales/public/tlh.json +3 -0
- package/dist/base-plugin/actions.d.ts.map +1 -1
- package/dist/base-plugin/actions.js +4 -1
- package/dist/base-plugin/actions.js.map +1 -1
- package/dist/base-plugin/fieldviews.d.ts +29 -0
- package/dist/base-plugin/fieldviews.d.ts.map +1 -1
- package/dist/base-plugin/fieldviews.js +60 -5
- package/dist/base-plugin/fieldviews.js.map +1 -1
- package/dist/base-plugin/index.d.ts +245 -20
- package/dist/base-plugin/index.d.ts.map +1 -1
- package/dist/base-plugin/types.d.ts +127 -65
- package/dist/base-plugin/types.d.ts.map +1 -1
- package/dist/base-plugin/types.js +152 -36
- package/dist/base-plugin/types.js.map +1 -1
- package/dist/base-plugin/viewtemplates/edit.d.ts +46 -8
- package/dist/base-plugin/viewtemplates/edit.d.ts.map +1 -1
- package/dist/base-plugin/viewtemplates/edit.js +258 -112
- package/dist/base-plugin/viewtemplates/edit.js.map +1 -1
- package/dist/base-plugin/viewtemplates/feed.d.ts +14 -1
- package/dist/base-plugin/viewtemplates/feed.d.ts.map +1 -1
- package/dist/base-plugin/viewtemplates/feed.js +20 -8
- package/dist/base-plugin/viewtemplates/feed.js.map +1 -1
- package/dist/base-plugin/viewtemplates/filter.d.ts +17 -1
- package/dist/base-plugin/viewtemplates/filter.d.ts.map +1 -1
- package/dist/base-plugin/viewtemplates/filter.js +64 -45
- package/dist/base-plugin/viewtemplates/filter.js.map +1 -1
- package/dist/base-plugin/viewtemplates/list.d.ts +21 -1
- package/dist/base-plugin/viewtemplates/list.d.ts.map +1 -1
- package/dist/base-plugin/viewtemplates/list.js +63 -40
- package/dist/base-plugin/viewtemplates/list.js.map +1 -1
- package/dist/base-plugin/viewtemplates/listshowlist.d.ts +14 -1
- package/dist/base-plugin/viewtemplates/listshowlist.d.ts.map +1 -1
- package/dist/base-plugin/viewtemplates/listshowlist.js +15 -4
- package/dist/base-plugin/viewtemplates/listshowlist.js.map +1 -1
- package/dist/base-plugin/viewtemplates/room.d.ts +41 -1
- package/dist/base-plugin/viewtemplates/room.d.ts.map +1 -1
- package/dist/base-plugin/viewtemplates/room.js +107 -80
- package/dist/base-plugin/viewtemplates/room.js.map +1 -1
- package/dist/base-plugin/viewtemplates/show.d.ts +38 -4
- package/dist/base-plugin/viewtemplates/show.d.ts.map +1 -1
- package/dist/base-plugin/viewtemplates/show.js +120 -75
- package/dist/base-plugin/viewtemplates/show.js.map +1 -1
- package/dist/base-plugin/viewtemplates/viewable_fields.d.ts +26 -7
- package/dist/base-plugin/viewtemplates/viewable_fields.d.ts.map +1 -1
- package/dist/base-plugin/viewtemplates/viewable_fields.js +60 -48
- package/dist/base-plugin/viewtemplates/viewable_fields.js.map +1 -1
- package/dist/coverage/coverage-final.json +46 -0
- package/dist/coverage/lcov-report/block-navigation.d.ts +2 -0
- package/dist/coverage/lcov-report/block-navigation.d.ts.map +1 -0
- package/dist/coverage/lcov-report/block-navigation.js +71 -0
- package/dist/coverage/lcov-report/block-navigation.js.map +1 -0
- package/dist/coverage/lcov-report/prettify.d.ts +1 -0
- package/dist/coverage/lcov-report/prettify.d.ts.map +1 -0
- package/dist/coverage/lcov-report/prettify.js +478 -0
- package/dist/coverage/lcov-report/prettify.js.map +1 -0
- package/dist/coverage/lcov-report/sorter.d.ts +2 -0
- package/dist/coverage/lcov-report/sorter.d.ts.map +1 -0
- package/dist/coverage/lcov-report/sorter.js +164 -0
- package/dist/coverage/lcov-report/sorter.js.map +1 -0
- package/dist/db/connect.d.ts.map +1 -1
- package/dist/db/connect.js +8 -1
- package/dist/db/connect.js.map +1 -1
- package/dist/db/connect_mobile.d.ts +9 -0
- package/dist/db/connect_mobile.d.ts.map +1 -0
- package/dist/db/connect_mobile.js +15 -0
- package/dist/db/connect_mobile.js.map +1 -0
- package/dist/db/fixtures.d.ts.map +1 -1
- package/dist/db/fixtures.js +6 -1
- package/dist/db/fixtures.js.map +1 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +16 -2
- package/dist/db/index.js.map +1 -1
- package/dist/db/state.d.ts +207 -52
- package/dist/db/state.d.ts.map +1 -1
- package/dist/db/state.js +87 -84
- package/dist/db/state.js.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +27 -2
- package/dist/index.js.map +1 -1
- package/dist/migrate.d.ts.map +1 -1
- package/dist/migrate.js +54 -40
- package/dist/migrate.js.map +1 -1
- package/dist/mobile-mocks/db/postgres.d.ts +1 -0
- package/dist/mobile-mocks/db/postgres.d.ts.map +1 -0
- package/dist/mobile-mocks/db/postgres.js +2 -0
- package/dist/mobile-mocks/db/postgres.js.map +1 -0
- package/dist/mobile-mocks/db/sqlite.d.ts +1 -0
- package/dist/mobile-mocks/db/sqlite.d.ts.map +1 -0
- package/dist/mobile-mocks/db/sqlite.js +2 -0
- package/dist/mobile-mocks/db/sqlite.js.map +1 -0
- package/dist/mobile-mocks/models/email.d.ts +1 -0
- package/dist/mobile-mocks/models/email.d.ts.map +1 -0
- package/dist/mobile-mocks/models/email.js +2 -0
- package/dist/mobile-mocks/models/email.js.map +1 -0
- package/dist/mobile-mocks/node/async_hooks.d.ts +4 -0
- package/dist/mobile-mocks/node/async_hooks.d.ts.map +1 -0
- package/dist/mobile-mocks/node/async_hooks.js +8 -0
- package/dist/mobile-mocks/node/async_hooks.js.map +1 -0
- package/dist/mobile-mocks/node/child_process.d.ts +3 -0
- package/dist/mobile-mocks/node/child_process.d.ts.map +1 -0
- package/dist/mobile-mocks/node/child_process.js +6 -0
- package/dist/mobile-mocks/node/child_process.js.map +1 -0
- package/dist/mobile-mocks/node/fs/promises.d.ts +6 -0
- package/dist/mobile-mocks/node/fs/promises.d.ts.map +1 -0
- package/dist/mobile-mocks/node/fs/promises.js +16 -0
- package/dist/mobile-mocks/node/fs/promises.js.map +1 -0
- package/dist/mobile-mocks/node/fs.d.ts +4 -0
- package/dist/mobile-mocks/node/fs.d.ts.map +1 -0
- package/dist/mobile-mocks/node/fs.js +15 -0
- package/dist/mobile-mocks/node/fs.js.map +1 -0
- package/dist/mobile-mocks/node/latest-version.d.ts +2 -0
- package/dist/mobile-mocks/node/latest-version.d.ts.map +1 -0
- package/dist/mobile-mocks/node/latest-version.js +7 -0
- package/dist/mobile-mocks/node/latest-version.js.map +1 -0
- package/dist/mobile-mocks/node/v8.d.ts +3 -0
- package/dist/mobile-mocks/node/v8.d.ts.map +1 -0
- package/dist/mobile-mocks/node/v8.js +8 -0
- package/dist/mobile-mocks/node/v8.js.map +1 -0
- package/dist/mobile-mocks/npm/env-paths.d.ts +6 -0
- package/dist/mobile-mocks/npm/env-paths.d.ts.map +1 -0
- package/dist/mobile-mocks/npm/env-paths.js +9 -0
- package/dist/mobile-mocks/npm/env-paths.js.map +1 -0
- package/dist/mobile-mocks/saltcorn/plugin-testing.d.ts +1 -0
- package/dist/mobile-mocks/saltcorn/plugin-testing.d.ts.map +1 -0
- package/dist/mobile-mocks/saltcorn/plugin-testing.js +2 -0
- package/dist/mobile-mocks/saltcorn/plugin-testing.js.map +1 -0
- package/dist/models/config.d.ts +9 -10
- package/dist/models/config.d.ts.map +1 -1
- package/dist/models/config.js +8 -7
- package/dist/models/config.js.map +1 -1
- package/dist/models/discovery.d.ts.map +1 -1
- package/dist/models/discovery.js +5 -1
- package/dist/models/discovery.js.map +1 -1
- package/dist/models/email.d.ts +2 -0
- package/dist/models/email.d.ts.map +1 -1
- package/dist/models/field.d.ts +6 -4
- package/dist/models/field.d.ts.map +1 -1
- package/dist/models/field.js +40 -21
- package/dist/models/field.js.map +1 -1
- package/dist/models/fieldrepeat.d.ts +5 -0
- package/dist/models/fieldrepeat.d.ts.map +1 -1
- package/dist/models/fieldrepeat.js +2 -0
- package/dist/models/fieldrepeat.js.map +1 -1
- package/dist/models/form.d.ts +2 -0
- package/dist/models/form.d.ts.map +1 -1
- package/dist/models/form.js +1 -0
- package/dist/models/form.js.map +1 -1
- package/dist/models/index.d.ts +2 -13
- package/dist/models/index.d.ts.map +1 -1
- package/dist/models/layout.d.ts.map +1 -1
- package/dist/models/layout.js +12 -2
- package/dist/models/layout.js.map +1 -1
- package/dist/models/page.d.ts +1 -1
- package/dist/models/page.d.ts.map +1 -1
- package/dist/models/page.js +17 -9
- package/dist/models/page.js.map +1 -1
- package/dist/models/scheduler.d.ts.map +1 -1
- package/dist/models/scheduler.js +3 -1
- package/dist/models/scheduler.js.map +1 -1
- package/dist/models/table.d.ts +2 -1
- package/dist/models/table.d.ts.map +1 -1
- package/dist/models/table.js +32 -11
- package/dist/models/table.js.map +1 -1
- package/dist/models/trigger.d.ts +3 -3
- package/dist/models/trigger.d.ts.map +1 -1
- package/dist/models/trigger.js +4 -5
- package/dist/models/trigger.js.map +1 -1
- package/dist/models/user.d.ts +1 -1
- package/dist/models/user.d.ts.map +1 -1
- package/dist/models/user.js +7 -15
- package/dist/models/user.js.map +1 -1
- package/dist/models/view.d.ts +16 -12
- package/dist/models/view.d.ts.map +1 -1
- package/dist/models/view.js +63 -15
- package/dist/models/view.js.map +1 -1
- package/dist/models/workflow.d.ts +1 -0
- package/dist/models/workflow.d.ts.map +1 -1
- package/dist/models/workflow.js +58 -2
- package/dist/models/workflow.js.map +1 -1
- package/dist/package.json +127 -0
- package/dist/plugin-helper.d.ts +17 -13
- package/dist/plugin-helper.d.ts.map +1 -1
- package/dist/plugin-helper.js +122 -74
- package/dist/plugin-helper.js.map +1 -1
- package/dist/plugin-testing.d.ts +1 -0
- package/dist/plugin-testing.d.ts.map +1 -1
- package/dist/plugin-testing.js +84 -1
- package/dist/plugin-testing.js.map +1 -1
- package/dist/tests/actions.test.js +30 -5
- package/dist/tests/actions.test.js.map +1 -1
- package/dist/tests/db.test.d.ts +2 -0
- package/dist/tests/db.test.d.ts.map +1 -0
- package/dist/tests/db.test.js +32 -0
- package/dist/tests/db.test.js.map +1 -0
- package/dist/tests/exact_views.test.js +274 -19
- package/dist/tests/exact_views.test.js.map +1 -1
- package/dist/tests/field.test.js +36 -0
- package/dist/tests/field.test.js.map +1 -1
- package/dist/tests/mocks.d.ts +2 -0
- package/dist/tests/mocks.d.ts.map +1 -1
- package/dist/tests/mocks.js +2 -0
- package/dist/tests/mocks.js.map +1 -1
- package/dist/tests/models.test.js +46 -1
- package/dist/tests/models.test.js.map +1 -1
- package/dist/tests/remote_query_helper.d.ts +341 -0
- package/dist/tests/remote_query_helper.d.ts.map +1 -0
- package/dist/tests/remote_query_helper.js +446 -0
- package/dist/tests/remote_query_helper.js.map +1 -0
- package/dist/tests/state.test.d.ts +2 -0
- package/dist/tests/state.test.d.ts.map +1 -0
- package/dist/tests/state.test.js +78 -0
- package/dist/tests/state.test.js.map +1 -0
- package/dist/tests/table.test.js +19 -0
- package/dist/tests/table.test.js.map +1 -1
- package/dist/tests/view.test.js +29 -0
- package/dist/tests/view.test.js.map +1 -1
- package/dist/tsconfig.json +24 -0
- package/dist/tsconfig.ref.json +9 -0
- package/dist/tsconfig.ref.tsbuildinfo +1 -1
- package/dist/utils.d.ts +3 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +14 -23
- package/dist/utils.js.map +1 -1
- package/dist/webpack.config.d.ts +57 -0
- package/dist/webpack.config.d.ts.map +1 -0
- package/dist/webpack.config.js +75 -0
- package/dist/webpack.config.js.map +1 -0
- package/package.json +38 -13
- package/CHANGELOG.md +0 -8
- package/dist/models/backup.d.ts +0 -9
- package/dist/models/backup.d.ts.map +0 -1
- package/dist/models/backup.js +0 -278
- package/dist/models/backup.js.map +0 -1
- package/dist/models/pack.d.ts +0 -42
- package/dist/models/pack.d.ts.map +0 -1
- package/dist/models/pack.js +0 -419
- package/dist/models/pack.js.map +0 -1
- package/dist/models/tenant.d.ts +0 -17
- package/dist/models/tenant.d.ts.map +0 -1
- package/dist/models/tenant.js +0 -152
- package/dist/models/tenant.js.map +0 -1
- package/dist/tests/backup.test.d.ts +0 -2
- package/dist/tests/backup.test.d.ts.map +0 -1
- package/dist/tests/backup.test.js +0 -101
- package/dist/tests/backup.test.js.map +0 -1
- package/dist/tests/pack.test.d.ts +0 -2
- package/dist/tests/pack.test.d.ts.map +0 -1
- package/dist/tests/pack.test.js +0 -338
- package/dist/tests/pack.test.js.map +0 -1
- package/dist/tests/random.test.d.ts +0 -2
- package/dist/tests/random.test.d.ts.map +0 -1
- package/dist/tests/random.test.js +0 -149
- package/dist/tests/random.test.js.map +0 -1
- package/dist/tests/tenant.test.d.ts +0 -2
- package/dist/tests/tenant.test.d.ts.map +0 -1
- package/dist/tests/tenant.test.js +0 -52
- package/dist/tests/tenant.test.js.map +0 -1
|
@@ -16,12 +16,13 @@ const { text, text_attr } = require("@saltcorn/markup/tags");
|
|
|
16
16
|
const { renderForm } = require("@saltcorn/markup");
|
|
17
17
|
const FieldRepeat = require("../../models/fieldrepeat");
|
|
18
18
|
const { get_expression_function, expressionChecker, } = require("../../models/expression");
|
|
19
|
-
const { InvalidConfiguration } = require("../../utils");
|
|
19
|
+
const { InvalidConfiguration, isNode } = require("../../utils");
|
|
20
20
|
const Library = require("../../models/library");
|
|
21
|
+
const { check_view_columns } = require("../../plugin-testing");
|
|
21
22
|
const { initial_config_all_fields, calcfldViewOptions, calcfldViewConfig, get_parent_views, get_link_view_opts, picked_fields_to_query, stateFieldsToWhere, stateFieldsToQuery, strictParseInt, } = require("../../plugin-helper");
|
|
22
23
|
const { splitUniques, getForm, fill_presets, parse_view_select, get_view_link_query, objToQueryString, } = require("./viewable_fields");
|
|
23
|
-
const { traverse, getStringsForI18n, translateLayout, } = require("../../models/layout");
|
|
24
|
-
const { asyncMap } = require("../../utils");
|
|
24
|
+
const { traverse, getStringsForI18n, translateLayout, traverseSync, } = require("../../models/layout");
|
|
25
|
+
const { asyncMap, isWeb } = require("../../utils");
|
|
25
26
|
/**
|
|
26
27
|
* @param {object} req
|
|
27
28
|
* @returns {Workflow}
|
|
@@ -42,7 +43,7 @@ const configuration_workflow = (req) => new Workflow({
|
|
|
42
43
|
await field.reftable.getFields();
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
|
-
const { field_view_options, handlesTextStyle } = calcfldViewOptions(fields, "edit");
|
|
46
|
+
const { field_view_options, handlesTextStyle, blockDisplay } = calcfldViewOptions(fields, "edit");
|
|
46
47
|
const fieldViewConfigForms = await calcfldViewConfig(fields, true);
|
|
47
48
|
const roles = await User.get_roles();
|
|
48
49
|
const images = await File.find({ mime_super: "image" });
|
|
@@ -115,6 +116,7 @@ const configuration_workflow = (req) => new Workflow({
|
|
|
115
116
|
field_view_options,
|
|
116
117
|
parent_field_list,
|
|
117
118
|
handlesTextStyle,
|
|
119
|
+
blockDisplay,
|
|
118
120
|
roles,
|
|
119
121
|
actions,
|
|
120
122
|
fieldViewConfigForms,
|
|
@@ -185,7 +187,6 @@ const configuration_workflow = (req) => new Workflow({
|
|
|
185
187
|
done_view_opts.push(`${v.name}.${relation.name}`);
|
|
186
188
|
}));
|
|
187
189
|
return new Form({
|
|
188
|
-
blurb: req.__("The view you choose here can be ignored depending on the context of the form, for instance if it appears in a pop-up the redirect will not take place."),
|
|
189
190
|
fields: [
|
|
190
191
|
{
|
|
191
192
|
name: "auto_save",
|
|
@@ -194,24 +195,36 @@ const configuration_workflow = (req) => new Workflow({
|
|
|
194
195
|
type: "Bool",
|
|
195
196
|
},
|
|
196
197
|
{
|
|
197
|
-
name: "
|
|
198
|
-
label:
|
|
199
|
-
sublabel: req.__("This is the view to which the user will be sent when the form is submitted, unless a formula below is true."),
|
|
198
|
+
name: "destination_type",
|
|
199
|
+
label: "Destination type",
|
|
200
200
|
type: "String",
|
|
201
201
|
required: true,
|
|
202
|
+
sublabel: req.__("This is the view to which the user will be sent when the form is submitted. The view you specify here can be ignored depending on the context of the form, for instance if it appears in a pop-up the redirect will not take place."),
|
|
203
|
+
//fieldview: "radio_group",
|
|
202
204
|
attributes: {
|
|
203
|
-
options:
|
|
205
|
+
options: ["View", "Formula", "Back to referer"],
|
|
204
206
|
},
|
|
205
207
|
},
|
|
206
208
|
{
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
209
|
+
name: "view_when_done",
|
|
210
|
+
label: req.__("Destination view"),
|
|
211
|
+
type: "String",
|
|
212
|
+
required: true,
|
|
213
|
+
attributes: {
|
|
214
|
+
options: done_view_opts,
|
|
215
|
+
},
|
|
216
|
+
showIf: { destination_type: "View" },
|
|
210
217
|
},
|
|
211
218
|
new FieldRepeat({
|
|
212
219
|
name: "formula_destinations",
|
|
220
|
+
showIf: { destination_type: "Formula" },
|
|
213
221
|
fields: [
|
|
214
|
-
{
|
|
222
|
+
{
|
|
223
|
+
type: "String",
|
|
224
|
+
name: "expression",
|
|
225
|
+
label: "Formula",
|
|
226
|
+
sublabel: "if this formula evaluates to true, use the following view",
|
|
227
|
+
},
|
|
215
228
|
{
|
|
216
229
|
name: "view",
|
|
217
230
|
label: req.__("View"),
|
|
@@ -268,26 +281,8 @@ const initial_config = initial_config_all_fields(true);
|
|
|
268
281
|
* @param {object} optsTwo.res
|
|
269
282
|
* @returns {Promise<Form>}
|
|
270
283
|
*/
|
|
271
|
-
const run = async (table_id, viewname, {
|
|
272
|
-
|
|
273
|
-
const fields = await table.getFields();
|
|
274
|
-
const { uniques, nonUniques } = splitUniques(fields, state);
|
|
275
|
-
let row = null;
|
|
276
|
-
if (Object.keys(uniques).length > 0) {
|
|
277
|
-
row = await table.getRow(uniques);
|
|
278
|
-
}
|
|
279
|
-
return await render({
|
|
280
|
-
table,
|
|
281
|
-
fields,
|
|
282
|
-
viewname,
|
|
283
|
-
columns,
|
|
284
|
-
layout,
|
|
285
|
-
row,
|
|
286
|
-
req,
|
|
287
|
-
res,
|
|
288
|
-
state,
|
|
289
|
-
auto_save,
|
|
290
|
-
});
|
|
284
|
+
const run = async (table_id, viewname, {}, state, { res, req }, { editQuery }) => {
|
|
285
|
+
return await editQuery(state);
|
|
291
286
|
};
|
|
292
287
|
/**
|
|
293
288
|
* @param {number} table_id
|
|
@@ -299,22 +294,8 @@ const run = async (table_id, viewname, { columns, layout, auto_save }, state, {
|
|
|
299
294
|
* @param {object} extra
|
|
300
295
|
* @returns {Promise<Form[]>}
|
|
301
296
|
*/
|
|
302
|
-
const runMany = async (table_id, viewname, { columns, layout, auto_save }, state, extra) => {
|
|
303
|
-
const table
|
|
304
|
-
const fields = await table.getFields();
|
|
305
|
-
const { joinFields, aggregations } = picked_fields_to_query(columns, fields);
|
|
306
|
-
const qstate = await stateFieldsToWhere({ fields, state });
|
|
307
|
-
const q = await stateFieldsToQuery({ state, fields });
|
|
308
|
-
const rows = await table.getJoinedRows({
|
|
309
|
-
where: qstate,
|
|
310
|
-
joinFields,
|
|
311
|
-
aggregations,
|
|
312
|
-
...(extra && extra.limit && { limit: extra.limit }),
|
|
313
|
-
...(extra && extra.offset && { offset: extra.offset }),
|
|
314
|
-
...(extra && extra.orderBy && { orderBy: extra.orderBy }),
|
|
315
|
-
...(extra && extra.orderDesc && { orderDesc: extra.orderDesc }),
|
|
316
|
-
...q,
|
|
317
|
-
});
|
|
297
|
+
const runMany = async (table_id, viewname, { columns, layout, auto_save }, state, extra, { editManyQuery, getRowQuery }) => {
|
|
298
|
+
const { table, fields, rows } = editManyQuery();
|
|
318
299
|
return await asyncMap(rows, async (row) => {
|
|
319
300
|
const html = await render({
|
|
320
301
|
table,
|
|
@@ -327,6 +308,7 @@ const runMany = async (table_id, viewname, { columns, layout, auto_save }, state
|
|
|
327
308
|
res: extra.res,
|
|
328
309
|
state,
|
|
329
310
|
auto_save,
|
|
311
|
+
getRowQuery,
|
|
330
312
|
});
|
|
331
313
|
return { html, row };
|
|
332
314
|
});
|
|
@@ -341,7 +323,7 @@ const runMany = async (table_id, viewname, { columns, layout, auto_save }, state
|
|
|
341
323
|
* @throws {InvalidConfiguration}
|
|
342
324
|
* @returns {Promise<void>}
|
|
343
325
|
*/
|
|
344
|
-
const transformForm = async ({ form, table, req, row, res }) => {
|
|
326
|
+
const transformForm = async ({ form, table, req, row, res, getRowQuery }) => {
|
|
345
327
|
await traverse(form.layout, {
|
|
346
328
|
action(segment) {
|
|
347
329
|
if (segment.action_name === "Delete") {
|
|
@@ -359,13 +341,53 @@ const transformForm = async ({ form, table, req, row, res }) => {
|
|
|
359
341
|
segment.sourceURL = `/field/show-calculated/${table.name}/${segment.join_field}/${segment.fieldview}?${qs}`;
|
|
360
342
|
},
|
|
361
343
|
async view(segment) {
|
|
344
|
+
//console.log(segment);
|
|
345
|
+
const view_select = parse_view_select(segment.view);
|
|
346
|
+
//console.log({ view_select });
|
|
347
|
+
const view = await View.findOne({ name: view_select.viewname });
|
|
348
|
+
if (!view)
|
|
349
|
+
throw new InvalidConfiguration(`Cannot find embedded view: ${view_select.viewname}`);
|
|
350
|
+
if (view.viewtemplate === "Edit" && view_select.type === "ChildList") {
|
|
351
|
+
const childTable = Table.findOne({ id: view.table_id });
|
|
352
|
+
const childForm = await getForm(childTable, view.name, view.configuration.columns, view.configuration.layout, row?.id, req);
|
|
353
|
+
traverseSync(childForm.layout, {
|
|
354
|
+
field(segment) {
|
|
355
|
+
segment.field_name = `${view_select.field_name}.${segment.field_name}`;
|
|
356
|
+
},
|
|
357
|
+
});
|
|
358
|
+
const fr = new FieldRepeat({
|
|
359
|
+
name: view_select.field_name,
|
|
360
|
+
label: view_select.field_name,
|
|
361
|
+
fields: childForm.fields,
|
|
362
|
+
layout: childForm.layout,
|
|
363
|
+
metadata: {
|
|
364
|
+
table_id: childTable.id,
|
|
365
|
+
relation: view_select.field_name,
|
|
366
|
+
},
|
|
367
|
+
});
|
|
368
|
+
if (row?.id) {
|
|
369
|
+
const childRows = getRowQuery
|
|
370
|
+
? await getRowQuery(view.table_id, view_select, row.id)
|
|
371
|
+
: await childTable.getRows({
|
|
372
|
+
[view_select.field_name]: row.id,
|
|
373
|
+
});
|
|
374
|
+
fr.metadata.rows = childRows;
|
|
375
|
+
if (!fr.fields.map((f) => f.name).includes(childTable.pk_name))
|
|
376
|
+
fr.fields.push({
|
|
377
|
+
name: childTable.pk_name,
|
|
378
|
+
input_type: "hidden",
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
form.fields.push(fr);
|
|
382
|
+
segment.type = "field_repeat";
|
|
383
|
+
segment.field_repeat = fr;
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
362
386
|
if (!row) {
|
|
363
387
|
segment.type = "blank";
|
|
364
388
|
segment.contents = "";
|
|
365
389
|
return;
|
|
366
390
|
}
|
|
367
|
-
const view_select = parse_view_select(segment.view);
|
|
368
|
-
const view = await View.findOne({ name: view_select.viewname });
|
|
369
391
|
if (!view)
|
|
370
392
|
throw new InvalidConfiguration(`Edit view incorrectly configured: cannot find embedded view ${view_select.viewname}`);
|
|
371
393
|
let state;
|
|
@@ -405,10 +427,10 @@ const transformForm = async ({ form, table, req, row, res }) => {
|
|
|
405
427
|
* @param {object} opts.res
|
|
406
428
|
* @returns {Promise<Form>}
|
|
407
429
|
*/
|
|
408
|
-
const render = async ({ table, fields, viewname, columns, layout, row, req, state, res, auto_save, }) => {
|
|
409
|
-
const form = await getForm(table, viewname, columns, layout, state.id, req);
|
|
430
|
+
const render = async ({ table, fields, viewname, columns, layout, row, req, state, res, auto_save, destination_type, isRemote, getRowQuery, }) => {
|
|
431
|
+
const form = await getForm(table, viewname, columns, layout, state.id, req, isRemote);
|
|
410
432
|
if (auto_save)
|
|
411
|
-
form.onChange = `saveAndContinue(this)`;
|
|
433
|
+
form.onChange = `saveAndContinue(this, ${!isWeb(req) ? `'${form.action}'` : undefined})`;
|
|
412
434
|
if (row) {
|
|
413
435
|
form.values = row;
|
|
414
436
|
const file_fields = form.fields.filter((f) => f.type === "File");
|
|
@@ -420,6 +442,10 @@ const render = async ({ table, fields, viewname, columns, layout, row, req, stat
|
|
|
420
442
|
}
|
|
421
443
|
form.hidden(table.pk_name);
|
|
422
444
|
}
|
|
445
|
+
if (destination_type === "Back to referer") {
|
|
446
|
+
form.hidden("_referer");
|
|
447
|
+
form.values._referer = req.headers?.referer;
|
|
448
|
+
}
|
|
423
449
|
Object.entries(state).forEach(([k, v]) => {
|
|
424
450
|
const field = form.fields.find((f) => f.name === k);
|
|
425
451
|
if (field && ((field.type && field.type.read) || field.is_fkey)) {
|
|
@@ -434,8 +460,8 @@ const render = async ({ table, fields, viewname, columns, layout, row, req, stat
|
|
|
434
460
|
}
|
|
435
461
|
});
|
|
436
462
|
await form.fill_fkey_options();
|
|
437
|
-
await transformForm({ form, table, req, row, res });
|
|
438
|
-
return renderForm(form, req.csrfToken());
|
|
463
|
+
await transformForm({ form, table, req, row, res, getRowQuery });
|
|
464
|
+
return renderForm(form, !isRemote ? req.csrfToken() : false);
|
|
439
465
|
};
|
|
440
466
|
/**
|
|
441
467
|
* @param {number} table_id
|
|
@@ -454,12 +480,12 @@ const render = async ({ table, fields, viewname, columns, layout, row, req, stat
|
|
|
454
480
|
* @param {string} optsTwo.redirect
|
|
455
481
|
* @returns {Promise<void>}
|
|
456
482
|
*/
|
|
457
|
-
const runPost = async (table_id, viewname, { columns, layout, fixed, view_when_done, formula_destinations, auto_save }, state, body, { res, req, redirect }) => {
|
|
483
|
+
const runPost = async (table_id, viewname, { columns, layout, fixed, view_when_done, formula_destinations, auto_save, destination_type, }, state, body, { res, req, redirect }, { tryInsertQuery, tryUpdateQuery, getRowQuery }) => {
|
|
458
484
|
const table = await Table.findOne({ id: table_id });
|
|
459
485
|
const fields = await table.getFields();
|
|
460
486
|
const form = await getForm(table, viewname, columns, layout, body.id, req);
|
|
461
487
|
if (auto_save)
|
|
462
|
-
form.onChange = `saveAndContinue(this)`;
|
|
488
|
+
form.onChange = `saveAndContinue(this, ${!isWeb(req) ? `'${form.action}'` : undefined})`;
|
|
463
489
|
Object.entries(body).forEach(([k, v]) => {
|
|
464
490
|
const form_field = form.fields.find((f) => f.name === k);
|
|
465
491
|
const tbl_field = fields.find((f) => f.name === k);
|
|
@@ -468,13 +494,21 @@ const runPost = async (table_id, viewname, { columns, layout, fixed, view_when_d
|
|
|
468
494
|
}
|
|
469
495
|
});
|
|
470
496
|
setDateLocales(form, req.getLocale());
|
|
497
|
+
await transformForm({
|
|
498
|
+
form,
|
|
499
|
+
table,
|
|
500
|
+
req,
|
|
501
|
+
row: body[table.pk_name]
|
|
502
|
+
? { [table.pk_name]: body[table.pk_name] }
|
|
503
|
+
: undefined,
|
|
504
|
+
getRowQuery,
|
|
505
|
+
});
|
|
471
506
|
form.validate(body);
|
|
472
507
|
if (form.hasErrors) {
|
|
473
508
|
if (req.xhr)
|
|
474
509
|
res.status(422);
|
|
475
510
|
await form.fill_fkey_options();
|
|
476
|
-
|
|
477
|
-
res.sendWrap(viewname, renderForm(form, req.csrfToken()));
|
|
511
|
+
res.sendWrap(viewname, renderForm(form, req.csrfToken ? req.csrfToken() : false));
|
|
478
512
|
}
|
|
479
513
|
else {
|
|
480
514
|
let row;
|
|
@@ -485,7 +519,10 @@ const runPost = async (table_id, viewname, { columns, layout, fixed, view_when_d
|
|
|
485
519
|
row = { ...use_fixed, ...form.values };
|
|
486
520
|
}
|
|
487
521
|
else {
|
|
488
|
-
row = form.values;
|
|
522
|
+
row = { ...form.values };
|
|
523
|
+
}
|
|
524
|
+
for (const field of form.fields.filter((f) => f.isRepeat)) {
|
|
525
|
+
delete row[field.name];
|
|
489
526
|
}
|
|
490
527
|
const file_fields = form.fields.filter((f) => f.type === "File");
|
|
491
528
|
for (const field of file_fields) {
|
|
@@ -499,77 +536,102 @@ const runPost = async (table_id, viewname, { columns, layout, fixed, view_when_d
|
|
|
499
536
|
}
|
|
500
537
|
const originalID = id;
|
|
501
538
|
if (typeof id === "undefined") {
|
|
502
|
-
const ins_res = await
|
|
539
|
+
const ins_res = await tryInsertQuery(row);
|
|
503
540
|
if (ins_res.success) {
|
|
504
541
|
id = ins_res.success;
|
|
505
542
|
row[pk.name] = id;
|
|
506
543
|
}
|
|
507
544
|
else {
|
|
508
545
|
req.flash("error", text_attr(ins_res.error));
|
|
509
|
-
res.sendWrap(viewname, renderForm(form, req.csrfToken()));
|
|
546
|
+
res.sendWrap(viewname, renderForm(form, req.csrfToken ? req.csrfToken() : false));
|
|
510
547
|
return;
|
|
511
548
|
}
|
|
512
549
|
}
|
|
513
550
|
else {
|
|
514
|
-
const upd_res = await
|
|
551
|
+
const upd_res = await tryUpdateQuery(row, id);
|
|
515
552
|
if (upd_res.error) {
|
|
516
553
|
req.flash("error", text_attr(upd_res.error));
|
|
517
554
|
res.sendWrap(viewname, renderForm(form, req.csrfToken()));
|
|
518
555
|
return;
|
|
519
556
|
}
|
|
520
557
|
}
|
|
521
|
-
|
|
522
|
-
|
|
558
|
+
for (const field of form.fields.filter((f) => f.isRepeat)) {
|
|
559
|
+
const childTable = Table.findOne({ id: field.metadata?.table_id });
|
|
560
|
+
for (const childRow of form.values[field.name]) {
|
|
561
|
+
childRow[field.metadata?.relation] = id;
|
|
562
|
+
if (childRow[childTable.pk_name]) {
|
|
563
|
+
const upd_res = await childTable.tryUpdateRow(childRow, childRow[childTable.pk_name]);
|
|
564
|
+
if (upd_res.error) {
|
|
565
|
+
req.flash("error", text_attr(upd_res.error));
|
|
566
|
+
res.sendWrap(viewname, renderForm(form, req.csrfToken()));
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
else {
|
|
571
|
+
const ins_res = await childTable.tryInsertRow(childRow, req.user ? +req.user.id : undefined);
|
|
572
|
+
if (ins_res.error) {
|
|
573
|
+
req.flash("error", text_attr(ins_res.error));
|
|
574
|
+
res.sendWrap(viewname, renderForm(form, req.csrfToken()));
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
if (req.xhr && !originalID && !req.smr) {
|
|
581
|
+
res.json({ id, view_when_done });
|
|
523
582
|
return;
|
|
524
583
|
}
|
|
525
584
|
if (redirect) {
|
|
526
585
|
res.redirect(redirect);
|
|
527
586
|
return;
|
|
528
587
|
}
|
|
529
|
-
|
|
530
|
-
|
|
588
|
+
let use_view_when_done = view_when_done;
|
|
589
|
+
if (destination_type === "Back to referer" && body._referer) {
|
|
590
|
+
res.redirect(body._referer);
|
|
531
591
|
return;
|
|
532
592
|
}
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
593
|
+
else if (destination_type !== "View")
|
|
594
|
+
for (const { view, expression } of formula_destinations || []) {
|
|
595
|
+
if (expression) {
|
|
596
|
+
const f = get_expression_function(expression, fields);
|
|
597
|
+
if (f(row)) {
|
|
598
|
+
use_view_when_done = view;
|
|
599
|
+
continue;
|
|
600
|
+
}
|
|
540
601
|
}
|
|
541
602
|
}
|
|
603
|
+
if (!use_view_when_done) {
|
|
604
|
+
res.redirect(`/`);
|
|
605
|
+
return;
|
|
542
606
|
}
|
|
543
607
|
const [viewname_when_done, relation] = use_view_when_done.split(".");
|
|
544
608
|
const nxview = await View.findOne({ name: viewname_when_done });
|
|
545
|
-
//console.log()
|
|
546
609
|
if (!nxview) {
|
|
547
610
|
req.flash("warning", `View "${use_view_when_done}" not found - change "View when done" in "${viewname}" view`);
|
|
548
611
|
res.redirect(`/`);
|
|
549
612
|
}
|
|
550
613
|
else {
|
|
551
614
|
const state_fields = await nxview.get_state_fields();
|
|
615
|
+
let target = `/view/${text(viewname_when_done)}`;
|
|
616
|
+
let query = "";
|
|
552
617
|
if ((nxview.table_id === table_id || relation) &&
|
|
553
618
|
state_fields.some((sf) => sf.name === pk.name)) {
|
|
554
619
|
const get_query = get_view_link_query(fields);
|
|
555
|
-
|
|
620
|
+
query = relation
|
|
556
621
|
? `?${pk.name}=${text(row[relation])}`
|
|
557
622
|
: get_query(row);
|
|
558
|
-
res.redirect(`/view/${text(viewname_when_done)}${query}`);
|
|
559
623
|
}
|
|
560
|
-
|
|
561
|
-
|
|
624
|
+
const redirectPath = `${target}${query}`;
|
|
625
|
+
if (!isWeb(req)) {
|
|
626
|
+
res.json({ redirect: `get${redirectPath}` });
|
|
627
|
+
}
|
|
628
|
+
else {
|
|
629
|
+
res.redirect(redirectPath);
|
|
630
|
+
}
|
|
562
631
|
}
|
|
563
632
|
}
|
|
564
633
|
};
|
|
565
|
-
|
|
566
|
-
* @param {object} opts
|
|
567
|
-
* @param {object} opts.body
|
|
568
|
-
* @param {string} opts.table_id
|
|
569
|
-
* @param {object} opts.req
|
|
570
|
-
* @returns {Promise<boolean>}
|
|
571
|
-
*/
|
|
572
|
-
const authorise_post = async ({ body, table_id, req }) => {
|
|
634
|
+
const doAuthPost = async ({ body, table_id, req }) => {
|
|
573
635
|
const table = await Table.findOne({ id: table_id });
|
|
574
636
|
const user_id = req.user ? req.user.id : null;
|
|
575
637
|
if (table.ownership_field_id && user_id) {
|
|
@@ -592,6 +654,16 @@ const authorise_post = async ({ body, table_id, req }) => {
|
|
|
592
654
|
return true;
|
|
593
655
|
return false;
|
|
594
656
|
};
|
|
657
|
+
/**
|
|
658
|
+
* @param {object} opts
|
|
659
|
+
* @param {object} opts.body
|
|
660
|
+
* @param {string} opts.table_id
|
|
661
|
+
* @param {object} opts.req
|
|
662
|
+
* @returns {Promise<boolean>}
|
|
663
|
+
*/
|
|
664
|
+
const authorise_post = async ({ body, table_id, req }, { authorizePostQuery }) => {
|
|
665
|
+
return await authorizePostQuery(body, table_id);
|
|
666
|
+
};
|
|
595
667
|
module.exports = {
|
|
596
668
|
/** @type {string} */
|
|
597
669
|
name: "Edit",
|
|
@@ -612,20 +684,8 @@ module.exports = {
|
|
|
612
684
|
* @param {...*} opts.rest
|
|
613
685
|
* @returns {Promise<boolean>}
|
|
614
686
|
*/
|
|
615
|
-
authorise_get: async ({ query, table_id, req }) => {
|
|
616
|
-
|
|
617
|
-
if (Object.keys(body).length == 1) {
|
|
618
|
-
const table = await Table.findOne({ id: table_id });
|
|
619
|
-
if (table.ownership_field_id || table.ownership_formula) {
|
|
620
|
-
const fields = await table.getFields();
|
|
621
|
-
const { uniques } = splitUniques(fields, body);
|
|
622
|
-
if (Object.keys(uniques).length > 0) {
|
|
623
|
-
body = await table.getRow(uniques);
|
|
624
|
-
return table.is_owner(req.user, body);
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
return authorise_post({ body, table_id, req });
|
|
687
|
+
authorise_get: async ({ query, table_id, req }, { authorizeGetQuery }) => {
|
|
688
|
+
return await authorizeGetQuery(query, table_id);
|
|
629
689
|
},
|
|
630
690
|
/**
|
|
631
691
|
* @param {object} opts
|
|
@@ -635,17 +695,103 @@ module.exports = {
|
|
|
635
695
|
getStringsForI18n({ layout }) {
|
|
636
696
|
return getStringsForI18n(layout);
|
|
637
697
|
},
|
|
638
|
-
|
|
698
|
+
queries: ({ table_id, name, configuration: { columns, default_state, layout, auto_save, destination_type, }, req, res, }) => ({
|
|
699
|
+
async editQuery(state) {
|
|
700
|
+
const table = await Table.findOne({ id: table_id });
|
|
701
|
+
const fields = await table.getFields();
|
|
702
|
+
const { uniques } = splitUniques(fields, state);
|
|
703
|
+
let row = null;
|
|
704
|
+
if (Object.keys(uniques).length > 0) {
|
|
705
|
+
row = await table.getRow(uniques);
|
|
706
|
+
}
|
|
707
|
+
const isRemote = !isWeb(req);
|
|
708
|
+
return await render({
|
|
709
|
+
table,
|
|
710
|
+
fields,
|
|
711
|
+
viewname: name,
|
|
712
|
+
columns,
|
|
713
|
+
layout,
|
|
714
|
+
row,
|
|
715
|
+
req,
|
|
716
|
+
res,
|
|
717
|
+
state,
|
|
718
|
+
auto_save,
|
|
719
|
+
destination_type,
|
|
720
|
+
isRemote,
|
|
721
|
+
});
|
|
722
|
+
},
|
|
723
|
+
async editManyQuery(state) {
|
|
724
|
+
const table = await Table.findOne({ id: table_id });
|
|
725
|
+
const fields = await table.getFields();
|
|
726
|
+
const { joinFields, aggregations } = picked_fields_to_query(columns, fields);
|
|
727
|
+
const qstate = await stateFieldsToWhere({ fields, state });
|
|
728
|
+
const q = await stateFieldsToQuery({ state, fields });
|
|
729
|
+
const rows = await table.getJoinedRows({
|
|
730
|
+
where: qstate,
|
|
731
|
+
joinFields,
|
|
732
|
+
aggregations,
|
|
733
|
+
...(extra && extra.limit && { limit: extra.limit }),
|
|
734
|
+
...(extra && extra.offset && { offset: extra.offset }),
|
|
735
|
+
...(extra && extra.orderBy && { orderBy: extra.orderBy }),
|
|
736
|
+
...(extra && extra.orderDesc && { orderDesc: extra.orderDesc }),
|
|
737
|
+
...q,
|
|
738
|
+
});
|
|
739
|
+
return {
|
|
740
|
+
table,
|
|
741
|
+
fields,
|
|
742
|
+
rows,
|
|
743
|
+
};
|
|
744
|
+
},
|
|
745
|
+
async tryInsertQuery(row) {
|
|
746
|
+
const table = await Table.findOne({ id: table_id });
|
|
747
|
+
const ins_res = await table.tryInsertRow(row, req.user ? +req.user.id : undefined);
|
|
748
|
+
return ins_res;
|
|
749
|
+
},
|
|
750
|
+
async tryUpdateQuery(row, id) {
|
|
751
|
+
const table = await Table.findOne({ id: table_id });
|
|
752
|
+
const upd_res = await table.tryUpdateRow(row, id, req.user ? +req.user.id : undefined);
|
|
753
|
+
return upd_res;
|
|
754
|
+
},
|
|
755
|
+
async authorizePostQuery(body, table_id /*overwrites*/) {
|
|
756
|
+
return await doAuthPost({ body, table_id, req });
|
|
757
|
+
},
|
|
758
|
+
async authorizeGetQuery(query, table_id) {
|
|
759
|
+
let body = query || {};
|
|
760
|
+
if (Object.keys(body).length == 1) {
|
|
761
|
+
const table = await Table.findOne({ id: table_id });
|
|
762
|
+
if (table.ownership_field_id || table.ownership_formula) {
|
|
763
|
+
const fields = await table.getFields();
|
|
764
|
+
const { uniques } = splitUniques(fields, body);
|
|
765
|
+
if (Object.keys(uniques).length > 0) {
|
|
766
|
+
body = await table.getRow(uniques);
|
|
767
|
+
return table.is_owner(req.user, body);
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
return doAuthPost({ body, table_id, req });
|
|
772
|
+
},
|
|
773
|
+
async getRowQuery(table_id, view_select, row_id) {
|
|
774
|
+
const childTable = Table.findOne({ id: table_id });
|
|
775
|
+
return await childTable.getRows({
|
|
776
|
+
[view_select.field_name]: row_id,
|
|
777
|
+
});
|
|
778
|
+
},
|
|
779
|
+
}),
|
|
780
|
+
configCheck: async (view) => {
|
|
781
|
+
const { name, configuration: { view_when_done, destination_type, formula_destinations }, } = view;
|
|
639
782
|
const errs = [];
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
783
|
+
if (destination_type !== "Back to referer") {
|
|
784
|
+
const vwd = await View.findOne({
|
|
785
|
+
name: (view_when_done || "").split(".")[0],
|
|
786
|
+
});
|
|
787
|
+
if (!vwd)
|
|
788
|
+
errs.push(`In View ${name}, view when done ${view_when_done} not found`);
|
|
789
|
+
for (const { expression } of formula_destinations || []) {
|
|
790
|
+
if (expression)
|
|
791
|
+
expressionChecker(expression, `In View ${name}, destination formula ${expression} error: `, errs);
|
|
792
|
+
}
|
|
648
793
|
}
|
|
794
|
+
errs.push(...(await check_view_columns(view, view.configuration.columns)));
|
|
649
795
|
return errs;
|
|
650
796
|
},
|
|
651
797
|
};
|