@saltcorn/data 0.8.6-beta.2 → 0.8.6-beta.4
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.js +1 -1
- package/dist/base-plugin/actions.js.map +1 -1
- package/dist/base-plugin/index.d.ts +5 -1
- package/dist/base-plugin/index.d.ts.map +1 -1
- package/dist/base-plugin/types.d.ts +51 -44
- package/dist/base-plugin/types.d.ts.map +1 -1
- package/dist/base-plugin/types.js +20 -12
- package/dist/base-plugin/types.js.map +1 -1
- package/dist/base-plugin/viewtemplates/edit.d.ts.map +1 -1
- package/dist/base-plugin/viewtemplates/edit.js +15 -5
- package/dist/base-plugin/viewtemplates/edit.js.map +1 -1
- package/dist/base-plugin/viewtemplates/feed.js +1 -1
- package/dist/base-plugin/viewtemplates/feed.js.map +1 -1
- package/dist/base-plugin/viewtemplates/filter.js +3 -3
- package/dist/base-plugin/viewtemplates/filter.js.map +1 -1
- package/dist/base-plugin/viewtemplates/list.js +3 -3
- package/dist/base-plugin/viewtemplates/list.js.map +1 -1
- package/dist/base-plugin/viewtemplates/room.js +2 -2
- package/dist/base-plugin/viewtemplates/room.js.map +1 -1
- package/dist/base-plugin/viewtemplates/show.d.ts.map +1 -1
- package/dist/base-plugin/viewtemplates/show.js +18 -8
- package/dist/base-plugin/viewtemplates/show.js.map +1 -1
- package/dist/base-plugin/viewtemplates/viewable_fields.d.ts +7 -4
- package/dist/base-plugin/viewtemplates/viewable_fields.d.ts.map +1 -1
- package/dist/base-plugin/viewtemplates/viewable_fields.js +113 -83
- package/dist/base-plugin/viewtemplates/viewable_fields.js.map +1 -1
- package/dist/db/fixtures.d.ts.map +1 -1
- package/dist/db/fixtures.js +422 -20
- package/dist/db/fixtures.js.map +1 -1
- package/dist/db/state.d.ts +1 -0
- package/dist/db/state.d.ts.map +1 -1
- package/dist/db/state.js +9 -2
- package/dist/db/state.js.map +1 -1
- package/dist/diagram/node_extract_utils.d.ts.map +1 -1
- package/dist/diagram/node_extract_utils.js +7 -3
- package/dist/diagram/node_extract_utils.js.map +1 -1
- package/dist/migrations/202304281224.d.ts +3 -0
- package/dist/migrations/202304281224.d.ts.map +1 -0
- package/dist/migrations/202304281224.js +117 -0
- package/dist/migrations/202304281224.js.map +1 -0
- package/dist/migrations/202305081143.d.ts +2 -0
- package/dist/migrations/202305081143.d.ts.map +1 -0
- package/dist/migrations/202305081143.js +17 -0
- package/dist/migrations/202305081143.js.map +1 -0
- package/dist/models/config.d.ts +1 -0
- package/dist/models/config.d.ts.map +1 -1
- package/dist/models/config.js +11 -4
- package/dist/models/config.js.map +1 -1
- package/dist/models/email.js +1 -1
- package/dist/models/field.d.ts.map +1 -1
- package/dist/models/field.js +21 -1
- package/dist/models/field.js.map +1 -1
- package/dist/models/file.d.ts +36 -1
- package/dist/models/file.d.ts.map +1 -1
- package/dist/models/file.js +48 -5
- package/dist/models/file.js.map +1 -1
- package/dist/models/index.d.ts +2 -1
- package/dist/models/index.d.ts.map +1 -1
- package/dist/models/layout.d.ts +1 -1
- package/dist/models/layout.d.ts.map +1 -1
- package/dist/models/layout.js +3 -1
- package/dist/models/layout.js.map +1 -1
- package/dist/models/page.js +1 -1
- package/dist/models/page.js.map +1 -1
- package/dist/models/random.js +1 -1
- package/dist/models/random.js.map +1 -1
- package/dist/models/table.d.ts +7 -1
- package/dist/models/table.d.ts.map +1 -1
- package/dist/models/table.js +22 -10
- package/dist/models/table.js.map +1 -1
- package/dist/models/user.js +1 -1
- package/dist/models/user.js.map +1 -1
- package/dist/models/view.d.ts +1 -0
- package/dist/models/view.d.ts.map +1 -1
- package/dist/models/view.js +27 -4
- package/dist/models/view.js.map +1 -1
- package/dist/models/workflow.d.ts.map +1 -1
- package/dist/models/workflow.js +5 -1
- package/dist/models/workflow.js.map +1 -1
- package/dist/plugin-helper.d.ts +27 -1
- package/dist/plugin-helper.d.ts.map +1 -1
- package/dist/plugin-helper.js +266 -15
- package/dist/plugin-helper.js.map +1 -1
- package/dist/tests/auth.test.js +12 -12
- package/dist/tests/auth.test.js.map +1 -1
- package/dist/tests/auxtest.test.js +132 -3
- package/dist/tests/auxtest.test.js.map +1 -1
- package/dist/tests/common_helpers.d.ts +8 -0
- package/dist/tests/common_helpers.d.ts.map +1 -0
- package/dist/tests/common_helpers.js +362 -0
- package/dist/tests/common_helpers.js.map +1 -0
- package/dist/tests/email.test.js +4 -4
- package/dist/tests/email.test.js.map +1 -1
- package/dist/tests/exact_views.test.js +10 -10
- package/dist/tests/exact_views.test.js.map +1 -1
- package/dist/tests/mocks.js +1 -1
- package/dist/tests/mocks.js.map +1 -1
- package/dist/tests/models.test.js +4 -4
- package/dist/tests/models.test.js.map +1 -1
- package/dist/tests/remote_query_helper.js +6 -6
- package/dist/tests/remote_query_helper.js.map +1 -1
- package/dist/tests/state.test.js +1 -1
- package/dist/tests/state.test.js.map +1 -1
- package/dist/tests/table.test.js +23 -8
- package/dist/tests/table.test.js.map +1 -1
- package/dist/tests/user.test.js +3 -3
- package/dist/tests/user.test.js.map +1 -1
- package/dist/tests/view.test.js +230 -10
- package/dist/tests/view.test.js.map +1 -1
- package/dist/utils.d.ts +17 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +32 -0
- package/dist/utils.js.map +1 -1
- package/package.json +7 -7
package/dist/plugin-helper.js
CHANGED
|
@@ -11,7 +11,7 @@ const Trigger = require("./models/trigger");
|
|
|
11
11
|
const { getState } = require("./db/state");
|
|
12
12
|
const db = require("./db");
|
|
13
13
|
const { button, a, text, i } = require("@saltcorn/markup/tags");
|
|
14
|
-
const { applyAsync, InvalidConfiguration } = require("./utils");
|
|
14
|
+
const { applyAsync, InvalidConfiguration, parseRelationPath, buildRelationPath, } = require("./utils");
|
|
15
15
|
const { jsexprToWhere, freeVariables, add_free_variables_to_joinfields, } = require("./models/expression");
|
|
16
16
|
const { traverseSync } = require("./models/layout");
|
|
17
17
|
const { isNode } = require("./utils");
|
|
@@ -82,7 +82,11 @@ const stateToQueryString = (state) => {
|
|
|
82
82
|
return "";
|
|
83
83
|
return ("?" +
|
|
84
84
|
Object.entries(state)
|
|
85
|
-
.map(([k, v]) => k === "id"
|
|
85
|
+
.map(([k, v]) => k === "id"
|
|
86
|
+
? null
|
|
87
|
+
: `${encodeURIComponent(k)}=${encodeURIComponent(k === "_inbound_relation_path_" && typeof v !== "string"
|
|
88
|
+
? queryToString(v)
|
|
89
|
+
: v)}`)
|
|
86
90
|
.filter((s) => !!s)
|
|
87
91
|
.join("&"));
|
|
88
92
|
};
|
|
@@ -233,6 +237,154 @@ const calcfldViewConfig = async (fields, isEdit, nrecurse = 2) => {
|
|
|
233
237
|
}
|
|
234
238
|
return fieldViewConfigForms;
|
|
235
239
|
};
|
|
240
|
+
/**
|
|
241
|
+
* helper for 'get_inbound_relation_opts'
|
|
242
|
+
* @param {Table} targetTbl table to check for an Inbound relation
|
|
243
|
+
* @param {Table} srcTable table of the top view
|
|
244
|
+
* @param {string[]} levelPath inbound levels already visited
|
|
245
|
+
* @param {*} tableCache helper cache so that we don't have to call Table.findOne() all the time
|
|
246
|
+
* @param {*} fieldCache helper cache so that we don't have to call Field.find() all the time
|
|
247
|
+
* @returns
|
|
248
|
+
*/
|
|
249
|
+
const get_inbound_path_suffixes = async (targetTbl, srcTable, levelPath, tableCache, fieldCache) => {
|
|
250
|
+
const result = [];
|
|
251
|
+
// fks from targetTbl
|
|
252
|
+
for (const fkToRelTbl of targetTbl.getForeignKeys()) {
|
|
253
|
+
const relTblName = fkToRelTbl.reftable_name;
|
|
254
|
+
if (relTblName === srcTable.name)
|
|
255
|
+
continue;
|
|
256
|
+
// inbounds to the target of fk
|
|
257
|
+
const inboundFks = fieldCache[relTblName]
|
|
258
|
+
? fieldCache[relTblName].filter((field) => field.table_id !== targetTbl.id &&
|
|
259
|
+
!levelPath.find((val) => val.tbl === targetTbl.name && val.fk === fkToRelTbl.name))
|
|
260
|
+
: [];
|
|
261
|
+
for (const inboundFk of inboundFks) {
|
|
262
|
+
const inboundTable = tableCache[inboundFk.table_id];
|
|
263
|
+
if (inboundTable) {
|
|
264
|
+
const relTblRefs = inboundTable
|
|
265
|
+
.getForeignKeys()
|
|
266
|
+
.filter((f) => f.reftable_name === relTblName);
|
|
267
|
+
// the inbound comes from 'srcTable'
|
|
268
|
+
if (inboundTable.id === srcTable.id) {
|
|
269
|
+
const levels = levelPath.map((val) => val.fk).join(".");
|
|
270
|
+
for (const inboundRelTblKey of relTblRefs) {
|
|
271
|
+
const newSuffix = `.${srcTable.name}.${inboundRelTblKey.name}.${targetTbl.name}$${fkToRelTbl.name}${levels ? `.${levels}` : ""}`;
|
|
272
|
+
if (result.indexOf(newSuffix) === -1) {
|
|
273
|
+
result.push(newSuffix);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
// check if there are refs to 'srcTable'
|
|
279
|
+
const srcRefs = inboundTable
|
|
280
|
+
.getForeignKeys()
|
|
281
|
+
.filter((f) => f.reftable_name === srcTable.name);
|
|
282
|
+
for (const srcTblRef of srcRefs) {
|
|
283
|
+
for (const relTblRef of relTblRefs) {
|
|
284
|
+
if (levelPath.length > 0) {
|
|
285
|
+
let levels = `${levelPath[0].tbl}$${fkToRelTbl.name}`;
|
|
286
|
+
for (let i = 0; i < levelPath.length; i++) {
|
|
287
|
+
levels = `${levels}.${levelPath[i].fk}`;
|
|
288
|
+
}
|
|
289
|
+
const newSuffix = `.${srcTable.name}.${inboundTable.name}$${srcTblRef.name}.${relTblRef.name}.` +
|
|
290
|
+
`${levels}`;
|
|
291
|
+
if (result.indexOf(newSuffix) === -1) {
|
|
292
|
+
result.push(newSuffix);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
const newSuffix = `.${srcTable.name}.${inboundTable.name}$${srcTblRef.name}.${relTblRef.name}.${targetTbl.name}$${fkToRelTbl.name}`;
|
|
297
|
+
if (result.indexOf(newSuffix) === -1) {
|
|
298
|
+
result.push(newSuffix);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return result;
|
|
308
|
+
};
|
|
309
|
+
/**
|
|
310
|
+
* search for relations where an in select to source is possible
|
|
311
|
+
* @param {Table} source
|
|
312
|
+
* @param {string} viewname
|
|
313
|
+
* @returns
|
|
314
|
+
*/
|
|
315
|
+
const get_inbound_relation_opts = async (source, viewname) => {
|
|
316
|
+
const tableCache = {};
|
|
317
|
+
for (const table of await Table.find()) {
|
|
318
|
+
tableCache[table.id] = table;
|
|
319
|
+
}
|
|
320
|
+
const fieldCache = {};
|
|
321
|
+
for (const field of await Field.find()) {
|
|
322
|
+
if (field.reftable_name) {
|
|
323
|
+
if (!fieldCache[field.reftable_name])
|
|
324
|
+
fieldCache[field.reftable_name] = [];
|
|
325
|
+
fieldCache[field.reftable_name].push(field);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
const result = [];
|
|
329
|
+
const search = async (table, path, rootTable, visited) => {
|
|
330
|
+
const visitedCopy = new Set(visited);
|
|
331
|
+
const suffixes = await get_inbound_path_suffixes(table, source, path, tableCache, fieldCache);
|
|
332
|
+
if (suffixes.length > 0) {
|
|
333
|
+
const views = await View.find_table_views_where(rootTable.id, ({ state_fields, viewrow }) => viewrow.name !== viewname &&
|
|
334
|
+
!state_fields.some((sf) => sf.name === "id"));
|
|
335
|
+
for (const suffix of suffixes) {
|
|
336
|
+
result.push({ path: suffix, views });
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
if (!visitedCopy.has(table.name)) {
|
|
340
|
+
visitedCopy.add(table.name);
|
|
341
|
+
for (const inboundFk of fieldCache[table.name] || []) {
|
|
342
|
+
if (inboundFk.table_id === table.id)
|
|
343
|
+
continue;
|
|
344
|
+
const inboundTbl = tableCache[inboundFk.table_id];
|
|
345
|
+
await search(inboundTbl, [{ tbl: inboundTbl.name, fk: inboundFk.name }, ...path], rootTable, visitedCopy);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
// search in reverse,
|
|
350
|
+
// start with the target (table of the subview) to the relation source
|
|
351
|
+
for (const table of await Table.find()) {
|
|
352
|
+
const visited = new Set();
|
|
353
|
+
await search(table, [], table, visited);
|
|
354
|
+
}
|
|
355
|
+
return result;
|
|
356
|
+
};
|
|
357
|
+
/**
|
|
358
|
+
* Get all relation options where source has a key to another table (refTable)
|
|
359
|
+
* and refTable has a key to source.
|
|
360
|
+
* Otherwise one could use a OneToOneShow from refTable.
|
|
361
|
+
* @param {Table} source
|
|
362
|
+
* @param {string} viewname name of the topview
|
|
363
|
+
* @returns viewnames mapped to arrays of Inbound options
|
|
364
|
+
*/
|
|
365
|
+
const get_inbound_self_relation_opts = async (source, viewname) => {
|
|
366
|
+
const fields = await Field.find({
|
|
367
|
+
reftable_name: source.name,
|
|
368
|
+
is_unique: true,
|
|
369
|
+
});
|
|
370
|
+
const result = [];
|
|
371
|
+
const targetFields = source.getForeignKeys();
|
|
372
|
+
for (const field of fields) {
|
|
373
|
+
const refTable = Table.findOne({ id: field.table_id });
|
|
374
|
+
const fromTargetToRef = targetFields.filter((field) => field.reftable_name === refTable.name);
|
|
375
|
+
if (fromTargetToRef.length > 0) {
|
|
376
|
+
const views = await View.find_table_views_where(source, ({ state_fields, viewrow }) => viewrow.name !== viewname &&
|
|
377
|
+
state_fields.some((sf) => sf.name === "id"));
|
|
378
|
+
for (const toRef of fromTargetToRef) {
|
|
379
|
+
result.push({
|
|
380
|
+
path: `.${source.name}.${toRef.name}.${field.name}`,
|
|
381
|
+
views,
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
return result;
|
|
387
|
+
};
|
|
236
388
|
/**
|
|
237
389
|
* @function
|
|
238
390
|
* @param {Table|object} table
|
|
@@ -250,6 +402,7 @@ const get_link_view_opts = async (table, viewname, accept = () => true) => {
|
|
|
250
402
|
const view_name_opts = all_views.filter(accept).map((v) => ({
|
|
251
403
|
label: `${v.name} [${v.viewtemplate} ${table_id_to_name[v.table_id] || ""}]`,
|
|
252
404
|
name: v.name,
|
|
405
|
+
table: table_id_to_name[v.table_id] || "",
|
|
253
406
|
}));
|
|
254
407
|
const view_relation_opts = {};
|
|
255
408
|
const link_view_opts = [];
|
|
@@ -267,15 +420,20 @@ const get_link_view_opts = async (table, viewname, accept = () => true) => {
|
|
|
267
420
|
relation: table.name,
|
|
268
421
|
});
|
|
269
422
|
});
|
|
270
|
-
const
|
|
423
|
+
const link_view_opts_push_legacy = (o) => {
|
|
271
424
|
if (!link_view_opts.map((v) => v.name).includes(o.name))
|
|
272
425
|
push_view_option(o);
|
|
273
426
|
};
|
|
427
|
+
const link_view_opts_push = (o) => {
|
|
428
|
+
if (!view_relation_opts[o.view] ||
|
|
429
|
+
!view_relation_opts[o.view].find(({ value }) => value === o.name))
|
|
430
|
+
push_view_option(o);
|
|
431
|
+
};
|
|
274
432
|
const child_views = await get_child_views(table, viewname);
|
|
275
433
|
for (const { relation, related_table, through, throughTable, views, } of child_views) {
|
|
276
434
|
for (const view of views) {
|
|
277
435
|
if (through && throughTable) {
|
|
278
|
-
|
|
436
|
+
link_view_opts_push_legacy({
|
|
279
437
|
view: view.name,
|
|
280
438
|
name: `ChildList:${view.name}.${throughTable.name}.${through.name}.${related_table.name}.${relation.name}`,
|
|
281
439
|
label: `${view.name} [${view.viewtemplate} ${related_table.name}.${relation.name}.${through.name}]`,
|
|
@@ -283,7 +441,7 @@ const get_link_view_opts = async (table, viewname, accept = () => true) => {
|
|
|
283
441
|
});
|
|
284
442
|
}
|
|
285
443
|
else {
|
|
286
|
-
|
|
444
|
+
link_view_opts_push_legacy({
|
|
287
445
|
view: view.name,
|
|
288
446
|
name: `ChildList:${view.name}.${related_table.name}.${relation.name}`,
|
|
289
447
|
label: `${view.name} [${view.viewtemplate} ${related_table.name}.${relation.name}]`,
|
|
@@ -295,7 +453,7 @@ const get_link_view_opts = async (table, viewname, accept = () => true) => {
|
|
|
295
453
|
const parent_views = await get_parent_views(table, viewname);
|
|
296
454
|
for (const { relation, related_table, views } of parent_views) {
|
|
297
455
|
for (const view of views) {
|
|
298
|
-
|
|
456
|
+
link_view_opts_push_legacy({
|
|
299
457
|
view: view.name,
|
|
300
458
|
name: `ParentShow:${view.name}.${related_table.name}.${relation.name}`,
|
|
301
459
|
label: `${view.name} [${view.viewtemplate} ${relation.name}.${related_table.name}]`,
|
|
@@ -306,7 +464,7 @@ const get_link_view_opts = async (table, viewname, accept = () => true) => {
|
|
|
306
464
|
const onetoone_views = await get_onetoone_views(table, viewname);
|
|
307
465
|
for (const { relation, related_table, views } of onetoone_views) {
|
|
308
466
|
for (const view of views) {
|
|
309
|
-
|
|
467
|
+
link_view_opts_push_legacy({
|
|
310
468
|
view: view.name,
|
|
311
469
|
name: `OneToOneShow:${view.name}.${related_table.name}.${relation.name}`,
|
|
312
470
|
label: `${view.name} [${view.viewtemplate} ${related_table.name}.${relation.label}]`,
|
|
@@ -316,13 +474,35 @@ const get_link_view_opts = async (table, viewname, accept = () => true) => {
|
|
|
316
474
|
}
|
|
317
475
|
const independent_views = await View.find_all_views_where(({ state_fields }) => !state_fields.some((sf) => sf.required));
|
|
318
476
|
independent_views.forEach((view) => {
|
|
319
|
-
|
|
477
|
+
link_view_opts_push_legacy({
|
|
320
478
|
view: view.name,
|
|
321
479
|
label: `${view.name} [${view.viewtemplate}]`,
|
|
322
480
|
name: `Independent:${view.name}`,
|
|
323
481
|
relation: "None",
|
|
324
482
|
});
|
|
325
483
|
});
|
|
484
|
+
const inbound_rel_opts = await get_inbound_relation_opts(table, viewname);
|
|
485
|
+
for (const { path, views } of inbound_rel_opts) {
|
|
486
|
+
for (const view of views) {
|
|
487
|
+
link_view_opts_push({
|
|
488
|
+
view: view.name,
|
|
489
|
+
label: `${view.name} [${view.viewtemplate} ${table.name}]`,
|
|
490
|
+
name: path,
|
|
491
|
+
relation: path,
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
const self_inbounds = await get_inbound_self_relation_opts(table, viewname);
|
|
496
|
+
for (const { path, views } of self_inbounds) {
|
|
497
|
+
for (const view of views) {
|
|
498
|
+
link_view_opts_push({
|
|
499
|
+
view: view.name,
|
|
500
|
+
label: `${view.name} [${view.viewtemplate} ${table.name}]`,
|
|
501
|
+
name: path,
|
|
502
|
+
relation: path,
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
}
|
|
326
506
|
return { link_view_opts, view_name_opts, view_relation_opts };
|
|
327
507
|
};
|
|
328
508
|
/**
|
|
@@ -1168,16 +1348,36 @@ const stateFieldsToQuery = ({ state, stateHash, fields, prefix = "" }) => {
|
|
|
1168
1348
|
*/
|
|
1169
1349
|
// todo potentially move to utils
|
|
1170
1350
|
const addOrCreateList = (container, key, x) => {
|
|
1171
|
-
if (container[key])
|
|
1172
|
-
container[key].
|
|
1351
|
+
if (container[key]) {
|
|
1352
|
+
if (container[key].length)
|
|
1353
|
+
container[key].push(x);
|
|
1354
|
+
else
|
|
1355
|
+
container[key] = [container[key], x];
|
|
1356
|
+
}
|
|
1173
1357
|
else
|
|
1174
1358
|
container[key] = [x];
|
|
1175
1359
|
};
|
|
1360
|
+
const stringToQuery = (s) => {
|
|
1361
|
+
const json = JSON.parse(s);
|
|
1362
|
+
const { path, sourcetable } = parseRelationPath(json.relation);
|
|
1363
|
+
return {
|
|
1364
|
+
...json,
|
|
1365
|
+
path,
|
|
1366
|
+
sourcetable,
|
|
1367
|
+
};
|
|
1368
|
+
};
|
|
1369
|
+
const queryToString = (query) => {
|
|
1370
|
+
const relObj = {
|
|
1371
|
+
srcId: query.srcId,
|
|
1372
|
+
relation: buildRelationPath(query.sourcetable, query.path),
|
|
1373
|
+
};
|
|
1374
|
+
return JSON.stringify(relObj);
|
|
1375
|
+
};
|
|
1176
1376
|
/**
|
|
1177
1377
|
* @function
|
|
1178
1378
|
* @param {object} opts
|
|
1179
1379
|
* @param {Field[]} opts.fields
|
|
1180
|
-
* @param {object} opts.state
|
|
1380
|
+
* @param {object} opts.state
|
|
1181
1381
|
* @param {boolean} [opts.approximate = true]
|
|
1182
1382
|
* @param {Table} opts.table
|
|
1183
1383
|
* @returns {object}
|
|
@@ -1185,7 +1385,7 @@ const addOrCreateList = (container, key, x) => {
|
|
|
1185
1385
|
const stateFieldsToWhere = ({ fields, state, approximate = true, table }) => {
|
|
1186
1386
|
let qstate = {};
|
|
1187
1387
|
Object.entries(state || {}).forEach(([k, v]) => {
|
|
1188
|
-
if (k === "_fts" || (table?.name && k === `_fts_${table.
|
|
1388
|
+
if (k === "_fts" || (table?.name && k === `_fts_${table.santized_name}`)) {
|
|
1189
1389
|
qstate["_fts"] = {
|
|
1190
1390
|
searchTerm: v.replace(/\0/g, ""),
|
|
1191
1391
|
fields,
|
|
@@ -1194,7 +1394,35 @@ const stateFieldsToWhere = ({ fields, state, approximate = true, table }) => {
|
|
|
1194
1394
|
return;
|
|
1195
1395
|
}
|
|
1196
1396
|
const field = fields.find((fld) => fld.name === k);
|
|
1197
|
-
if (k
|
|
1397
|
+
if (k === "_inbound_relation_path_") {
|
|
1398
|
+
const queryObj = typeof v === "string" ? stringToQuery(v) : v;
|
|
1399
|
+
const levels = [];
|
|
1400
|
+
let lastTableName = queryObj.sourcetable;
|
|
1401
|
+
let where = null;
|
|
1402
|
+
for (const level of queryObj.path) {
|
|
1403
|
+
if (level.inboundKey) {
|
|
1404
|
+
levels.push({ ...level });
|
|
1405
|
+
lastTableName = level.table;
|
|
1406
|
+
if (!where)
|
|
1407
|
+
where = { [db.sqlsanitize(level.inboundKey)]: queryObj.srcId };
|
|
1408
|
+
}
|
|
1409
|
+
else {
|
|
1410
|
+
const lastTable = Table.findOne({ name: lastTableName });
|
|
1411
|
+
const refField = lastTable.fields.find((field) => field.name === level.fkey);
|
|
1412
|
+
levels.push({ table: refField.reftable_name, fkey: level.fkey });
|
|
1413
|
+
lastTableName = refField.reftable_name;
|
|
1414
|
+
if (!where)
|
|
1415
|
+
where = { id: queryObj.srcId };
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
addOrCreateList(qstate, "id", {
|
|
1419
|
+
inSelectWithLevels: {
|
|
1420
|
+
joinLevels: levels,
|
|
1421
|
+
where,
|
|
1422
|
+
},
|
|
1423
|
+
});
|
|
1424
|
+
}
|
|
1425
|
+
else if (k.startsWith("_fromdate_")) {
|
|
1198
1426
|
const datefield = db.sqlsanitize(k.replace("_fromdate_", ""));
|
|
1199
1427
|
const dfield = fields.find((fld) => fld.name === datefield);
|
|
1200
1428
|
if (dfield)
|
|
@@ -1221,6 +1449,9 @@ const stateFieldsToWhere = ({ fields, state, approximate = true, table }) => {
|
|
|
1221
1449
|
else if (field && field.type.name === "String" && v && v.slugify) {
|
|
1222
1450
|
qstate[k] = v;
|
|
1223
1451
|
}
|
|
1452
|
+
else if (Array.isArray(v) && field && field.type && field.type.read) {
|
|
1453
|
+
qstate[k] = { or: v.map(field.type.read) };
|
|
1454
|
+
}
|
|
1224
1455
|
else if (field &&
|
|
1225
1456
|
field.type.name === "String" &&
|
|
1226
1457
|
!(field.attributes && field.attributes.options) &&
|
|
@@ -1456,7 +1687,7 @@ const initial_config_all_fields = (isEdit) => async ({ table_id, exttable_name }
|
|
|
1456
1687
|
aboves.push({
|
|
1457
1688
|
type: "action",
|
|
1458
1689
|
block: false,
|
|
1459
|
-
minRole:
|
|
1690
|
+
minRole: 100,
|
|
1460
1691
|
action_name: "Save",
|
|
1461
1692
|
});
|
|
1462
1693
|
cfg.layout = { above: aboves };
|
|
@@ -1603,6 +1834,9 @@ const json_list_to_external_table = (get_json_list, fields0) => {
|
|
|
1603
1834
|
getFields() {
|
|
1604
1835
|
return fields;
|
|
1605
1836
|
},
|
|
1837
|
+
getForeignKeys() {
|
|
1838
|
+
return fields.filter((f) => f.is_fkey && f.type !== "File");
|
|
1839
|
+
},
|
|
1606
1840
|
getField(fnm) {
|
|
1607
1841
|
return fields.find((f) => f.name === fnm);
|
|
1608
1842
|
},
|
|
@@ -1610,7 +1844,7 @@ const json_list_to_external_table = (get_json_list, fields0) => {
|
|
|
1610
1844
|
getRows,
|
|
1611
1845
|
get min_role_read() {
|
|
1612
1846
|
const roles = getState().getConfig("exttables_min_role_read", {});
|
|
1613
|
-
return roles[tbl.name] ||
|
|
1847
|
+
return roles[tbl.name] || 100;
|
|
1614
1848
|
},
|
|
1615
1849
|
getJoinedRows(opts = {}) {
|
|
1616
1850
|
const { where, ...rest } = opts;
|
|
@@ -1677,6 +1911,20 @@ const run_action_column = async ({ col, req, ...rest }) => {
|
|
|
1677
1911
|
...rest,
|
|
1678
1912
|
});
|
|
1679
1913
|
};
|
|
1914
|
+
/**
|
|
1915
|
+
* for all tables collect the foreign keys with the targets
|
|
1916
|
+
* should only be used as options for the saltcorn-builder
|
|
1917
|
+
* @returns table names as key and the fks as value
|
|
1918
|
+
*/
|
|
1919
|
+
const build_schema_fk_options = async () => {
|
|
1920
|
+
const result = {};
|
|
1921
|
+
for (const table of await Table.find()) {
|
|
1922
|
+
result[table.name] = table.getForeignKeys().map((field) => {
|
|
1923
|
+
return { name: field.name, reftable_name: field.reftable_name };
|
|
1924
|
+
});
|
|
1925
|
+
}
|
|
1926
|
+
return result;
|
|
1927
|
+
};
|
|
1680
1928
|
module.exports = {
|
|
1681
1929
|
field_picker_fields,
|
|
1682
1930
|
picked_fields_to_query,
|
|
@@ -1698,5 +1946,8 @@ module.exports = {
|
|
|
1698
1946
|
run_action_column,
|
|
1699
1947
|
json_list_to_external_table,
|
|
1700
1948
|
add_free_variables_to_joinfields,
|
|
1949
|
+
get_inbound_relation_opts,
|
|
1950
|
+
get_inbound_self_relation_opts,
|
|
1951
|
+
build_schema_fk_options,
|
|
1701
1952
|
};
|
|
1702
1953
|
//# sourceMappingURL=plugin-helper.js.map
|