@saltcorn/data 1.4.2 → 1.4.3
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/mobile-mocks/npm/apns2.d.ts +1 -0
- package/dist/mobile-mocks/npm/apns2.d.ts.map +1 -0
- package/dist/mobile-mocks/npm/apns2.js +2 -0
- package/dist/mobile-mocks/npm/apns2.js.map +1 -0
- package/dist/mobile-mocks/npm/vm2.d.ts +1 -0
- package/dist/mobile-mocks/npm/vm2.d.ts.map +1 -0
- package/dist/mobile-mocks/npm/vm2.js +2 -0
- package/dist/mobile-mocks/npm/vm2.js.map +1 -0
- package/dist/mobile-mocks/npm/xml2js.d.ts +1 -0
- package/dist/mobile-mocks/npm/xml2js.d.ts.map +1 -0
- package/dist/mobile-mocks/npm/xml2js.js +2 -0
- package/dist/mobile-mocks/npm/xml2js.js.map +1 -0
- package/dist/viewable_fields.d.ts +151 -96
- package/dist/viewable_fields.d.ts.map +1 -1
- package/dist/viewable_fields.js +452 -91
- package/dist/viewable_fields.js.map +1 -1
- package/package.json +8 -8
- package/dist/models/s3_helpers.d.ts +0 -54
- package/dist/models/s3_helpers.d.ts.map +0 -1
- package/dist/models/s3_helpers.js +0 -505
- package/dist/models/s3_helpers.js.map +0 -1
- package/dist/test-utils/mocks.d.ts +0 -203
- package/dist/test-utils/mocks.d.ts.map +0 -1
- package/dist/test-utils/mocks.js +0 -329
- package/dist/test-utils/mocks.js.map +0 -1
- package/dist/tests/mail_queue.test.d.ts +0 -2
- package/dist/tests/mail_queue.test.d.ts.map +0 -1
- package/dist/tests/mail_queue.test.js +0 -122
- package/dist/tests/mail_queue.test.js.map +0 -1
- package/dist/tests/table_sync_info.test.d.ts +0 -2
- package/dist/tests/table_sync_info.test.d.ts.map +0 -1
- package/dist/tests/table_sync_info.test.js +0 -62
- package/dist/tests/table_sync_info.test.js.map +0 -1
package/dist/viewable_fields.js
CHANGED
|
@@ -1,21 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.updateViewSelect = exports.transformForm = exports.setDateLocales = exports.standardLayoutRowVisitor = exports.standardBlockDispatch = exports.edit_build_in_actions = exports.make_link = exports.get_view_link_query = exports.fill_presets = exports.getForm = exports.splitUniques = exports.parse_view_select = exports.view_linker = exports.action_link = exports.objToQueryString = exports.action_url = exports.get_viewable_fields_from_layout = exports.get_viewable_fields = void 0;
|
|
2
7
|
/**
|
|
3
8
|
* @category saltcorn-data
|
|
4
9
|
* @module base-plugin/viewtemplates/viewable_fields
|
|
5
10
|
* @subcategory base-plugin
|
|
6
11
|
*/
|
|
12
|
+
const table_1 = __importDefault(require("./models/table"));
|
|
13
|
+
const field_1 = __importDefault(require("./models/field"));
|
|
14
|
+
const view_1 = __importDefault(require("./models/view"));
|
|
7
15
|
const { post_btn } = require("@saltcorn/markup");
|
|
8
16
|
const { text, a, i, div, button, span, script, domReady, input, } = require("@saltcorn/markup/tags");
|
|
9
17
|
const { getState, getReq__ } = require("./db/state");
|
|
10
|
-
const
|
|
18
|
+
const plugin_helper_1 = require("./plugin-helper");
|
|
11
19
|
const { eval_expression, freeVariables, get_expression_function, } = require("./models/expression");
|
|
12
|
-
const
|
|
20
|
+
const FieldRepeat = require("./models/fieldrepeat");
|
|
13
21
|
const Form = require("./models/form");
|
|
14
|
-
const { traverseSync } = require("./models/layout");
|
|
15
|
-
const { structuredClone, isWeb, isOfflineMode, getSessionId, interpolate, objectToQueryString, validSqlId, } = require("./utils");
|
|
22
|
+
const { traverseSync, traverse, translateLayout } = require("./models/layout");
|
|
23
|
+
const { structuredClone, isWeb, isOfflineMode, getSessionId, interpolate, objectToQueryString, validSqlId, InvalidConfiguration, renderServerSide, } = require("./utils");
|
|
16
24
|
const db = require("./db");
|
|
17
|
-
const View = require("./models/view");
|
|
18
|
-
const Table = require("./models/table");
|
|
19
25
|
const { isNode, dollarizeObject, getSafeBaseUrl } = require("./utils");
|
|
20
26
|
const { bool, date } = require("./base-plugin/types");
|
|
21
27
|
const _ = require("underscore");
|
|
@@ -63,6 +69,7 @@ const action_url = (viewname, table, action_name, r, colId, colIdNm, confirm, co
|
|
|
63
69
|
javascript: `${confirmStr}view_post('${viewname}', 'run_action', {${colIdNm}:'${colId}'${r ? `, ${pk_name}:'${r?.[pk_name]}'` : ""}${columnIndex(colIndex)}}${runAsync ? `,{runAsync:true}` : ""});`,
|
|
64
70
|
};
|
|
65
71
|
};
|
|
72
|
+
exports.action_url = action_url;
|
|
66
73
|
/**
|
|
67
74
|
* @param {string} url
|
|
68
75
|
* @param {object} req
|
|
@@ -81,11 +88,11 @@ const action_url = (viewname, table, action_name, r, colId, colIdNm, confirm, co
|
|
|
81
88
|
* @returns {object}
|
|
82
89
|
*/
|
|
83
90
|
const action_link = (url, req, { action_name, action_label, confirm, rndid, action_style, action_size, action_icon, action_bgcol, action_title, action_class, action_bordercol, action_textcol, spinner, block, }, __ = (s) => s) => {
|
|
84
|
-
const label = action_label === " " ? "" : __(action_label) || action_name;
|
|
91
|
+
const label = action_label === " " ? "" : __(action_label || "") || action_name;
|
|
85
92
|
let style = action_style === "btn-custom-color"
|
|
86
93
|
? `background-color: ${action_bgcol || "#000000"};border-color: ${action_bordercol || "#000000"}; color: ${action_textcol || "#000000"}`
|
|
87
94
|
: null;
|
|
88
|
-
if (url.javascript)
|
|
95
|
+
if (typeof url !== "string" && url.javascript)
|
|
89
96
|
return a({
|
|
90
97
|
href: "javascript:void(0)",
|
|
91
98
|
onclick: `${spinner ? "spin_action_link(this);" : ""}${url.javascript}`,
|
|
@@ -111,6 +118,7 @@ const action_link = (url, req, { action_name, action_label, confirm, rndid, acti
|
|
|
111
118
|
formClass: !block && "d-inline",
|
|
112
119
|
});
|
|
113
120
|
};
|
|
121
|
+
exports.action_link = action_link;
|
|
114
122
|
const slug_transform = (row) => (step) => step.transform === "slugify"
|
|
115
123
|
? `/${db.slugify(row[step.field])}`
|
|
116
124
|
: `/${row[step.field]}`;
|
|
@@ -126,6 +134,7 @@ const get_view_link_query = (fields, view) => {
|
|
|
126
134
|
const pk_name = fields.find((f) => f.primary_key).name;
|
|
127
135
|
return (r) => `?${pk_name}=${r[pk_name]}`;
|
|
128
136
|
};
|
|
137
|
+
exports.get_view_link_query = get_view_link_query;
|
|
129
138
|
/**
|
|
130
139
|
* @function
|
|
131
140
|
* @param {object} opts
|
|
@@ -137,7 +146,7 @@ const get_view_link_query = (fields, view) => {
|
|
|
137
146
|
* @param {Field[]} fields
|
|
138
147
|
* @returns {object}
|
|
139
148
|
*/
|
|
140
|
-
const make_link = ({ link_text, link_text_formula, link_url, link_url_formula, link_target_blank, in_dropdown, in_modal, link_icon, icon, link_style, link_size, }, fields, __ = (s) => s, in_row_click) => {
|
|
149
|
+
const make_link = ({ link_text, link_text_formula, link_url, link_url_formula, link_target_blank, in_dropdown, in_modal, link_icon, icon, link_style, link_size, link_title, }, fields, __ = (s) => s, in_row_click) => {
|
|
141
150
|
return {
|
|
142
151
|
label: "",
|
|
143
152
|
key: (r) => {
|
|
@@ -164,6 +173,8 @@ const make_link = ({ link_text, link_text_formula, link_url, link_url_formula, l
|
|
|
164
173
|
attrs.class = [...(attrs.class || []), link_size];
|
|
165
174
|
if (in_row_click)
|
|
166
175
|
attrs.onclick = "event.stopPropagation()";
|
|
176
|
+
if (link_title)
|
|
177
|
+
attrs.title = link_title;
|
|
167
178
|
if (in_modal)
|
|
168
179
|
return a({
|
|
169
180
|
...attrs,
|
|
@@ -176,6 +187,7 @@ const make_link = ({ link_text, link_text_formula, link_url, link_url_formula, l
|
|
|
176
187
|
},
|
|
177
188
|
};
|
|
178
189
|
};
|
|
190
|
+
exports.make_link = make_link;
|
|
179
191
|
/**
|
|
180
192
|
* @param {string} view name of the view or a legacy relation (type:telation)
|
|
181
193
|
* @param {string} relation new relation path syntax
|
|
@@ -221,6 +233,7 @@ const parse_view_select = (view, relation) => {
|
|
|
221
233
|
}
|
|
222
234
|
}
|
|
223
235
|
};
|
|
236
|
+
exports.parse_view_select = parse_view_select;
|
|
224
237
|
const pathToQuery = (relation, srcTable, subTable, row) => {
|
|
225
238
|
const path = relation.path;
|
|
226
239
|
switch (relation.type) {
|
|
@@ -251,6 +264,7 @@ const pathToQuery = (relation, srcTable, subTable, row) => {
|
|
|
251
264
|
: row[idName]?.id || row[idName];
|
|
252
265
|
return `?${relation.relationString}=${srcId}`;
|
|
253
266
|
}
|
|
267
|
+
return null;
|
|
254
268
|
};
|
|
255
269
|
//todo: use above to simplify code
|
|
256
270
|
/**
|
|
@@ -297,10 +311,10 @@ in_row_click) => {
|
|
|
297
311
|
.join("&");
|
|
298
312
|
};
|
|
299
313
|
if (relation) {
|
|
300
|
-
const topview =
|
|
301
|
-
const srcTable =
|
|
302
|
-
const subview =
|
|
303
|
-
const subTable =
|
|
314
|
+
const topview = view_1.default.findOne({ name: srcViewName });
|
|
315
|
+
const srcTable = table_1.default.findOne({ id: topview.table_id });
|
|
316
|
+
const subview = view_1.default.findOne({ name: view });
|
|
317
|
+
const subTable = table_1.default.findOne({ id: subview.table_id });
|
|
304
318
|
const relObj = new Relation(relation, subTable ? subTable.name : "", ViewDisplayType.NO_ROW_LIMIT);
|
|
305
319
|
relObj.subView = subview;
|
|
306
320
|
const type = relObj.type;
|
|
@@ -319,7 +333,7 @@ in_row_click) => {
|
|
|
319
333
|
else
|
|
320
334
|
label = get_label(view, r);
|
|
321
335
|
const target = `${safePrefix}/view/${encodeURIComponent(view)}${query}`;
|
|
322
|
-
return link_view(isWeb || in_modal ? target : `javascript:execLink('${target}')`, label, in_modal && srcViewName && { reload_view: srcViewName }, link_style, link_size, link_icon || icon, textStyle, link_bgcol, link_bordercol, link_textcol, in_dropdown && "dropdown-item", get_extra_state(r), link_target_blank, label_attr, link_title, link_class, req, in_row_click);
|
|
336
|
+
return (0, plugin_helper_1.link_view)(isWeb || in_modal ? target : `javascript:execLink('${target}')`, label, in_modal && srcViewName && { reload_view: srcViewName }, link_style, link_size, link_icon || icon, textStyle, link_bgcol, link_bordercol, link_textcol, in_dropdown && "dropdown-item", get_extra_state(r), link_target_blank, label_attr, link_title, link_class, req, in_row_click);
|
|
323
337
|
}
|
|
324
338
|
},
|
|
325
339
|
};
|
|
@@ -330,13 +344,13 @@ in_row_click) => {
|
|
|
330
344
|
switch (vtype) {
|
|
331
345
|
case "Own":
|
|
332
346
|
const vnm = vrest;
|
|
333
|
-
const viewrow =
|
|
347
|
+
const viewrow = view_1.default.findOne({ name: vnm });
|
|
334
348
|
const get_query = get_view_link_query(fields, viewrow || {});
|
|
335
349
|
return {
|
|
336
350
|
label: vnm,
|
|
337
351
|
key: (r) => {
|
|
338
352
|
const target = `${safePrefix}/view/${encodeURIComponent(vnm)}${get_query(r)}`;
|
|
339
|
-
return link_view(isWeb || in_modal ? target : `javascript:execLink('${target}')`, get_label(vnm, r), in_modal && srcViewName && { reload_view: srcViewName }, link_style, link_size, link_icon || icon, textStyle, link_bgcol, link_bordercol, link_textcol, in_dropdown && "dropdown-item", get_extra_state(r), link_target_blank, label_attr, link_title, link_class, req, in_row_click);
|
|
353
|
+
return (0, plugin_helper_1.link_view)(isWeb || in_modal ? target : `javascript:execLink('${target}')`, get_label(vnm, r), in_modal && srcViewName && { reload_view: srcViewName }, link_style, link_size, link_icon || icon, textStyle, link_bgcol, link_bordercol, link_textcol, in_dropdown && "dropdown-item", get_extra_state(r), link_target_blank, label_attr, link_title, link_class, req, in_row_click);
|
|
340
354
|
},
|
|
341
355
|
};
|
|
342
356
|
case "Independent":
|
|
@@ -345,7 +359,7 @@ in_row_click) => {
|
|
|
345
359
|
label: ivnm,
|
|
346
360
|
key: (r) => {
|
|
347
361
|
const target = `${safePrefix}/view/${encodeURIComponent(ivnm)}`;
|
|
348
|
-
return link_view(isWeb || in_modal ? target : `javascript:execLink('${target}')`, get_label(ivnm, r), in_modal && srcViewName && { reload_view: srcViewName }, link_style, link_size, link_icon || icon, textStyle, link_bgcol, link_bordercol, link_textcol, in_dropdown && "dropdown-item", get_extra_state(r), link_target_blank, label_attr, link_title, link_class, req, in_row_click);
|
|
362
|
+
return (0, plugin_helper_1.link_view)(isWeb || in_modal ? target : `javascript:execLink('${target}')`, get_label(ivnm, r), in_modal && srcViewName && { reload_view: srcViewName }, link_style, link_size, link_icon || icon, textStyle, link_bgcol, link_bordercol, link_textcol, in_dropdown && "dropdown-item", get_extra_state(r), link_target_blank, label_attr, link_title, link_class, req, in_row_click);
|
|
349
363
|
},
|
|
350
364
|
};
|
|
351
365
|
case "ChildList":
|
|
@@ -356,7 +370,7 @@ in_row_click) => {
|
|
|
356
370
|
label: viewnm,
|
|
357
371
|
key: (r) => {
|
|
358
372
|
const target = `${safePrefix}/view/${encodeURIComponent(viewnm)}?${varPath}=${r.id}`;
|
|
359
|
-
return link_view(isWeb || in_modal ? target : `javascript:execLink('${target}')`, get_label(viewnm, r), in_modal && srcViewName && { reload_view: srcViewName }, link_style, link_size, link_icon || icon, textStyle, link_bgcol, link_bordercol, link_textcol, in_dropdown && "dropdown-item", get_extra_state(r), link_target_blank, label_attr, link_title, link_class, req, in_row_click);
|
|
373
|
+
return (0, plugin_helper_1.link_view)(isWeb || in_modal ? target : `javascript:execLink('${target}')`, get_label(viewnm, r), in_modal && srcViewName && { reload_view: srcViewName }, link_style, link_size, link_icon || icon, textStyle, link_bgcol, link_bordercol, link_textcol, in_dropdown && "dropdown-item", get_extra_state(r), link_target_blank, label_attr, link_title, link_class, req, in_row_click);
|
|
360
374
|
},
|
|
361
375
|
};
|
|
362
376
|
case "ParentShow":
|
|
@@ -369,7 +383,7 @@ in_row_click) => {
|
|
|
369
383
|
const summary_field = r[`summary_field_${ptbl.toLowerCase()}`];
|
|
370
384
|
if (r[pfld]) {
|
|
371
385
|
const target = `${safePrefix}/view/${encodeURIComponent(pviewnm)}?${reffield.refname}=${typeof r[pfld] === "object" ? r[pfld].id : r[pfld]}`;
|
|
372
|
-
return link_view(isWeb || in_modal ? target : `javascript:execLink('${target}')`, get_label(typeof summary_field === "undefined"
|
|
386
|
+
return (0, plugin_helper_1.link_view)(isWeb || in_modal ? target : `javascript:execLink('${target}')`, get_label(typeof summary_field === "undefined"
|
|
373
387
|
? pviewnm
|
|
374
388
|
: summary_field, r), in_modal && srcViewName && { reload_view: srcViewName }, link_style, link_size, link_icon || icon, textStyle, link_bgcol, link_bordercol, link_textcol, in_dropdown && "dropdown-item", get_extra_state(r), link_target_blank, label_attr, link_title, link_class, req, in_row_click);
|
|
375
389
|
}
|
|
@@ -382,6 +396,7 @@ in_row_click) => {
|
|
|
382
396
|
}
|
|
383
397
|
}
|
|
384
398
|
};
|
|
399
|
+
exports.view_linker = view_linker;
|
|
385
400
|
/**
|
|
386
401
|
* @param {string} nm
|
|
387
402
|
* @returns {boolean}
|
|
@@ -407,7 +422,7 @@ const flapMapish = (xs, f) => {
|
|
|
407
422
|
}
|
|
408
423
|
return res;
|
|
409
424
|
};
|
|
410
|
-
const get_viewable_fields_from_layout = (viewname, statehash, table, fields, columns, isShow, req, __, state = {}, srcViewName, layoutCols, viewResults, in_row_click) => {
|
|
425
|
+
const get_viewable_fields_from_layout = (viewname, statehash, table, fields, columns, isShow, req, __, state = {}, srcViewName, layoutCols, viewResults, in_row_click, disable_join_agg_sort) => {
|
|
411
426
|
const typeMap = {
|
|
412
427
|
field: "Field",
|
|
413
428
|
join_field: "JoinField",
|
|
@@ -422,7 +437,7 @@ const get_viewable_fields_from_layout = (viewname, statehash, table, fields, col
|
|
|
422
437
|
};
|
|
423
438
|
const toArray = (x) => !x ? [] : Array.isArray(x) ? x : x.above ? x.above : [x];
|
|
424
439
|
//console.log("layout cols", layoutCols);
|
|
425
|
-
const newCols = layoutCols.map(({ contents, ...rest }) => {
|
|
440
|
+
const newCols = (layoutCols || []).map(({ contents, ...rest }) => {
|
|
426
441
|
if (!contents)
|
|
427
442
|
contents = rest;
|
|
428
443
|
if (contents.above) {
|
|
@@ -463,8 +478,9 @@ const get_viewable_fields_from_layout = (viewname, statehash, table, fields, col
|
|
|
463
478
|
return col;
|
|
464
479
|
});
|
|
465
480
|
//console.log("newCols", newCols);
|
|
466
|
-
return get_viewable_fields(viewname, statehash, table, fields, newCols, isShow, req, __, state, srcViewName, viewResults, in_row_click);
|
|
481
|
+
return get_viewable_fields(viewname, statehash, table, fields, newCols, isShow, req, __, state, srcViewName, viewResults, in_row_click, disable_join_agg_sort);
|
|
467
482
|
};
|
|
483
|
+
exports.get_viewable_fields_from_layout = get_viewable_fields_from_layout;
|
|
468
484
|
/**
|
|
469
485
|
* @function
|
|
470
486
|
* @param {string} viewname
|
|
@@ -476,7 +492,7 @@ const get_viewable_fields_from_layout = (viewname, statehash, table, fields, col
|
|
|
476
492
|
* @param {*} __
|
|
477
493
|
* @returns {object[]}
|
|
478
494
|
*/
|
|
479
|
-
const get_viewable_fields = (viewname, statehash, table, fields, columns, isShow, req, __, state = {}, srcViewName, viewResults, in_row_click) => {
|
|
495
|
+
const get_viewable_fields = (viewname, statehash, table, fields, columns, isShow, req, __, state = {}, srcViewName, viewResults, in_row_click, disable_join_agg_sort) => {
|
|
480
496
|
const dropdown_actions = [];
|
|
481
497
|
const checkShowIf = (tFieldGenF) => (column, index) => {
|
|
482
498
|
const tfield = tFieldGenF(column, index);
|
|
@@ -531,7 +547,7 @@ const get_viewable_fields = (viewname, statehash, table, fields, columns, isShow
|
|
|
531
547
|
blockDispatch: {
|
|
532
548
|
...standardBlockDispatch(viewname, state, table, { req }, r),
|
|
533
549
|
view(column) {
|
|
534
|
-
return viewResults[column.view + column.relation]?.(r);
|
|
550
|
+
return viewResults?.[column.view + column.relation]?.(r);
|
|
535
551
|
},
|
|
536
552
|
},
|
|
537
553
|
layout,
|
|
@@ -595,7 +611,7 @@ const get_viewable_fields = (viewname, statehash, table, fields, columns, isShow
|
|
|
595
611
|
? eval_expression(column.action_label, r, req.user, "Action label formula")
|
|
596
612
|
: __(column.action_label) || __(column.action_name);
|
|
597
613
|
const icon = column.action_icon || column.icon || undefined;
|
|
598
|
-
if (url.javascript)
|
|
614
|
+
if (typeof url !== "string" && url.javascript)
|
|
599
615
|
return a({
|
|
600
616
|
href: "javascript:void(0)",
|
|
601
617
|
class: [
|
|
@@ -638,7 +654,7 @@ const get_viewable_fields = (viewname, statehash, table, fields, columns, isShow
|
|
|
638
654
|
else if (column.type === "View") {
|
|
639
655
|
return {
|
|
640
656
|
label: column.header_label ? __(column.header_label) : "",
|
|
641
|
-
key: (r) => viewResults[column.view + column.relation]?.(r),
|
|
657
|
+
key: (r) => viewResults?.[column.view + column.relation]?.(r),
|
|
642
658
|
};
|
|
643
659
|
}
|
|
644
660
|
else if (column.type === "ViewLink") {
|
|
@@ -710,7 +726,8 @@ const get_viewable_fields = (viewname, statehash, table, fields, columns, isShow
|
|
|
710
726
|
else {
|
|
711
727
|
if (field && field.type === "File")
|
|
712
728
|
column.field_type = "File";
|
|
713
|
-
else if (field?.type
|
|
729
|
+
else if (field?.type?.name &&
|
|
730
|
+
field?.type?.fieldviews?.[fieldview]) {
|
|
714
731
|
column.field_type = field.type.name;
|
|
715
732
|
type = getState().types[column.field_type];
|
|
716
733
|
}
|
|
@@ -725,7 +742,7 @@ const get_viewable_fields = (viewname, statehash, table, fields, columns, isShow
|
|
|
725
742
|
let statekey;
|
|
726
743
|
if (!column.join_field.includes("->") && keypath.length == 2) {
|
|
727
744
|
statekey = `${refNm}.${table.getField(refNm).reftable_name}->${targetNm}`;
|
|
728
|
-
header_filter = headerFilterForField(field, state, statekey);
|
|
745
|
+
header_filter = headerFilterForField(field || null, state, statekey);
|
|
729
746
|
}
|
|
730
747
|
let gofv = fieldview && type && type.fieldviews && type.fieldviews[fieldview]
|
|
731
748
|
? (row) => type.fieldviews[fieldview].run(row[key], req, {
|
|
@@ -752,11 +769,15 @@ const get_viewable_fields = (viewname, statehash, table, fields, columns, isShow
|
|
|
752
769
|
statekey,
|
|
753
770
|
header_filter,
|
|
754
771
|
key: gofv ? gofv : (row) => text(row[key]),
|
|
755
|
-
sortlink:
|
|
772
|
+
sortlink: disable_join_agg_sort
|
|
773
|
+
? undefined
|
|
774
|
+
: sortlinkForName(key, req, viewname, statehash),
|
|
756
775
|
};
|
|
757
776
|
if (column.click_to_edit) {
|
|
758
777
|
const reffield = fields.find((f) => f.name === refNm);
|
|
759
|
-
const oldkey = typeof fvrun.key === "function"
|
|
778
|
+
const oldkey = typeof fvrun.key === "function"
|
|
779
|
+
? fvrun.key
|
|
780
|
+
: (r) => r[fvrun.key];
|
|
760
781
|
const newkey = (row) => div({
|
|
761
782
|
"data-inline-edit-fielddata": encodeURIComponent(JSON.stringify({
|
|
762
783
|
field_name: keypath[0],
|
|
@@ -813,7 +834,7 @@ const get_viewable_fields = (viewname, statehash, table, fields, columns, isShow
|
|
|
813
834
|
showValue = (x) => type.fieldviews[column.agg_fieldview].run(x, req, column);
|
|
814
835
|
}
|
|
815
836
|
else if (column.agg_fieldview) {
|
|
816
|
-
const aggField =
|
|
837
|
+
const aggField = table_1.default.findOne(table)?.getField?.(column.agg_field);
|
|
817
838
|
const outcomeType = column.stat === "Percent true" || column.stat === "Percent false"
|
|
818
839
|
? "Float"
|
|
819
840
|
: column.stat === "Count" || column.stat === "CountUnique"
|
|
@@ -840,7 +861,9 @@ const get_viewable_fields = (viewname, statehash, table, fields, columns, isShow
|
|
|
840
861
|
? column.header_label
|
|
841
862
|
: column.stat + " " + table, targetNm, req, __, statehash),
|
|
842
863
|
key,
|
|
843
|
-
sortlink:
|
|
864
|
+
sortlink: disable_join_agg_sort
|
|
865
|
+
? undefined
|
|
866
|
+
: sortlinkForName(targetNm, req, viewname, statehash),
|
|
844
867
|
};
|
|
845
868
|
}
|
|
846
869
|
else if (column.type === "Field") {
|
|
@@ -852,14 +875,15 @@ const get_viewable_fields = (viewname, statehash, table, fields, columns, isShow
|
|
|
852
875
|
const localized_fld_nm = f.attributes.localized_by[locale];
|
|
853
876
|
f_with_val = fields.find((fld) => fld.name === localized_fld_nm) || f;
|
|
854
877
|
}
|
|
855
|
-
const
|
|
878
|
+
const ftype = f?.type;
|
|
879
|
+
const isNum = f && ftype && ftype.name === "Integer";
|
|
856
880
|
if (isNum && !setWidth.align)
|
|
857
881
|
setWidth.align = "right";
|
|
858
882
|
let fvrun;
|
|
859
|
-
let header_filter = headerFilterForField(f, state);
|
|
883
|
+
let header_filter = headerFilterForField(f || null, state);
|
|
860
884
|
if (column.fieldview &&
|
|
861
|
-
|
|
862
|
-
fvrun =
|
|
885
|
+
ftype?.fieldviews?.[column.fieldview]?.expandColumns) {
|
|
886
|
+
fvrun = ftype.fieldviews[column.fieldview].expandColumns(f, {
|
|
863
887
|
...f.attributes,
|
|
864
888
|
...column.configuration,
|
|
865
889
|
}, column);
|
|
@@ -874,12 +898,12 @@ const get_viewable_fields = (viewname, statehash, table, fields, columns, isShow
|
|
|
874
898
|
? (row) => row[f.name] &&
|
|
875
899
|
getState().fileviews[column.fieldview].run(row[f.name], row[`${f.name}__filename`], { row, ...column, ...(column?.configuration || {}) })
|
|
876
900
|
: column.fieldview &&
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
? (row) =>
|
|
901
|
+
ftype.fieldviews &&
|
|
902
|
+
ftype.fieldviews[column.fieldview]
|
|
903
|
+
? (row) => ftype.fieldviews[column.fieldview].run(row[f_with_val.name], req, { row, ...f.attributes, ...column.configuration })
|
|
880
904
|
: isShow
|
|
881
|
-
?
|
|
882
|
-
? (row) =>
|
|
905
|
+
? ftype.showAs
|
|
906
|
+
? (row) => ftype.showAs(row[f_with_val.name])
|
|
883
907
|
: (row) => text(row[f_with_val.name])
|
|
884
908
|
: f.listKey,
|
|
885
909
|
header_filter,
|
|
@@ -945,8 +969,12 @@ const get_viewable_fields = (viewname, statehash, table, fields, columns, isShow
|
|
|
945
969
|
}
|
|
946
970
|
return tfields;
|
|
947
971
|
};
|
|
972
|
+
exports.get_viewable_fields = get_viewable_fields;
|
|
948
973
|
const headerFilterForField = (f, state, path) => (id) => {
|
|
949
|
-
|
|
974
|
+
const ftype = f?.type;
|
|
975
|
+
if (!f)
|
|
976
|
+
return "";
|
|
977
|
+
if (ftype?.name === "Date") {
|
|
950
978
|
const set_initial = state[`_fromdate_${f.name}`] && state[`_todate_${f.name}`]
|
|
951
979
|
? `defaultDate: ["${state[`_fromdate_${f.name}`]}", "${state[`_todate_${f.name}`]}"],`
|
|
952
980
|
: "";
|
|
@@ -963,33 +991,33 @@ const headerFilterForField = (f, state, path) => (id) => {
|
|
|
963
991
|
script(domReady(`ensure_script_loaded("/static_assets/${db.connectObj.version_tag}/flatpickr.min.js");
|
|
964
992
|
ensure_css_loaded("/static_assets/${db.connectObj.version_tag}/flatpickr.min.css");
|
|
965
993
|
$('#daterangefilter${f.name}').flatpickr({mode:'range',
|
|
966
|
-
dateFormat: "Y-m-d",${set_initial}
|
|
994
|
+
dateFormat: "Y-m-d",${set_initial}
|
|
967
995
|
onChange: function(selectedDates, dateStr, instance) {
|
|
968
996
|
set_header_filter($(instance.element));
|
|
969
997
|
if(selectedDates.length==2) {
|
|
970
|
-
|
|
998
|
+
|
|
971
999
|
set_state_fields({_fromdate_${f.name}: selectedDates[0].toLocaleDateString('en-CA'), _todate_${f.name}: selectedDates[1].toLocaleDateString('en-CA') }, false, ${id ? `document.getElementById('${id}')` : "this"})
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
}
|
|
1000
|
+
|
|
1001
|
+
|
|
1002
|
+
}
|
|
975
1003
|
},
|
|
976
1004
|
});`)));
|
|
977
1005
|
}
|
|
978
1006
|
let fieldviewObjs;
|
|
979
1007
|
/*if (f.is_fkey) {
|
|
980
|
-
|
|
981
|
-
|
|
1008
|
+
fieldviewObjs = [getState().keyFieldviews.select];
|
|
1009
|
+
} else */
|
|
982
1010
|
let extraAttrs = {};
|
|
983
|
-
if (
|
|
984
|
-
fieldviewObjs = [
|
|
1011
|
+
if (ftype?.name === "Bool") {
|
|
1012
|
+
fieldviewObjs = [ftype.fieldviews.tristate];
|
|
985
1013
|
extraAttrs.outline_buttons = true;
|
|
986
1014
|
}
|
|
987
|
-
else if (
|
|
988
|
-
fieldviewObjs = [
|
|
989
|
-
else if (
|
|
1015
|
+
else if (ftype?.name === "String")
|
|
1016
|
+
fieldviewObjs = [ftype.fieldviews.edit];
|
|
1017
|
+
else if (ftype?.name === "Integer" || ftype?.name === "Float")
|
|
990
1018
|
fieldviewObjs = [
|
|
991
|
-
|
|
992
|
-
|
|
1019
|
+
ftype.fieldviews.above_input,
|
|
1020
|
+
ftype.fieldviews.below_input,
|
|
993
1021
|
];
|
|
994
1022
|
if (!fieldviewObjs)
|
|
995
1023
|
return "";
|
|
@@ -1023,7 +1051,7 @@ const standardLayoutRowVisitor = (viewname, state, table, row, req) => {
|
|
|
1023
1051
|
const locale = req.getLocale();
|
|
1024
1052
|
const fields = table.fields;
|
|
1025
1053
|
const evalMaybeExpr = (segment, key, fmlkey) => {
|
|
1026
|
-
if (segment.isFormula && segment.isFormula[fmlkey || key]) {
|
|
1054
|
+
if (segment.isFormula && segment.isFormula[fmlkey || key] && segment[key]) {
|
|
1027
1055
|
segment[key] = eval_expression(segment[key], { session_id, locale, ...row }, req.user, `property ${key} in segment of type ${segment.type}`);
|
|
1028
1056
|
}
|
|
1029
1057
|
};
|
|
@@ -1057,8 +1085,8 @@ const standardLayoutRowVisitor = (viewname, state, table, row, req) => {
|
|
|
1057
1085
|
}
|
|
1058
1086
|
});
|
|
1059
1087
|
// TODO mutation here - potential issue with renderRows
|
|
1060
|
-
segment.titles = segment.titles.filter((
|
|
1061
|
-
segment.contents = segment.contents.filter((
|
|
1088
|
+
segment.titles = segment.titles.filter((_v, ix) => !to_delete.has(ix));
|
|
1089
|
+
segment.contents = segment.contents.filter((_v, ix) => !to_delete.has(ix));
|
|
1062
1090
|
(segment.titles || []).forEach((t, ix) => {
|
|
1063
1091
|
if (typeof t === "string" && t.includes("{{")) {
|
|
1064
1092
|
segment.titles[ix] = interpolate(t, row, req.user, "Tab titles");
|
|
@@ -1080,9 +1108,10 @@ const standardLayoutRowVisitor = (viewname, state, table, row, req) => {
|
|
|
1080
1108
|
const field = fields.find((f) => f.name === segment.field);
|
|
1081
1109
|
if (!field)
|
|
1082
1110
|
return;
|
|
1083
|
-
|
|
1111
|
+
const ftype = field.type;
|
|
1112
|
+
if (ftype?.name === "String")
|
|
1084
1113
|
segment.url = row[segment.field];
|
|
1085
|
-
if (
|
|
1114
|
+
if (ftype === "File") {
|
|
1086
1115
|
segment.url = `/files/serve/${row[segment.field]}`;
|
|
1087
1116
|
segment.fileid = row[segment.field];
|
|
1088
1117
|
}
|
|
@@ -1110,6 +1139,7 @@ const standardLayoutRowVisitor = (viewname, state, table, row, req) => {
|
|
|
1110
1139
|
},
|
|
1111
1140
|
};
|
|
1112
1141
|
};
|
|
1142
|
+
exports.standardLayoutRowVisitor = standardLayoutRowVisitor;
|
|
1113
1143
|
const standardBlockDispatch = (viewname, state, table, extra, row) => {
|
|
1114
1144
|
const req = extra.req;
|
|
1115
1145
|
const fields = table.fields;
|
|
@@ -1120,6 +1150,7 @@ const standardBlockDispatch = (viewname, state, table, extra, row) => {
|
|
|
1120
1150
|
let field = fields.find((fld) => fld.name === field_name);
|
|
1121
1151
|
if (!field)
|
|
1122
1152
|
return "";
|
|
1153
|
+
const ftype = field.type;
|
|
1123
1154
|
let val = row[field_name];
|
|
1124
1155
|
let fvrun;
|
|
1125
1156
|
if (field &&
|
|
@@ -1134,7 +1165,7 @@ const standardBlockDispatch = (viewname, state, table, extra, row) => {
|
|
|
1134
1165
|
...field.attributes,
|
|
1135
1166
|
...configuration,
|
|
1136
1167
|
};
|
|
1137
|
-
if (fieldview &&
|
|
1168
|
+
if (fieldview && ftype === "File") {
|
|
1138
1169
|
if (req.generate_email)
|
|
1139
1170
|
cfg.targetPrefix = getSafeBaseUrl();
|
|
1140
1171
|
fvrun = val
|
|
@@ -1142,10 +1173,10 @@ const standardBlockDispatch = (viewname, state, table, extra, row) => {
|
|
|
1142
1173
|
: "";
|
|
1143
1174
|
}
|
|
1144
1175
|
else if (fieldview &&
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
fvrun =
|
|
1176
|
+
ftype &&
|
|
1177
|
+
ftype.fieldviews &&
|
|
1178
|
+
ftype.fieldviews[fieldview])
|
|
1179
|
+
fvrun = ftype.fieldviews[fieldview].run(val, req, cfg);
|
|
1149
1180
|
else
|
|
1150
1181
|
fvrun = text(val);
|
|
1151
1182
|
if (click_to_edit &&
|
|
@@ -1248,12 +1279,12 @@ const standardBlockDispatch = (viewname, state, table, extra, row) => {
|
|
|
1248
1279
|
if (stat.toLowerCase() === "array_agg" && Array.isArray(val))
|
|
1249
1280
|
return val.map((v) => text(v?.toString?.())).join(", ");
|
|
1250
1281
|
else if (column.agg_fieldview) {
|
|
1251
|
-
const aggField =
|
|
1282
|
+
const aggField = table_1.default.findOne(table)?.getField?.(column.agg_field);
|
|
1252
1283
|
const outcomeType = stat === "Percent true" || stat === "Percent false"
|
|
1253
1284
|
? "Float"
|
|
1254
1285
|
: stat === "Count" || stat === "CountUnique"
|
|
1255
1286
|
? "Integer"
|
|
1256
|
-
: aggField
|
|
1287
|
+
: aggField?.type?.name;
|
|
1257
1288
|
const type = getState().types[outcomeType];
|
|
1258
1289
|
if (type?.fieldviews[column.agg_fieldview]) {
|
|
1259
1290
|
const readval = type.read(val);
|
|
@@ -1266,7 +1297,7 @@ const standardBlockDispatch = (viewname, state, table, extra, row) => {
|
|
|
1266
1297
|
if (segment.action_style === "on_page_load") {
|
|
1267
1298
|
if (extra?.isPreview)
|
|
1268
1299
|
return "";
|
|
1269
|
-
run_action_column({
|
|
1300
|
+
(0, plugin_helper_1.run_action_column)({
|
|
1270
1301
|
col: { ...segment },
|
|
1271
1302
|
referrer: req?.get?.("Referrer"),
|
|
1272
1303
|
req: req,
|
|
@@ -1311,6 +1342,7 @@ const standardBlockDispatch = (viewname, state, table, extra, row) => {
|
|
|
1311
1342
|
},
|
|
1312
1343
|
};
|
|
1313
1344
|
};
|
|
1345
|
+
exports.standardBlockDispatch = standardBlockDispatch;
|
|
1314
1346
|
/**
|
|
1315
1347
|
* @param {object} column
|
|
1316
1348
|
* @param {object} f
|
|
@@ -1350,12 +1382,15 @@ const splitUniques = (fields, state, fuzzyStrings) => {
|
|
|
1350
1382
|
field.type.name === "String")
|
|
1351
1383
|
uniques[k] = { ilike: v };
|
|
1352
1384
|
else if (field && (field.is_unique || field.primary_key))
|
|
1353
|
-
uniques[k] = field.type.read
|
|
1385
|
+
uniques[k] = field.type.read
|
|
1386
|
+
? field.type.read(v, field.attributes)
|
|
1387
|
+
: v;
|
|
1354
1388
|
else
|
|
1355
1389
|
nonUniques[k] = v;
|
|
1356
1390
|
});
|
|
1357
1391
|
return { uniques, nonUniques };
|
|
1358
1392
|
};
|
|
1393
|
+
exports.splitUniques = splitUniques;
|
|
1359
1394
|
/**
|
|
1360
1395
|
* @param {object} table
|
|
1361
1396
|
* @param {string} viewname
|
|
@@ -1374,7 +1409,7 @@ const getForm = async (table, viewname, columns, layout0, id, req, isRemote) =>
|
|
|
1374
1409
|
if (column.type === "Field") {
|
|
1375
1410
|
const f0 = fields.find((fld) => fld.name === column.field_name);
|
|
1376
1411
|
if (f0) {
|
|
1377
|
-
const f = new
|
|
1412
|
+
const f = new field_1.default(f0);
|
|
1378
1413
|
f.fieldview = column.fieldview;
|
|
1379
1414
|
if (f.type === "Key") {
|
|
1380
1415
|
if (state.keyFieldviews[column.fieldview])
|
|
@@ -1404,7 +1439,7 @@ const getForm = async (table, viewname, columns, layout0, id, req, isRemote) =>
|
|
|
1404
1439
|
return f;
|
|
1405
1440
|
}
|
|
1406
1441
|
else if (table.name === "users" && column.field_name === "password") {
|
|
1407
|
-
return new
|
|
1442
|
+
return new field_1.default({
|
|
1408
1443
|
name: "password",
|
|
1409
1444
|
fieldview: column.fieldview,
|
|
1410
1445
|
type: "String",
|
|
@@ -1412,14 +1447,14 @@ const getForm = async (table, viewname, columns, layout0, id, req, isRemote) =>
|
|
|
1412
1447
|
}
|
|
1413
1448
|
else if (table.name === "users" &&
|
|
1414
1449
|
column.field_name === "passwordRepeat") {
|
|
1415
|
-
return new
|
|
1450
|
+
return new field_1.default({
|
|
1416
1451
|
name: "passwordRepeat",
|
|
1417
1452
|
fieldview: column.fieldview,
|
|
1418
1453
|
type: "String",
|
|
1419
1454
|
});
|
|
1420
1455
|
}
|
|
1421
1456
|
else if (table.name === "users" && column.field_name === "remember") {
|
|
1422
|
-
return new
|
|
1457
|
+
return new field_1.default({
|
|
1423
1458
|
name: "remember",
|
|
1424
1459
|
fieldview: column.fieldview,
|
|
1425
1460
|
type: "Bool",
|
|
@@ -1451,6 +1486,7 @@ const getForm = async (table, viewname, columns, layout0, id, req, isRemote) =>
|
|
|
1451
1486
|
ref: ref.replace("?", ""),
|
|
1452
1487
|
target,
|
|
1453
1488
|
refTable: refField.reftable_name,
|
|
1489
|
+
refTablePK: table_1.default.findOne(refField.reftable_name).pk_name,
|
|
1454
1490
|
};
|
|
1455
1491
|
})
|
|
1456
1492
|
.filter(Boolean);
|
|
@@ -1490,6 +1526,345 @@ const getForm = async (table, viewname, columns, layout0, id, req, isRemote) =>
|
|
|
1490
1526
|
form.hidden(form.pk_name);
|
|
1491
1527
|
return form;
|
|
1492
1528
|
};
|
|
1529
|
+
exports.getForm = getForm;
|
|
1530
|
+
const transformForm = async ({ form, table, req, row, res, getRowQuery, viewname, optionsQuery, state, }) => {
|
|
1531
|
+
let originalState = state;
|
|
1532
|
+
let pseudo_row = {};
|
|
1533
|
+
if (!row) {
|
|
1534
|
+
table.fields.forEach((f) => {
|
|
1535
|
+
pseudo_row[f.name] = undefined;
|
|
1536
|
+
});
|
|
1537
|
+
}
|
|
1538
|
+
const appState = getState();
|
|
1539
|
+
const __ = db.is_node && appState
|
|
1540
|
+
? (s) => appState.i18n.__({ phrase: s, locale: req.getLocale() }) || s
|
|
1541
|
+
: (s) => {
|
|
1542
|
+
return s;
|
|
1543
|
+
};
|
|
1544
|
+
await traverse(form.layout, {
|
|
1545
|
+
container(segment) {
|
|
1546
|
+
if (segment.click_action) {
|
|
1547
|
+
segment.url = `javascript:view_post(this, 'run_action', {click_action: '${segment.click_action}', ...get_form_record(this) })`;
|
|
1548
|
+
}
|
|
1549
|
+
},
|
|
1550
|
+
async action(segment) {
|
|
1551
|
+
if (segment.action_style === "on_page_load") {
|
|
1552
|
+
segment.type = "blank";
|
|
1553
|
+
segment.style = {};
|
|
1554
|
+
if (segment.minRole && segment.minRole != 100) {
|
|
1555
|
+
const minRole = +segment.minRole;
|
|
1556
|
+
const userRole = req?.user?.role_id || 100;
|
|
1557
|
+
if (minRole < userRole)
|
|
1558
|
+
return;
|
|
1559
|
+
}
|
|
1560
|
+
if (req.method === "POST")
|
|
1561
|
+
return;
|
|
1562
|
+
//run action
|
|
1563
|
+
try {
|
|
1564
|
+
const actionResult = await (0, plugin_helper_1.run_action_column)({
|
|
1565
|
+
col: { ...segment },
|
|
1566
|
+
referrer: req?.get?.("Referrer"),
|
|
1567
|
+
req,
|
|
1568
|
+
res,
|
|
1569
|
+
table,
|
|
1570
|
+
row: row || pseudo_row,
|
|
1571
|
+
});
|
|
1572
|
+
if (actionResult)
|
|
1573
|
+
segment.contents = script(domReady(`common_done(${JSON.stringify(actionResult)}, "${viewname}")`));
|
|
1574
|
+
}
|
|
1575
|
+
catch (e) {
|
|
1576
|
+
const err = e;
|
|
1577
|
+
appState.log(5, `Error in Edit ${viewname} on page load action: ${err.message}`);
|
|
1578
|
+
err.message = `Error in evaluating Run on Page Load action in view ${viewname}: ${err.message}`;
|
|
1579
|
+
throw err;
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
if (segment.action_name === "Delete") {
|
|
1583
|
+
if (form.values && form.values[table.pk_name]) {
|
|
1584
|
+
segment.action_url = table.delete_url(form.values);
|
|
1585
|
+
}
|
|
1586
|
+
else {
|
|
1587
|
+
segment.type = "blank";
|
|
1588
|
+
segment.contents = "";
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
else if (segment.action_name === "form_action" &&
|
|
1592
|
+
segment.configuration?.form_action === "Save" &&
|
|
1593
|
+
table.fields.some((f) => f.type === "File")) {
|
|
1594
|
+
let url = action_url(viewname, table, segment.action_name, row || pseudo_row, segment.rndid, "rndid", segment.confirm);
|
|
1595
|
+
if (typeof url !== "string" && url.javascript) {
|
|
1596
|
+
//redo to include dynamic row
|
|
1597
|
+
const confirmStr = segment.confirm
|
|
1598
|
+
? `if(confirm('Are you sure?'))`
|
|
1599
|
+
: "";
|
|
1600
|
+
url.javascript = `${confirmStr}view_post(this, 'run_action', get_form_data(this, '${segment.rndid}') );`;
|
|
1601
|
+
}
|
|
1602
|
+
segment.action_link = action_link(url, req, segment, __);
|
|
1603
|
+
}
|
|
1604
|
+
else if (!["Sign up", ...edit_build_in_actions].includes(segment.action_name) &&
|
|
1605
|
+
!segment.action_name.startsWith("Login")) {
|
|
1606
|
+
let url = action_url(viewname, table, segment.action_name, row || pseudo_row, segment.rndid, "rndid", segment.confirm, undefined, segment.run_async);
|
|
1607
|
+
if (typeof url !== "string" && url.javascript) {
|
|
1608
|
+
//redo to include dynamic row
|
|
1609
|
+
const confirmStr = segment.confirm
|
|
1610
|
+
? `if(confirm('Are you sure?'))`
|
|
1611
|
+
: "";
|
|
1612
|
+
// If this is a Multi-step action or the form/table contains File fields,
|
|
1613
|
+
// post multipart FormData so req.files is populated server-side.
|
|
1614
|
+
const hasFileFields = table.fields?.some((f) => f.type === "File");
|
|
1615
|
+
if (segment.action_name === "Multi-step action" || hasFileFields) {
|
|
1616
|
+
url.javascript = `${confirmStr}view_post(this, 'run_action', get_form_data(this, '${segment.rndid}') );`;
|
|
1617
|
+
}
|
|
1618
|
+
else {
|
|
1619
|
+
url.javascript = `${confirmStr}view_post(this, 'run_action', {rndid:'${segment.rndid}', ...get_form_record(this)});`;
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1622
|
+
segment.action_link = action_link(url, req, segment, __);
|
|
1623
|
+
}
|
|
1624
|
+
},
|
|
1625
|
+
join_field(segment) {
|
|
1626
|
+
const qs = objToQueryString(segment.configuration);
|
|
1627
|
+
segment.sourceURL = `/field/show-calculated/${table.name}/${segment.join_field}/${segment.fieldview}?${qs}`;
|
|
1628
|
+
},
|
|
1629
|
+
tabs(segment) {
|
|
1630
|
+
const to_delete = new Set();
|
|
1631
|
+
(segment.showif || []).forEach((sif, ix) => {
|
|
1632
|
+
if (sif) {
|
|
1633
|
+
const showit = eval_expression(sif, row || pseudo_row, req.user, "Tab show if formula");
|
|
1634
|
+
if (!showit)
|
|
1635
|
+
to_delete.add(ix);
|
|
1636
|
+
}
|
|
1637
|
+
});
|
|
1638
|
+
segment.titles = segment.titles.filter((_v, ix) => !to_delete.has(ix));
|
|
1639
|
+
segment.contents = segment.contents.filter((_v, ix) => !to_delete.has(ix));
|
|
1640
|
+
(segment.titles || []).forEach((t, ix) => {
|
|
1641
|
+
if (typeof t === "string" && t.includes("{{")) {
|
|
1642
|
+
segment.titles[ix] = interpolate(t, row, req.user, "Tab titles");
|
|
1643
|
+
}
|
|
1644
|
+
});
|
|
1645
|
+
},
|
|
1646
|
+
view_link(segment) {
|
|
1647
|
+
segment.type = "blank";
|
|
1648
|
+
const view_select = parse_view_select(segment.view);
|
|
1649
|
+
if (!row && view_select.type !== "Independent") {
|
|
1650
|
+
segment.contents = "";
|
|
1651
|
+
}
|
|
1652
|
+
else {
|
|
1653
|
+
const prefix = req.generate_email && req.get_base_url ? req.get_base_url() : "";
|
|
1654
|
+
const { key } = view_linker(segment, table.fields, (s) => s, isWeb(req), req.user, prefix, req.query, req, viewname);
|
|
1655
|
+
segment.contents = key(row || {});
|
|
1656
|
+
}
|
|
1657
|
+
},
|
|
1658
|
+
async view(segment) {
|
|
1659
|
+
//console.log(segment);
|
|
1660
|
+
const view_select = parse_view_select(segment.view, segment.relation);
|
|
1661
|
+
//console.log({ view_select });
|
|
1662
|
+
const view = view_1.default.findOne({ name: view_select.viewname });
|
|
1663
|
+
if (!view)
|
|
1664
|
+
throw new InvalidConfiguration(`Cannot find embedded view: ${view_select.viewname}`);
|
|
1665
|
+
// check if the relation path matches a ChildList relations
|
|
1666
|
+
let childListRelPath = false;
|
|
1667
|
+
if (segment.relation && view.table_id) {
|
|
1668
|
+
const targetTbl = table_1.default.findOne({ id: view.table_id });
|
|
1669
|
+
const relation = new Relation(segment.relation, targetTbl.name, (0, plugin_helper_1.displayType)(await view.get_state_fields()));
|
|
1670
|
+
childListRelPath = relation.type === RelationType.CHILD_LIST;
|
|
1671
|
+
}
|
|
1672
|
+
// Edit-in-edit
|
|
1673
|
+
if (view.viewtemplate === "Edit" &&
|
|
1674
|
+
(view_select.type === "ChildList" || childListRelPath)) {
|
|
1675
|
+
if (childListRelPath)
|
|
1676
|
+
updateViewSelect(view_select);
|
|
1677
|
+
const childTable = table_1.default.findOne({ id: view.table_id });
|
|
1678
|
+
const childForm = await getForm(childTable, view.name, view.configuration.columns, view.configuration.layout, row?.id, req, !isWeb(req));
|
|
1679
|
+
traverseSync(childForm.layout, {
|
|
1680
|
+
field(segment) {
|
|
1681
|
+
segment.field_name = `${view_select.field_name}.${segment.field_name}`;
|
|
1682
|
+
},
|
|
1683
|
+
});
|
|
1684
|
+
for (const field of childForm.fields) {
|
|
1685
|
+
if (field.name === childTable.pk_name) {
|
|
1686
|
+
field.class = field.class
|
|
1687
|
+
? `${field.class} omit-repeater-clone`
|
|
1688
|
+
: "omit-repeater-clone";
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1691
|
+
await childForm.fill_fkey_options(false, optionsQuery, req.user);
|
|
1692
|
+
const fr = new FieldRepeat({
|
|
1693
|
+
name: view_select.field_name,
|
|
1694
|
+
label: view_select.field_name,
|
|
1695
|
+
fields: childForm.fields,
|
|
1696
|
+
layout: childForm.layout,
|
|
1697
|
+
metadata: {
|
|
1698
|
+
table_id: childTable.id,
|
|
1699
|
+
view: segment.view,
|
|
1700
|
+
relation: view_select.field_name,
|
|
1701
|
+
relation_path: segment.relation,
|
|
1702
|
+
order_field: segment.order_field,
|
|
1703
|
+
},
|
|
1704
|
+
});
|
|
1705
|
+
if (row?.id) {
|
|
1706
|
+
const childRows = getRowQuery
|
|
1707
|
+
? await getRowQuery(view.table_id, view_select, row.id, segment.order_field)
|
|
1708
|
+
: await childTable.getRows({
|
|
1709
|
+
[view_select.field_name]: row.id,
|
|
1710
|
+
}, segment.order_field ? { orderBy: segment.order_field } : {});
|
|
1711
|
+
fr.metadata.rows = childRows;
|
|
1712
|
+
if (!fr.fields.map((f) => f.name).includes(childTable.pk_name))
|
|
1713
|
+
fr.fields.push({
|
|
1714
|
+
name: childTable.pk_name,
|
|
1715
|
+
input_type: "hidden",
|
|
1716
|
+
});
|
|
1717
|
+
}
|
|
1718
|
+
form.fields.push(fr);
|
|
1719
|
+
segment.type = "field_repeat";
|
|
1720
|
+
segment.field_repeat = fr;
|
|
1721
|
+
return;
|
|
1722
|
+
} // end edit in edit
|
|
1723
|
+
const outerState = {};
|
|
1724
|
+
Object.entries(originalState || {}).forEach(([k, v]) => {
|
|
1725
|
+
if (k.startsWith("_"))
|
|
1726
|
+
outerState[k] = v;
|
|
1727
|
+
});
|
|
1728
|
+
let state = {};
|
|
1729
|
+
let urlFormula;
|
|
1730
|
+
let needFields = new Set();
|
|
1731
|
+
if (view_select.type === "RelationPath" && view.table_id) {
|
|
1732
|
+
const pathToUrlFormula = (relation) => {
|
|
1733
|
+
const st = (0, plugin_helper_1.pathToState)(relation, (k) => `row.` + k);
|
|
1734
|
+
return Object.entries(st)
|
|
1735
|
+
.map(([k, v]) => {
|
|
1736
|
+
needFields.add(v.split(".")[1]);
|
|
1737
|
+
return `${k}='+${v}+'`;
|
|
1738
|
+
})
|
|
1739
|
+
.join("&");
|
|
1740
|
+
};
|
|
1741
|
+
const targetTbl = table_1.default.findOne({ id: view.table_id });
|
|
1742
|
+
if (targetTbl) {
|
|
1743
|
+
const relation = new Relation(segment.relation, targetTbl.name, (0, plugin_helper_1.displayType)(await view.get_state_fields()));
|
|
1744
|
+
const relFmlQS = pathToUrlFormula(relation);
|
|
1745
|
+
const type = relation.type;
|
|
1746
|
+
if (!row && type == RelationType.OWN) {
|
|
1747
|
+
segment.type = "blank";
|
|
1748
|
+
urlFormula = `add_extra_state('/view/${view.name}/?${relFmlQS}', ${JSON.stringify(segment.extra_state_fml)}, row, ${JSON.stringify(outerState)})`;
|
|
1749
|
+
segment.contents = segment.contents = div({
|
|
1750
|
+
class: "d-inline",
|
|
1751
|
+
"data-sc-embed-viewname": view.name,
|
|
1752
|
+
"data-view-source-need-fields": [...needFields].join(","),
|
|
1753
|
+
"data-view-source": encodeURIComponent(urlFormula),
|
|
1754
|
+
});
|
|
1755
|
+
return;
|
|
1756
|
+
}
|
|
1757
|
+
else if (!row &&
|
|
1758
|
+
type !== RelationType.INDEPENDENT &&
|
|
1759
|
+
!relation.isFixedRelation()) {
|
|
1760
|
+
urlFormula = `add_extra_state('/view/${view.name}/?${relFmlQS}', ${JSON.stringify(segment.extra_state_fml)}, row, ${JSON.stringify(outerState)})`;
|
|
1761
|
+
segment.contents = segment.contents = div({
|
|
1762
|
+
class: "d-inline",
|
|
1763
|
+
"data-sc-embed-viewname": view.name,
|
|
1764
|
+
"data-view-source-need-fields": [...needFields].join(","),
|
|
1765
|
+
"data-view-source": encodeURIComponent(urlFormula),
|
|
1766
|
+
});
|
|
1767
|
+
return;
|
|
1768
|
+
}
|
|
1769
|
+
const userId = req?.user?.id;
|
|
1770
|
+
state = (0, plugin_helper_1.pathToState)(relation, relation.isFixedRelation() ? () => userId : (k) => row[k]);
|
|
1771
|
+
urlFormula = `add_extra_state('/view/${view.name}?${relFmlQS}', ${JSON.stringify(segment.extra_state_fml)}, row, ${JSON.stringify(outerState)})`;
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
else {
|
|
1775
|
+
const isIndependent = view_select.type === "Independent";
|
|
1776
|
+
// legacy none check ?
|
|
1777
|
+
if (!view)
|
|
1778
|
+
throw new InvalidConfiguration(`Edit view incorrectly configured: cannot find embedded view ${view_select.viewname}`);
|
|
1779
|
+
switch (view_select.type) {
|
|
1780
|
+
case "Own":
|
|
1781
|
+
state = { id: row?.id };
|
|
1782
|
+
urlFormula = `add_extra_state('/view/${view.name}/?id='+row.id, ${JSON.stringify(segment.extra_state_fml)}, row, ${JSON.stringify(outerState)})`;
|
|
1783
|
+
needFields.add("id");
|
|
1784
|
+
break;
|
|
1785
|
+
case "Independent":
|
|
1786
|
+
state = {};
|
|
1787
|
+
urlFormula = `add_extra_state('/view/${view.name}/?id='+row.id, ${JSON.stringify(segment.extra_state_fml)}, row, ${JSON.stringify(outerState)})`;
|
|
1788
|
+
needFields.add("id");
|
|
1789
|
+
break;
|
|
1790
|
+
case "ChildList":
|
|
1791
|
+
case "OneToOneShow":
|
|
1792
|
+
state = { [view_select.field_name]: row?.id };
|
|
1793
|
+
urlFormula = `add_extra_state('/view/${view.name}/?${view_select.field_name}='+row.id, ${JSON.stringify(segment.extra_state_fml)}, row, ${JSON.stringify(outerState)})`;
|
|
1794
|
+
needFields.add("id");
|
|
1795
|
+
break;
|
|
1796
|
+
case "ParentShow":
|
|
1797
|
+
state = { id: row?.[view_select.field_name] };
|
|
1798
|
+
urlFormula = `add_extra_state('/view/${view.name}/?id='+row.${view_select.field_name}, ${JSON.stringify(segment.extra_state_fml)}, row, ${JSON.stringify(outerState)})`;
|
|
1799
|
+
needFields.add(view_select.field_name);
|
|
1800
|
+
break;
|
|
1801
|
+
}
|
|
1802
|
+
if (!row && !isIndependent) {
|
|
1803
|
+
segment.type = "blank";
|
|
1804
|
+
segment.contents = div({
|
|
1805
|
+
class: "d-inline",
|
|
1806
|
+
"data-sc-embed-viewname": view.name,
|
|
1807
|
+
"data-view-source-need-fields": [...needFields].join(","),
|
|
1808
|
+
"data-view-source": encodeURIComponent(urlFormula),
|
|
1809
|
+
});
|
|
1810
|
+
return;
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1813
|
+
const extra_state = segment.extra_state_fml
|
|
1814
|
+
? eval_expression(segment.extra_state_fml, {
|
|
1815
|
+
...dollarizeObject(req.query),
|
|
1816
|
+
session_id: getSessionId(req),
|
|
1817
|
+
...(row || pseudo_row),
|
|
1818
|
+
}, req.user, `Extra state formula for embedding view ${view.name}`)
|
|
1819
|
+
: {};
|
|
1820
|
+
const qs = (0, plugin_helper_1.stateToQueryString)({ ...state, ...outerState, ...extra_state }, true);
|
|
1821
|
+
segment.contents = div({
|
|
1822
|
+
class: "d-inline",
|
|
1823
|
+
"data-sc-embed-viewname": view.name,
|
|
1824
|
+
"data-sc-view-source": `/view/${view.name}${qs}`,
|
|
1825
|
+
"data-view-source-current": `/view/${view.name}${qs}`,
|
|
1826
|
+
"data-view-source-need-fields": [...needFields].join(","),
|
|
1827
|
+
"data-view-source": encodeURIComponent(urlFormula),
|
|
1828
|
+
}, view.renderLocally()
|
|
1829
|
+
? await view.run({ ...state, ...outerState, ...extra_state }, { req, res }, view.isRemoteTable())
|
|
1830
|
+
: await renderServerSide(view.name, {
|
|
1831
|
+
...state,
|
|
1832
|
+
...outerState,
|
|
1833
|
+
...extra_state,
|
|
1834
|
+
}));
|
|
1835
|
+
},
|
|
1836
|
+
});
|
|
1837
|
+
translateLayout(form.layout, req.getLocale());
|
|
1838
|
+
if (req.headers?.saltcornmodalrequest)
|
|
1839
|
+
form.xhrSubmit = true;
|
|
1840
|
+
setDateLocales(form, req.getLocale());
|
|
1841
|
+
};
|
|
1842
|
+
exports.transformForm = transformForm;
|
|
1843
|
+
const setDateLocales = (form, locale) => {
|
|
1844
|
+
form.fields.forEach((f) => {
|
|
1845
|
+
const ftype = f.type;
|
|
1846
|
+
if (ftype && ftype.name === "Date") {
|
|
1847
|
+
f.attributes.locale = locale;
|
|
1848
|
+
}
|
|
1849
|
+
});
|
|
1850
|
+
};
|
|
1851
|
+
exports.setDateLocales = setDateLocales;
|
|
1852
|
+
/**
|
|
1853
|
+
* update viewSelect so that it looks like a normal ChildList
|
|
1854
|
+
*/
|
|
1855
|
+
const updateViewSelect = (viewSelect) => {
|
|
1856
|
+
if (viewSelect.path.length === 1) {
|
|
1857
|
+
viewSelect.field_name = viewSelect.path[0].inboundKey;
|
|
1858
|
+
viewSelect.table_name = viewSelect.path[0].table;
|
|
1859
|
+
}
|
|
1860
|
+
else if (viewSelect.path.length === 2) {
|
|
1861
|
+
viewSelect.field_name = viewSelect.path[1].inboundKey;
|
|
1862
|
+
viewSelect.table_name = viewSelect.path[1].table;
|
|
1863
|
+
viewSelect.throughTable = viewSelect.path[0].inboundKey;
|
|
1864
|
+
viewSelect.through = viewSelect.path[0].table;
|
|
1865
|
+
}
|
|
1866
|
+
};
|
|
1867
|
+
exports.updateViewSelect = updateViewSelect;
|
|
1493
1868
|
/**
|
|
1494
1869
|
* @param {object} table
|
|
1495
1870
|
* @param {object} req
|
|
@@ -1528,9 +1903,11 @@ const fill_presets = async (table, req, fixed) => {
|
|
|
1528
1903
|
});
|
|
1529
1904
|
return fixed;
|
|
1530
1905
|
};
|
|
1906
|
+
exports.fill_presets = fill_presets;
|
|
1531
1907
|
const objToQueryString = (o) => Object.entries(o || {})
|
|
1532
1908
|
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
|
|
1533
1909
|
.join("&");
|
|
1910
|
+
exports.objToQueryString = objToQueryString;
|
|
1534
1911
|
// edit template build in actions
|
|
1535
1912
|
const edit_build_in_actions = [
|
|
1536
1913
|
"Save",
|
|
@@ -1542,21 +1919,5 @@ const edit_build_in_actions = [
|
|
|
1542
1919
|
"Delete",
|
|
1543
1920
|
"Cancel",
|
|
1544
1921
|
];
|
|
1545
|
-
|
|
1546
|
-
get_viewable_fields,
|
|
1547
|
-
get_viewable_fields_from_layout,
|
|
1548
|
-
action_url,
|
|
1549
|
-
objToQueryString,
|
|
1550
|
-
action_link,
|
|
1551
|
-
view_linker,
|
|
1552
|
-
parse_view_select,
|
|
1553
|
-
splitUniques,
|
|
1554
|
-
getForm,
|
|
1555
|
-
fill_presets,
|
|
1556
|
-
get_view_link_query,
|
|
1557
|
-
make_link,
|
|
1558
|
-
edit_build_in_actions,
|
|
1559
|
-
standardBlockDispatch,
|
|
1560
|
-
standardLayoutRowVisitor,
|
|
1561
|
-
};
|
|
1922
|
+
exports.edit_build_in_actions = edit_build_in_actions;
|
|
1562
1923
|
//# sourceMappingURL=viewable_fields.js.map
|