@saltcorn/data 1.5.0 → 1.5.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/migrations/202603101553.d.ts +4 -0
- package/dist/migrations/202603101553.d.ts.map +1 -0
- package/dist/migrations/202603101553.js +22 -0
- package/dist/migrations/202603101553.js.map +1 -0
- package/dist/mobile-mocks/node/assert.d.ts +1 -0
- package/dist/mobile-mocks/node/assert.d.ts.map +1 -0
- package/dist/mobile-mocks/node/assert.js +2 -0
- package/dist/mobile-mocks/node/assert.js.map +1 -0
- 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/models/expression.d.ts.map +1 -1
- package/dist/models/expression.js +1 -1
- package/dist/models/expression.js.map +1 -1
- package/dist/viewable_fields.d.ts +151 -96
- package/dist/viewable_fields.d.ts.map +1 -1
- package/dist/viewable_fields.js +465 -99
- 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
|
|
@@ -80,15 +87,15 @@ const action_url = (viewname, table, action_name, r, colId, colIdNm, confirm, co
|
|
|
80
87
|
* @param {*} __
|
|
81
88
|
* @returns {object}
|
|
82
89
|
*/
|
|
83
|
-
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;
|
|
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, in_row_click) => {
|
|
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
|
-
onclick: `${spinner ? "spin_action_link(this);" : ""}${url.javascript}`,
|
|
98
|
+
onclick: `${spinner ? "spin_action_link(this);" : ""}${url.javascript}${in_row_click ? ";event.stopPropagation()" : ""}`,
|
|
92
99
|
class: [
|
|
93
100
|
action_style === "btn-link"
|
|
94
101
|
? ""
|
|
@@ -107,10 +114,11 @@ const action_link = (url, req, { action_name, action_label, confirm, rndid, acti
|
|
|
107
114
|
icon: action_icon,
|
|
108
115
|
style,
|
|
109
116
|
spinner,
|
|
110
|
-
btnClass: `${action_style || "btn-primary"} ${action_size || ""}`,
|
|
117
|
+
btnClass: `${action_style || "btn-primary"} ${action_size || ""}${action_class ? " " + action_class : ""}`,
|
|
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);
|
|
@@ -529,9 +545,9 @@ const get_viewable_fields = (viewname, statehash, table, fields, columns, isShow
|
|
|
529
545
|
traverseSync(layout, standardLayoutRowVisitor(viewname, state, table, r, req));
|
|
530
546
|
return renderLayout({
|
|
531
547
|
blockDispatch: {
|
|
532
|
-
...standardBlockDispatch(viewname, state, table, { req }, r),
|
|
548
|
+
...standardBlockDispatch(viewname, state, table, { req }, r, in_row_click),
|
|
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,7 +1139,8 @@ const standardLayoutRowVisitor = (viewname, state, table, row, req) => {
|
|
|
1110
1139
|
},
|
|
1111
1140
|
};
|
|
1112
1141
|
};
|
|
1113
|
-
|
|
1142
|
+
exports.standardLayoutRowVisitor = standardLayoutRowVisitor;
|
|
1143
|
+
const standardBlockDispatch = (viewname, state, table, extra, row, in_row_click) => {
|
|
1114
1144
|
const req = extra.req;
|
|
1115
1145
|
const fields = table.fields;
|
|
1116
1146
|
const locale = req.getLocale();
|
|
@@ -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 &&
|
|
@@ -1166,7 +1197,7 @@ const standardBlockDispatch = (viewname, state, table, extra, row) => {
|
|
|
1166
1197
|
return fvrun;
|
|
1167
1198
|
},
|
|
1168
1199
|
join_field(jf) {
|
|
1169
|
-
|
|
1200
|
+
let { join_field, field_type, fieldview, configuration, target_field_attributes, click_to_edit, } = jf;
|
|
1170
1201
|
const keypath = join_field.split(".");
|
|
1171
1202
|
let value;
|
|
1172
1203
|
if (join_field.includes("->")) {
|
|
@@ -1185,6 +1216,11 @@ const standardBlockDispatch = (viewname, state, table, extra, row) => {
|
|
|
1185
1216
|
: "";
|
|
1186
1217
|
}
|
|
1187
1218
|
let fvRes;
|
|
1219
|
+
if (!field_type) {
|
|
1220
|
+
const field = table.getField(join_field);
|
|
1221
|
+
if (field)
|
|
1222
|
+
field_type = field?.type?.name;
|
|
1223
|
+
}
|
|
1188
1224
|
if (field_type && fieldview) {
|
|
1189
1225
|
const type = getState().types[field_type];
|
|
1190
1226
|
if (type && getState().types[field_type]) {
|
|
@@ -1248,12 +1284,12 @@ const standardBlockDispatch = (viewname, state, table, extra, row) => {
|
|
|
1248
1284
|
if (stat.toLowerCase() === "array_agg" && Array.isArray(val))
|
|
1249
1285
|
return val.map((v) => text(v?.toString?.())).join(", ");
|
|
1250
1286
|
else if (column.agg_fieldview) {
|
|
1251
|
-
const aggField =
|
|
1287
|
+
const aggField = table_1.default.findOne(table)?.getField?.(column.agg_field);
|
|
1252
1288
|
const outcomeType = stat === "Percent true" || stat === "Percent false"
|
|
1253
1289
|
? "Float"
|
|
1254
1290
|
: stat === "Count" || stat === "CountUnique"
|
|
1255
1291
|
? "Integer"
|
|
1256
|
-
: aggField
|
|
1292
|
+
: aggField?.type?.name;
|
|
1257
1293
|
const type = getState().types[outcomeType];
|
|
1258
1294
|
if (type?.fieldviews[column.agg_fieldview]) {
|
|
1259
1295
|
const readval = type.read(val);
|
|
@@ -1266,7 +1302,7 @@ const standardBlockDispatch = (viewname, state, table, extra, row) => {
|
|
|
1266
1302
|
if (segment.action_style === "on_page_load") {
|
|
1267
1303
|
if (extra?.isPreview)
|
|
1268
1304
|
return "";
|
|
1269
|
-
run_action_column({
|
|
1305
|
+
(0, plugin_helper_1.run_action_column)({
|
|
1270
1306
|
col: { ...segment },
|
|
1271
1307
|
referrer: req?.get?.("Referrer"),
|
|
1272
1308
|
req: req,
|
|
@@ -1283,11 +1319,11 @@ const standardBlockDispatch = (viewname, state, table, extra, row) => {
|
|
|
1283
1319
|
}
|
|
1284
1320
|
else if (segment.action_name === "Delete")
|
|
1285
1321
|
url = `${table.delete_url(row, `redirect=${encodeURIComponent(interpolate(segment.configuration?.after_delete_url || "/", row, req?.user, "delete action: after delete URL"))}`)}`;
|
|
1286
|
-
return action_link(url, req, segment);
|
|
1322
|
+
return action_link(url, req, segment, undefined, in_row_click);
|
|
1287
1323
|
},
|
|
1288
1324
|
view_link(view) {
|
|
1289
1325
|
const prefix = req.generate_email && req.get_base_url ? req.get_base_url() : "";
|
|
1290
|
-
const { key } = view_linker(view, fields, (s) => s, isWeb(req), req.user, prefix, state, req, viewname);
|
|
1326
|
+
const { key } = view_linker(view, fields, (s) => s, isWeb(req), req.user, prefix, state, req, viewname, undefined, in_row_click);
|
|
1291
1327
|
return key(row);
|
|
1292
1328
|
},
|
|
1293
1329
|
tabs(segment, go) {
|
|
@@ -1311,6 +1347,7 @@ const standardBlockDispatch = (viewname, state, table, extra, row) => {
|
|
|
1311
1347
|
},
|
|
1312
1348
|
};
|
|
1313
1349
|
};
|
|
1350
|
+
exports.standardBlockDispatch = standardBlockDispatch;
|
|
1314
1351
|
/**
|
|
1315
1352
|
* @param {object} column
|
|
1316
1353
|
* @param {object} f
|
|
@@ -1350,12 +1387,15 @@ const splitUniques = (fields, state, fuzzyStrings) => {
|
|
|
1350
1387
|
field.type.name === "String")
|
|
1351
1388
|
uniques[k] = { ilike: v };
|
|
1352
1389
|
else if (field && (field.is_unique || field.primary_key))
|
|
1353
|
-
uniques[k] = field.type.read
|
|
1390
|
+
uniques[k] = field.type.read
|
|
1391
|
+
? field.type.read(v, field.attributes)
|
|
1392
|
+
: v;
|
|
1354
1393
|
else
|
|
1355
1394
|
nonUniques[k] = v;
|
|
1356
1395
|
});
|
|
1357
1396
|
return { uniques, nonUniques };
|
|
1358
1397
|
};
|
|
1398
|
+
exports.splitUniques = splitUniques;
|
|
1359
1399
|
/**
|
|
1360
1400
|
* @param {object} table
|
|
1361
1401
|
* @param {string} viewname
|
|
@@ -1374,7 +1414,7 @@ const getForm = async (table, viewname, columns, layout0, id, req, isRemote) =>
|
|
|
1374
1414
|
if (column.type === "Field") {
|
|
1375
1415
|
const f0 = fields.find((fld) => fld.name === column.field_name);
|
|
1376
1416
|
if (f0) {
|
|
1377
|
-
const f = new
|
|
1417
|
+
const f = new field_1.default(f0);
|
|
1378
1418
|
f.fieldview = column.fieldview;
|
|
1379
1419
|
if (f.type === "Key") {
|
|
1380
1420
|
if (state.keyFieldviews[column.fieldview])
|
|
@@ -1404,7 +1444,7 @@ const getForm = async (table, viewname, columns, layout0, id, req, isRemote) =>
|
|
|
1404
1444
|
return f;
|
|
1405
1445
|
}
|
|
1406
1446
|
else if (table.name === "users" && column.field_name === "password") {
|
|
1407
|
-
return new
|
|
1447
|
+
return new field_1.default({
|
|
1408
1448
|
name: "password",
|
|
1409
1449
|
fieldview: column.fieldview,
|
|
1410
1450
|
type: "String",
|
|
@@ -1412,14 +1452,14 @@ const getForm = async (table, viewname, columns, layout0, id, req, isRemote) =>
|
|
|
1412
1452
|
}
|
|
1413
1453
|
else if (table.name === "users" &&
|
|
1414
1454
|
column.field_name === "passwordRepeat") {
|
|
1415
|
-
return new
|
|
1455
|
+
return new field_1.default({
|
|
1416
1456
|
name: "passwordRepeat",
|
|
1417
1457
|
fieldview: column.fieldview,
|
|
1418
1458
|
type: "String",
|
|
1419
1459
|
});
|
|
1420
1460
|
}
|
|
1421
1461
|
else if (table.name === "users" && column.field_name === "remember") {
|
|
1422
|
-
return new
|
|
1462
|
+
return new field_1.default({
|
|
1423
1463
|
name: "remember",
|
|
1424
1464
|
fieldview: column.fieldview,
|
|
1425
1465
|
type: "Bool",
|
|
@@ -1451,6 +1491,7 @@ const getForm = async (table, viewname, columns, layout0, id, req, isRemote) =>
|
|
|
1451
1491
|
ref: ref.replace("?", ""),
|
|
1452
1492
|
target,
|
|
1453
1493
|
refTable: refField.reftable_name,
|
|
1494
|
+
refTablePK: table_1.default.findOne(refField.reftable_name).pk_name,
|
|
1454
1495
|
};
|
|
1455
1496
|
})
|
|
1456
1497
|
.filter(Boolean);
|
|
@@ -1490,6 +1531,345 @@ const getForm = async (table, viewname, columns, layout0, id, req, isRemote) =>
|
|
|
1490
1531
|
form.hidden(form.pk_name);
|
|
1491
1532
|
return form;
|
|
1492
1533
|
};
|
|
1534
|
+
exports.getForm = getForm;
|
|
1535
|
+
const transformForm = async ({ form, table, req, row, res, getRowQuery, viewname, optionsQuery, state, }) => {
|
|
1536
|
+
let originalState = state;
|
|
1537
|
+
let pseudo_row = {};
|
|
1538
|
+
if (!row) {
|
|
1539
|
+
table.fields.forEach((f) => {
|
|
1540
|
+
pseudo_row[f.name] = undefined;
|
|
1541
|
+
});
|
|
1542
|
+
}
|
|
1543
|
+
const appState = getState();
|
|
1544
|
+
const __ = db.is_node && appState
|
|
1545
|
+
? (s) => appState.i18n.__({ phrase: s, locale: req.getLocale() }) || s
|
|
1546
|
+
: (s) => {
|
|
1547
|
+
return s;
|
|
1548
|
+
};
|
|
1549
|
+
await traverse(form.layout, {
|
|
1550
|
+
container(segment) {
|
|
1551
|
+
if (segment.click_action) {
|
|
1552
|
+
segment.url = `javascript:view_post(this, 'run_action', {click_action: '${segment.click_action}', ...get_form_record(this) })`;
|
|
1553
|
+
}
|
|
1554
|
+
},
|
|
1555
|
+
async action(segment) {
|
|
1556
|
+
if (segment.action_style === "on_page_load") {
|
|
1557
|
+
segment.type = "blank";
|
|
1558
|
+
segment.style = {};
|
|
1559
|
+
if (segment.minRole && segment.minRole != 100) {
|
|
1560
|
+
const minRole = +segment.minRole;
|
|
1561
|
+
const userRole = req?.user?.role_id || 100;
|
|
1562
|
+
if (minRole < userRole)
|
|
1563
|
+
return;
|
|
1564
|
+
}
|
|
1565
|
+
if (req.method === "POST")
|
|
1566
|
+
return;
|
|
1567
|
+
//run action
|
|
1568
|
+
try {
|
|
1569
|
+
const actionResult = await (0, plugin_helper_1.run_action_column)({
|
|
1570
|
+
col: { ...segment },
|
|
1571
|
+
referrer: req?.get?.("Referrer"),
|
|
1572
|
+
req,
|
|
1573
|
+
res,
|
|
1574
|
+
table,
|
|
1575
|
+
row: row || pseudo_row,
|
|
1576
|
+
});
|
|
1577
|
+
if (actionResult)
|
|
1578
|
+
segment.contents = script(domReady(`common_done(${JSON.stringify(actionResult)}, "${viewname}")`));
|
|
1579
|
+
}
|
|
1580
|
+
catch (e) {
|
|
1581
|
+
const err = e;
|
|
1582
|
+
appState.log(5, `Error in Edit ${viewname} on page load action: ${err.message}`);
|
|
1583
|
+
err.message = `Error in evaluating Run on Page Load action in view ${viewname}: ${err.message}`;
|
|
1584
|
+
throw err;
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
if (segment.action_name === "Delete") {
|
|
1588
|
+
if (form.values && form.values[table.pk_name]) {
|
|
1589
|
+
segment.action_url = table.delete_url(form.values);
|
|
1590
|
+
}
|
|
1591
|
+
else {
|
|
1592
|
+
segment.type = "blank";
|
|
1593
|
+
segment.contents = "";
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
else if (segment.action_name === "form_action" &&
|
|
1597
|
+
segment.configuration?.form_action === "Save" &&
|
|
1598
|
+
table.fields.some((f) => f.type === "File")) {
|
|
1599
|
+
let url = action_url(viewname, table, segment.action_name, row || pseudo_row, segment.rndid, "rndid", segment.confirm);
|
|
1600
|
+
if (typeof url !== "string" && url.javascript) {
|
|
1601
|
+
//redo to include dynamic row
|
|
1602
|
+
const confirmStr = segment.confirm
|
|
1603
|
+
? `if(confirm('Are you sure?'))`
|
|
1604
|
+
: "";
|
|
1605
|
+
url.javascript = `${confirmStr}view_post(this, 'run_action', get_form_data(this, '${segment.rndid}') );`;
|
|
1606
|
+
}
|
|
1607
|
+
segment.action_link = action_link(url, req, segment, __);
|
|
1608
|
+
}
|
|
1609
|
+
else if (!["Sign up", ...edit_build_in_actions].includes(segment.action_name) &&
|
|
1610
|
+
!segment.action_name.startsWith("Login")) {
|
|
1611
|
+
let url = action_url(viewname, table, segment.action_name, row || pseudo_row, segment.rndid, "rndid", segment.confirm, undefined, segment.run_async);
|
|
1612
|
+
if (typeof url !== "string" && url.javascript) {
|
|
1613
|
+
//redo to include dynamic row
|
|
1614
|
+
const confirmStr = segment.confirm
|
|
1615
|
+
? `if(confirm('Are you sure?'))`
|
|
1616
|
+
: "";
|
|
1617
|
+
// If this is a Multi-step action or the form/table contains File fields,
|
|
1618
|
+
// post multipart FormData so req.files is populated server-side.
|
|
1619
|
+
const hasFileFields = table.fields?.some((f) => f.type === "File");
|
|
1620
|
+
if (segment.action_name === "Multi-step action" || hasFileFields) {
|
|
1621
|
+
url.javascript = `${confirmStr}view_post(this, 'run_action', get_form_data(this, '${segment.rndid}') );`;
|
|
1622
|
+
}
|
|
1623
|
+
else {
|
|
1624
|
+
url.javascript = `${confirmStr}view_post(this, 'run_action', {rndid:'${segment.rndid}', ...get_form_record(this)});`;
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
segment.action_link = action_link(url, req, segment, __);
|
|
1628
|
+
}
|
|
1629
|
+
},
|
|
1630
|
+
join_field(segment) {
|
|
1631
|
+
const qs = objToQueryString(segment.configuration);
|
|
1632
|
+
segment.sourceURL = `/field/show-calculated/${table.name}/${segment.join_field}/${segment.fieldview}?${qs}`;
|
|
1633
|
+
},
|
|
1634
|
+
tabs(segment) {
|
|
1635
|
+
const to_delete = new Set();
|
|
1636
|
+
(segment.showif || []).forEach((sif, ix) => {
|
|
1637
|
+
if (sif) {
|
|
1638
|
+
const showit = eval_expression(sif, row || pseudo_row, req.user, "Tab show if formula");
|
|
1639
|
+
if (!showit)
|
|
1640
|
+
to_delete.add(ix);
|
|
1641
|
+
}
|
|
1642
|
+
});
|
|
1643
|
+
segment.titles = segment.titles.filter((_v, ix) => !to_delete.has(ix));
|
|
1644
|
+
segment.contents = segment.contents.filter((_v, ix) => !to_delete.has(ix));
|
|
1645
|
+
(segment.titles || []).forEach((t, ix) => {
|
|
1646
|
+
if (typeof t === "string" && t.includes("{{")) {
|
|
1647
|
+
segment.titles[ix] = interpolate(t, row, req.user, "Tab titles");
|
|
1648
|
+
}
|
|
1649
|
+
});
|
|
1650
|
+
},
|
|
1651
|
+
view_link(segment) {
|
|
1652
|
+
segment.type = "blank";
|
|
1653
|
+
const view_select = parse_view_select(segment.view);
|
|
1654
|
+
if (!row && view_select.type !== "Independent") {
|
|
1655
|
+
segment.contents = "";
|
|
1656
|
+
}
|
|
1657
|
+
else {
|
|
1658
|
+
const prefix = req.generate_email && req.get_base_url ? req.get_base_url() : "";
|
|
1659
|
+
const { key } = view_linker(segment, table.fields, (s) => s, isWeb(req), req.user, prefix, req.query, req, viewname);
|
|
1660
|
+
segment.contents = key(row || {});
|
|
1661
|
+
}
|
|
1662
|
+
},
|
|
1663
|
+
async view(segment) {
|
|
1664
|
+
//console.log(segment);
|
|
1665
|
+
const view_select = parse_view_select(segment.view, segment.relation);
|
|
1666
|
+
//console.log({ view_select });
|
|
1667
|
+
const view = view_1.default.findOne({ name: view_select.viewname });
|
|
1668
|
+
if (!view)
|
|
1669
|
+
throw new InvalidConfiguration(`Cannot find embedded view: ${view_select.viewname}`);
|
|
1670
|
+
// check if the relation path matches a ChildList relations
|
|
1671
|
+
let childListRelPath = false;
|
|
1672
|
+
if (segment.relation && view.table_id) {
|
|
1673
|
+
const targetTbl = table_1.default.findOne({ id: view.table_id });
|
|
1674
|
+
const relation = new Relation(segment.relation, targetTbl.name, (0, plugin_helper_1.displayType)(await view.get_state_fields()));
|
|
1675
|
+
childListRelPath = relation.type === RelationType.CHILD_LIST;
|
|
1676
|
+
}
|
|
1677
|
+
// Edit-in-edit
|
|
1678
|
+
if (view.viewtemplate === "Edit" &&
|
|
1679
|
+
(view_select.type === "ChildList" || childListRelPath)) {
|
|
1680
|
+
if (childListRelPath)
|
|
1681
|
+
updateViewSelect(view_select);
|
|
1682
|
+
const childTable = table_1.default.findOne({ id: view.table_id });
|
|
1683
|
+
const childForm = await getForm(childTable, view.name, view.configuration.columns, view.configuration.layout, row?.id, req, !isWeb(req));
|
|
1684
|
+
traverseSync(childForm.layout, {
|
|
1685
|
+
field(segment) {
|
|
1686
|
+
segment.field_name = `${view_select.field_name}.${segment.field_name}`;
|
|
1687
|
+
},
|
|
1688
|
+
});
|
|
1689
|
+
for (const field of childForm.fields) {
|
|
1690
|
+
if (field.name === childTable.pk_name) {
|
|
1691
|
+
field.class = field.class
|
|
1692
|
+
? `${field.class} omit-repeater-clone`
|
|
1693
|
+
: "omit-repeater-clone";
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1696
|
+
await childForm.fill_fkey_options(false, optionsQuery, req.user);
|
|
1697
|
+
const fr = new FieldRepeat({
|
|
1698
|
+
name: view_select.field_name,
|
|
1699
|
+
label: view_select.field_name,
|
|
1700
|
+
fields: childForm.fields,
|
|
1701
|
+
layout: childForm.layout,
|
|
1702
|
+
metadata: {
|
|
1703
|
+
table_id: childTable.id,
|
|
1704
|
+
view: segment.view,
|
|
1705
|
+
relation: view_select.field_name,
|
|
1706
|
+
relation_path: segment.relation,
|
|
1707
|
+
order_field: segment.order_field,
|
|
1708
|
+
},
|
|
1709
|
+
});
|
|
1710
|
+
if (row?.id) {
|
|
1711
|
+
const childRows = getRowQuery
|
|
1712
|
+
? await getRowQuery(view.table_id, view_select, row.id, segment.order_field)
|
|
1713
|
+
: await childTable.getRows({
|
|
1714
|
+
[view_select.field_name]: row.id,
|
|
1715
|
+
}, segment.order_field ? { orderBy: segment.order_field } : {});
|
|
1716
|
+
fr.metadata.rows = childRows;
|
|
1717
|
+
if (!fr.fields.map((f) => f.name).includes(childTable.pk_name))
|
|
1718
|
+
fr.fields.push({
|
|
1719
|
+
name: childTable.pk_name,
|
|
1720
|
+
input_type: "hidden",
|
|
1721
|
+
});
|
|
1722
|
+
}
|
|
1723
|
+
form.fields.push(fr);
|
|
1724
|
+
segment.type = "field_repeat";
|
|
1725
|
+
segment.field_repeat = fr;
|
|
1726
|
+
return;
|
|
1727
|
+
} // end edit in edit
|
|
1728
|
+
const outerState = {};
|
|
1729
|
+
Object.entries(originalState || {}).forEach(([k, v]) => {
|
|
1730
|
+
if (k.startsWith("_"))
|
|
1731
|
+
outerState[k] = v;
|
|
1732
|
+
});
|
|
1733
|
+
let state = {};
|
|
1734
|
+
let urlFormula;
|
|
1735
|
+
let needFields = new Set();
|
|
1736
|
+
if (view_select.type === "RelationPath" && view.table_id) {
|
|
1737
|
+
const pathToUrlFormula = (relation) => {
|
|
1738
|
+
const st = (0, plugin_helper_1.pathToState)(relation, (k) => `row.` + k);
|
|
1739
|
+
return Object.entries(st)
|
|
1740
|
+
.map(([k, v]) => {
|
|
1741
|
+
needFields.add(v.split(".")[1]);
|
|
1742
|
+
return `${k}='+${v}+'`;
|
|
1743
|
+
})
|
|
1744
|
+
.join("&");
|
|
1745
|
+
};
|
|
1746
|
+
const targetTbl = table_1.default.findOne({ id: view.table_id });
|
|
1747
|
+
if (targetTbl) {
|
|
1748
|
+
const relation = new Relation(segment.relation, targetTbl.name, (0, plugin_helper_1.displayType)(await view.get_state_fields()));
|
|
1749
|
+
const relFmlQS = pathToUrlFormula(relation);
|
|
1750
|
+
const type = relation.type;
|
|
1751
|
+
if (!row && type == RelationType.OWN) {
|
|
1752
|
+
segment.type = "blank";
|
|
1753
|
+
urlFormula = `add_extra_state('/view/${view.name}/?${relFmlQS}', ${JSON.stringify(segment.extra_state_fml)}, row, ${JSON.stringify(outerState)})`;
|
|
1754
|
+
segment.contents = segment.contents = div({
|
|
1755
|
+
class: "d-inline",
|
|
1756
|
+
"data-sc-embed-viewname": view.name,
|
|
1757
|
+
"data-view-source-need-fields": [...needFields].join(","),
|
|
1758
|
+
"data-view-source": encodeURIComponent(urlFormula),
|
|
1759
|
+
});
|
|
1760
|
+
return;
|
|
1761
|
+
}
|
|
1762
|
+
else if (!row &&
|
|
1763
|
+
type !== RelationType.INDEPENDENT &&
|
|
1764
|
+
!relation.isFixedRelation()) {
|
|
1765
|
+
urlFormula = `add_extra_state('/view/${view.name}/?${relFmlQS}', ${JSON.stringify(segment.extra_state_fml)}, row, ${JSON.stringify(outerState)})`;
|
|
1766
|
+
segment.contents = segment.contents = div({
|
|
1767
|
+
class: "d-inline",
|
|
1768
|
+
"data-sc-embed-viewname": view.name,
|
|
1769
|
+
"data-view-source-need-fields": [...needFields].join(","),
|
|
1770
|
+
"data-view-source": encodeURIComponent(urlFormula),
|
|
1771
|
+
});
|
|
1772
|
+
return;
|
|
1773
|
+
}
|
|
1774
|
+
const userId = req?.user?.id;
|
|
1775
|
+
state = (0, plugin_helper_1.pathToState)(relation, relation.isFixedRelation() ? () => userId : (k) => row[k]);
|
|
1776
|
+
urlFormula = `add_extra_state('/view/${view.name}?${relFmlQS}', ${JSON.stringify(segment.extra_state_fml)}, row, ${JSON.stringify(outerState)})`;
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1779
|
+
else {
|
|
1780
|
+
const isIndependent = view_select.type === "Independent";
|
|
1781
|
+
// legacy none check ?
|
|
1782
|
+
if (!view)
|
|
1783
|
+
throw new InvalidConfiguration(`Edit view incorrectly configured: cannot find embedded view ${view_select.viewname}`);
|
|
1784
|
+
switch (view_select.type) {
|
|
1785
|
+
case "Own":
|
|
1786
|
+
state = { id: row?.id };
|
|
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 "Independent":
|
|
1791
|
+
state = {};
|
|
1792
|
+
urlFormula = `add_extra_state('/view/${view.name}/?id='+row.id, ${JSON.stringify(segment.extra_state_fml)}, row, ${JSON.stringify(outerState)})`;
|
|
1793
|
+
needFields.add("id");
|
|
1794
|
+
break;
|
|
1795
|
+
case "ChildList":
|
|
1796
|
+
case "OneToOneShow":
|
|
1797
|
+
state = { [view_select.field_name]: row?.id };
|
|
1798
|
+
urlFormula = `add_extra_state('/view/${view.name}/?${view_select.field_name}='+row.id, ${JSON.stringify(segment.extra_state_fml)}, row, ${JSON.stringify(outerState)})`;
|
|
1799
|
+
needFields.add("id");
|
|
1800
|
+
break;
|
|
1801
|
+
case "ParentShow":
|
|
1802
|
+
state = { id: row?.[view_select.field_name] };
|
|
1803
|
+
urlFormula = `add_extra_state('/view/${view.name}/?id='+row.${view_select.field_name}, ${JSON.stringify(segment.extra_state_fml)}, row, ${JSON.stringify(outerState)})`;
|
|
1804
|
+
needFields.add(view_select.field_name);
|
|
1805
|
+
break;
|
|
1806
|
+
}
|
|
1807
|
+
if (!row && !isIndependent) {
|
|
1808
|
+
segment.type = "blank";
|
|
1809
|
+
segment.contents = div({
|
|
1810
|
+
class: "d-inline",
|
|
1811
|
+
"data-sc-embed-viewname": view.name,
|
|
1812
|
+
"data-view-source-need-fields": [...needFields].join(","),
|
|
1813
|
+
"data-view-source": encodeURIComponent(urlFormula),
|
|
1814
|
+
});
|
|
1815
|
+
return;
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1818
|
+
const extra_state = segment.extra_state_fml
|
|
1819
|
+
? eval_expression(segment.extra_state_fml, {
|
|
1820
|
+
...dollarizeObject(req.query),
|
|
1821
|
+
session_id: getSessionId(req),
|
|
1822
|
+
...(row || pseudo_row),
|
|
1823
|
+
}, req.user, `Extra state formula for embedding view ${view.name}`)
|
|
1824
|
+
: {};
|
|
1825
|
+
const qs = (0, plugin_helper_1.stateToQueryString)({ ...state, ...outerState, ...extra_state }, true);
|
|
1826
|
+
segment.contents = div({
|
|
1827
|
+
class: "d-inline",
|
|
1828
|
+
"data-sc-embed-viewname": view.name,
|
|
1829
|
+
"data-sc-view-source": `/view/${view.name}${qs}`,
|
|
1830
|
+
"data-view-source-current": `/view/${view.name}${qs}`,
|
|
1831
|
+
"data-view-source-need-fields": [...needFields].join(","),
|
|
1832
|
+
"data-view-source": encodeURIComponent(urlFormula),
|
|
1833
|
+
}, view.renderLocally()
|
|
1834
|
+
? await view.run({ ...state, ...outerState, ...extra_state }, { req, res }, view.isRemoteTable())
|
|
1835
|
+
: await renderServerSide(view.name, {
|
|
1836
|
+
...state,
|
|
1837
|
+
...outerState,
|
|
1838
|
+
...extra_state,
|
|
1839
|
+
}));
|
|
1840
|
+
},
|
|
1841
|
+
});
|
|
1842
|
+
translateLayout(form.layout, req.getLocale());
|
|
1843
|
+
if (req.headers?.saltcornmodalrequest)
|
|
1844
|
+
form.xhrSubmit = true;
|
|
1845
|
+
setDateLocales(form, req.getLocale());
|
|
1846
|
+
};
|
|
1847
|
+
exports.transformForm = transformForm;
|
|
1848
|
+
const setDateLocales = (form, locale) => {
|
|
1849
|
+
form.fields.forEach((f) => {
|
|
1850
|
+
const ftype = f.type;
|
|
1851
|
+
if (ftype && ftype.name === "Date") {
|
|
1852
|
+
f.attributes.locale = locale;
|
|
1853
|
+
}
|
|
1854
|
+
});
|
|
1855
|
+
};
|
|
1856
|
+
exports.setDateLocales = setDateLocales;
|
|
1857
|
+
/**
|
|
1858
|
+
* update viewSelect so that it looks like a normal ChildList
|
|
1859
|
+
*/
|
|
1860
|
+
const updateViewSelect = (viewSelect) => {
|
|
1861
|
+
if (viewSelect.path.length === 1) {
|
|
1862
|
+
viewSelect.field_name = viewSelect.path[0].inboundKey;
|
|
1863
|
+
viewSelect.table_name = viewSelect.path[0].table;
|
|
1864
|
+
}
|
|
1865
|
+
else if (viewSelect.path.length === 2) {
|
|
1866
|
+
viewSelect.field_name = viewSelect.path[1].inboundKey;
|
|
1867
|
+
viewSelect.table_name = viewSelect.path[1].table;
|
|
1868
|
+
viewSelect.throughTable = viewSelect.path[0].inboundKey;
|
|
1869
|
+
viewSelect.through = viewSelect.path[0].table;
|
|
1870
|
+
}
|
|
1871
|
+
};
|
|
1872
|
+
exports.updateViewSelect = updateViewSelect;
|
|
1493
1873
|
/**
|
|
1494
1874
|
* @param {object} table
|
|
1495
1875
|
* @param {object} req
|
|
@@ -1528,9 +1908,11 @@ const fill_presets = async (table, req, fixed) => {
|
|
|
1528
1908
|
});
|
|
1529
1909
|
return fixed;
|
|
1530
1910
|
};
|
|
1911
|
+
exports.fill_presets = fill_presets;
|
|
1531
1912
|
const objToQueryString = (o) => Object.entries(o || {})
|
|
1532
1913
|
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
|
|
1533
1914
|
.join("&");
|
|
1915
|
+
exports.objToQueryString = objToQueryString;
|
|
1534
1916
|
// edit template build in actions
|
|
1535
1917
|
const edit_build_in_actions = [
|
|
1536
1918
|
"Save",
|
|
@@ -1542,21 +1924,5 @@ const edit_build_in_actions = [
|
|
|
1542
1924
|
"Delete",
|
|
1543
1925
|
"Cancel",
|
|
1544
1926
|
];
|
|
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
|
-
};
|
|
1927
|
+
exports.edit_build_in_actions = edit_build_in_actions;
|
|
1562
1928
|
//# sourceMappingURL=viewable_fields.js.map
|