@saltcorn/data 0.6.1-beta.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/base-plugin/actions.js +172 -1
- package/base-plugin/fieldviews.js +63 -0
- package/base-plugin/fileviews.js +41 -0
- package/base-plugin/index.js +35 -0
- package/base-plugin/types.js +345 -9
- package/base-plugin/viewtemplates/edit.js +107 -0
- package/base-plugin/viewtemplates/feed.js +46 -0
- package/base-plugin/viewtemplates/filter.js +43 -0
- package/base-plugin/viewtemplates/list.js +73 -1
- package/base-plugin/viewtemplates/listshowlist.js +54 -3
- package/base-plugin/viewtemplates/room.js +100 -0
- package/base-plugin/viewtemplates/show.js +86 -0
- package/base-plugin/viewtemplates/viewable_fields.js +124 -0
- package/contracts.js +58 -0
- package/db/connect.js +13 -5
- package/db/db.test.js +0 -154
- package/db/fixtures.js +13 -1
- package/db/index.js +42 -3
- package/db/reset_schema.js +11 -0
- package/db/state.js +105 -36
- package/index.js +13 -0
- package/migrate.js +4 -1
- package/models/backup.js +78 -0
- package/models/config.js +113 -22
- package/models/crash.js +44 -0
- package/models/discovery.js +13 -11
- package/models/email.js +17 -0
- package/models/eventlog.js +51 -0
- package/models/expression.js +49 -1
- package/models/field.js +88 -9
- package/models/fieldrepeat.js +33 -0
- package/models/file.js +23 -4
- package/models/form.js +34 -0
- package/models/index.js +42 -0
- package/models/layout.js +33 -0
- package/models/library.js +44 -0
- package/models/pack.js +88 -0
- package/models/page.js +13 -3
- package/models/plugin.js +9 -2
- package/models/random.js +36 -0
- package/models/role.js +36 -0
- package/models/scheduler.js +28 -0
- package/models/table.js +34 -15
- package/models/table_constraints.js +44 -0
- package/models/tenant.js +46 -9
- package/models/trigger.js +24 -11
- package/models/user.js +33 -8
- package/models/view.js +89 -8
- package/models/workflow.js +31 -0
- package/package.json +7 -5
- package/plugin-helper.js +102 -44
- package/plugin-testing.js +4 -0
- package/tests/exact_views.test.js +5 -5
- package/utils.js +4 -0
- package/db/internal.js +0 -229
- package/db/multi-tenant.js +0 -24
- package/db/pg.js +0 -374
- package/db/single-tenant.js +0 -8
- package/db/sqlite.js +0 -280
- package/db/tenants.js +0 -6
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @category saltcorn-data
|
|
3
|
+
* @module base-plugin/viewtemplates/room
|
|
4
|
+
* @subcategory base-plugin
|
|
5
|
+
*/
|
|
1
6
|
const Field = require("../../models/field");
|
|
2
7
|
const Table = require("../../models/table");
|
|
3
8
|
const Form = require("../../models/form");
|
|
@@ -30,6 +35,11 @@ const { getState } = require("../../db/state");
|
|
|
30
35
|
const db = require("../../db");
|
|
31
36
|
const { getForm, fill_presets } = require("./viewable_fields");
|
|
32
37
|
|
|
38
|
+
/**
|
|
39
|
+
*
|
|
40
|
+
* @param {object} req
|
|
41
|
+
* @returns {Workflow}
|
|
42
|
+
*/
|
|
33
43
|
const configuration_workflow = (req) =>
|
|
34
44
|
new Workflow({
|
|
35
45
|
steps: [
|
|
@@ -160,6 +170,9 @@ const configuration_workflow = (req) =>
|
|
|
160
170
|
],
|
|
161
171
|
});
|
|
162
172
|
|
|
173
|
+
/**
|
|
174
|
+
* @returns {object[]}
|
|
175
|
+
*/
|
|
163
176
|
const get_state_fields = () => [
|
|
164
177
|
{
|
|
165
178
|
name: "id",
|
|
@@ -170,6 +183,23 @@ const get_state_fields = () => [
|
|
|
170
183
|
];
|
|
171
184
|
const limit = 10;
|
|
172
185
|
|
|
186
|
+
/**
|
|
187
|
+
* @param {string} table_id
|
|
188
|
+
* @param {string} viewname
|
|
189
|
+
* @param {object} optsOne
|
|
190
|
+
* @param {string} optsOne.participant_field,
|
|
191
|
+
* @param {string} optsOne.msg_relation
|
|
192
|
+
* @param {*} optsOne.msgsender_field
|
|
193
|
+
* @param {string} optsOne.msgview
|
|
194
|
+
* @param {string} optsOne.msgform
|
|
195
|
+
* @param {string} optsOne.participant_maxread_field
|
|
196
|
+
* @param {object} state
|
|
197
|
+
* @param {object} optsTwo
|
|
198
|
+
* @param {object} optsTwo.req
|
|
199
|
+
* @param {object} optsTwo.res
|
|
200
|
+
* @returns {Promise<div>}
|
|
201
|
+
* @throws {InvalidConfiguration}
|
|
202
|
+
*/
|
|
173
203
|
const run = async (
|
|
174
204
|
table_id,
|
|
175
205
|
viewname,
|
|
@@ -274,6 +304,18 @@ const run = async (
|
|
|
274
304
|
);
|
|
275
305
|
};
|
|
276
306
|
|
|
307
|
+
/**
|
|
308
|
+
* @param {*} table_id
|
|
309
|
+
* @param {*} viewname
|
|
310
|
+
* @param {object} optsOne
|
|
311
|
+
* @param {string} optsOne.participant_field
|
|
312
|
+
* @param {string} optsOne.participant_maxread_field
|
|
313
|
+
* @param {body} body
|
|
314
|
+
* @param {object} optsTwo
|
|
315
|
+
* @param {object} optsTwo.req
|
|
316
|
+
* @param {object} optsTwo.res
|
|
317
|
+
* @returns {Promise<void>}
|
|
318
|
+
*/
|
|
277
319
|
const ack_read = async (
|
|
278
320
|
table_id,
|
|
279
321
|
viewname,
|
|
@@ -321,6 +363,23 @@ const ack_read = async (
|
|
|
321
363
|
},
|
|
322
364
|
};
|
|
323
365
|
};
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* @param {*} table_id
|
|
369
|
+
* @param {*} viewname
|
|
370
|
+
* @param {object} optsOne.
|
|
371
|
+
* @param {string} optsOne.participant_field
|
|
372
|
+
* @param {string} optsOne.msg_relation
|
|
373
|
+
* @param {*} optsOne.msgsender_field
|
|
374
|
+
* @param {string} optsOne.msgview
|
|
375
|
+
* @param {*} optsOne.msgform
|
|
376
|
+
* @param {*} optsOne.participant_maxread_field
|
|
377
|
+
* @param {object} body
|
|
378
|
+
* @param {object} optsTwo
|
|
379
|
+
* @param {object} optsTwo.req
|
|
380
|
+
* @param {object} optsTwo.res
|
|
381
|
+
* @returns {Promise<object>}
|
|
382
|
+
*/
|
|
324
383
|
const fetch_older_msg = async (
|
|
325
384
|
table_id,
|
|
326
385
|
viewname,
|
|
@@ -384,6 +443,23 @@ const fetch_older_msg = async (
|
|
|
384
443
|
},
|
|
385
444
|
};
|
|
386
445
|
};
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* @param {*} table_id
|
|
449
|
+
* @param {string} viewname
|
|
450
|
+
* @param {object} optsOne
|
|
451
|
+
* @param {string} optsOne.participant_field
|
|
452
|
+
* @param {string} optsOne.msg_relation
|
|
453
|
+
* @param {*} optsOne.msgsender_field
|
|
454
|
+
* @param {string} optsOne.msgview
|
|
455
|
+
* @param {string} optsOne.msgform
|
|
456
|
+
* @param {string} optsOne.participant_maxread_field
|
|
457
|
+
* @param {*} body
|
|
458
|
+
* @param {object} optsTwo
|
|
459
|
+
* @param {object} optsTwo.req
|
|
460
|
+
* @param {object} optsTwo.res
|
|
461
|
+
* @returns {Promise<object>}
|
|
462
|
+
*/
|
|
387
463
|
const submit_msg_ajax = async (
|
|
388
464
|
table_id,
|
|
389
465
|
viewname,
|
|
@@ -472,6 +548,18 @@ const submit_msg_ajax = async (
|
|
|
472
548
|
}
|
|
473
549
|
};
|
|
474
550
|
|
|
551
|
+
/**
|
|
552
|
+
* @param {*} table_id
|
|
553
|
+
* @param {string} viewname
|
|
554
|
+
* @param {object} opts
|
|
555
|
+
* @param {*} opts.participant_field
|
|
556
|
+
* @param {string} opts.msg_relation,
|
|
557
|
+
* @param {string} opts.msgsender_field,
|
|
558
|
+
* @param {string} opts.msgview,
|
|
559
|
+
* @param {*} opts.msgform,
|
|
560
|
+
* @param {*} opts.participant_maxread_field,
|
|
561
|
+
* @returns {object[]}
|
|
562
|
+
*/
|
|
475
563
|
const virtual_triggers = (
|
|
476
564
|
table_id,
|
|
477
565
|
viewname,
|
|
@@ -514,14 +602,25 @@ const virtual_triggers = (
|
|
|
514
602
|
];
|
|
515
603
|
};
|
|
516
604
|
module.exports = {
|
|
605
|
+
/** @type {string} */
|
|
517
606
|
name: "Room",
|
|
607
|
+
/** @type {string} */
|
|
518
608
|
description: "Real-time space for chat",
|
|
519
609
|
configuration_workflow,
|
|
520
610
|
run,
|
|
521
611
|
get_state_fields,
|
|
612
|
+
/** @type {boolean} */
|
|
522
613
|
display_state_form: false,
|
|
523
614
|
routes: { submit_msg_ajax, ack_read, fetch_older_msg },
|
|
615
|
+
/** @type {boolean} */
|
|
524
616
|
noAutoTest: true,
|
|
617
|
+
/**
|
|
618
|
+
* @param {object} opts
|
|
619
|
+
* @param {object} opts.participant_field
|
|
620
|
+
* @param {string} room_id
|
|
621
|
+
* @param {object} user
|
|
622
|
+
* @returns {Promise<object>}
|
|
623
|
+
*/
|
|
525
624
|
authorize_join: async ({ participant_field }, room_id, user) => {
|
|
526
625
|
if (!user) return false;
|
|
527
626
|
const [
|
|
@@ -539,6 +638,7 @@ module.exports = {
|
|
|
539
638
|
return !!partRow;
|
|
540
639
|
},
|
|
541
640
|
virtual_triggers,
|
|
641
|
+
/** @returns {object[]} */
|
|
542
642
|
getStringsForI18n() {
|
|
543
643
|
return [];
|
|
544
644
|
},
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @category saltcorn-data
|
|
3
|
+
* @module base-plugin/viewtemplates/show
|
|
4
|
+
* @subcategory base-plugin
|
|
5
|
+
*/
|
|
1
6
|
const Form = require("../../models/form");
|
|
2
7
|
const User = require("../../models/user");
|
|
3
8
|
const Field = require("../../models/field");
|
|
@@ -49,6 +54,10 @@ const { get_expression_function } = require("../../models/expression");
|
|
|
49
54
|
const { get_base_url } = require("../../models/config");
|
|
50
55
|
const Library = require("../../models/library");
|
|
51
56
|
|
|
57
|
+
/**
|
|
58
|
+
* @param {object} req
|
|
59
|
+
* @returns {Workflow}
|
|
60
|
+
*/
|
|
52
61
|
const configuration_workflow = (req) =>
|
|
53
62
|
new Workflow({
|
|
54
63
|
steps: [
|
|
@@ -181,6 +190,10 @@ const configuration_workflow = (req) =>
|
|
|
181
190
|
},
|
|
182
191
|
],
|
|
183
192
|
});
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* @returns {object[]}
|
|
196
|
+
*/
|
|
184
197
|
const get_state_fields = () => [
|
|
185
198
|
{
|
|
186
199
|
name: "id",
|
|
@@ -190,8 +203,21 @@ const get_state_fields = () => [
|
|
|
190
203
|
},
|
|
191
204
|
];
|
|
192
205
|
|
|
206
|
+
/** @type {function} */
|
|
193
207
|
const initial_config = initial_config_all_fields(false);
|
|
194
208
|
|
|
209
|
+
/**
|
|
210
|
+
* @param {string} table_id
|
|
211
|
+
* @param {string} viewname
|
|
212
|
+
* @param {object} opts
|
|
213
|
+
* @param {object[]} opts.columns
|
|
214
|
+
* @param {object} opts.layout
|
|
215
|
+
* @param {string} [opts.page_title]
|
|
216
|
+
* @param {boolean} opts.page_title_formula
|
|
217
|
+
* @param {object} state
|
|
218
|
+
* @param {object} extra
|
|
219
|
+
* @returns {Promise<string>}
|
|
220
|
+
*/
|
|
195
221
|
const run = async (
|
|
196
222
|
table_id,
|
|
197
223
|
viewname,
|
|
@@ -216,6 +242,7 @@ const run = async (
|
|
|
216
242
|
const { joinFields, aggregations } = picked_fields_to_query(columns, fields);
|
|
217
243
|
readState(state, fields);
|
|
218
244
|
const qstate = await stateFieldsToWhere({ fields, state, approximate: true });
|
|
245
|
+
if (Object.keys(qstate).length === 0) return extra.req.__("No row selected");
|
|
219
246
|
const rows = await tbl.getJoinedRows({
|
|
220
247
|
where: qstate,
|
|
221
248
|
joinFields,
|
|
@@ -268,6 +295,12 @@ const run = async (
|
|
|
268
295
|
return page_title_preamble + rendered;
|
|
269
296
|
};
|
|
270
297
|
|
|
298
|
+
/**
|
|
299
|
+
* @param {object} opts
|
|
300
|
+
* @param {object} opts.layout
|
|
301
|
+
* @param {object[]} opts.fields
|
|
302
|
+
* @returns {Promise<void>}
|
|
303
|
+
*/
|
|
271
304
|
const set_join_fieldviews = async ({ layout, fields }) => {
|
|
272
305
|
await traverse(layout, {
|
|
273
306
|
join_field: async (segment) => {
|
|
@@ -298,6 +331,16 @@ const set_join_fieldviews = async ({ layout, fields }) => {
|
|
|
298
331
|
});
|
|
299
332
|
};
|
|
300
333
|
|
|
334
|
+
/**
|
|
335
|
+
* @param {object} table
|
|
336
|
+
* @param {string} viewname
|
|
337
|
+
* @param {object} opts
|
|
338
|
+
* @param {object[]} opts.columns
|
|
339
|
+
* @param {object} opts.layout
|
|
340
|
+
* @param {object} extra
|
|
341
|
+
* @param {object[]} rows
|
|
342
|
+
* @returns {Promise<string>}
|
|
343
|
+
*/
|
|
301
344
|
const renderRows = async (
|
|
302
345
|
table,
|
|
303
346
|
viewname,
|
|
@@ -387,6 +430,16 @@ const renderRows = async (
|
|
|
387
430
|
});
|
|
388
431
|
};
|
|
389
432
|
|
|
433
|
+
/**
|
|
434
|
+
* @param {number} table_id
|
|
435
|
+
* @param {string} viewname
|
|
436
|
+
* @param {object} opts
|
|
437
|
+
* @param {object[]} opts.columns
|
|
438
|
+
* @param {object} opts.layout
|
|
439
|
+
* @param {object} state
|
|
440
|
+
* @param {object} extra
|
|
441
|
+
* @returns {Promise<object[]>}
|
|
442
|
+
*/
|
|
390
443
|
const runMany = async (
|
|
391
444
|
table_id,
|
|
392
445
|
viewname,
|
|
@@ -423,6 +476,18 @@ const runMany = async (
|
|
|
423
476
|
return rendered.map((html, ix) => ({ html, row: rows[ix] }));
|
|
424
477
|
};
|
|
425
478
|
|
|
479
|
+
/**
|
|
480
|
+
* @param {object} row
|
|
481
|
+
* @param {Field[]} fields
|
|
482
|
+
* @param {Layout} layout0
|
|
483
|
+
* @param {string} viewname
|
|
484
|
+
* @param {Table} table
|
|
485
|
+
* @param {Role} role
|
|
486
|
+
* @param {object} req
|
|
487
|
+
* @param {object} is_owner
|
|
488
|
+
* @throws {Error}
|
|
489
|
+
* @returns {Layout}
|
|
490
|
+
*/
|
|
426
491
|
const render = (row, fields, layout0, viewname, table, role, req, is_owner) => {
|
|
427
492
|
const evalMaybeExpr = (segment, key, fmlkey) => {
|
|
428
493
|
if (segment.isFormula && segment.isFormula[fmlkey || key]) {
|
|
@@ -560,6 +625,19 @@ const render = (row, fields, layout0, viewname, table, role, req, is_owner) => {
|
|
|
560
625
|
is_owner,
|
|
561
626
|
});
|
|
562
627
|
};
|
|
628
|
+
|
|
629
|
+
/**
|
|
630
|
+
* @param {number} table_id
|
|
631
|
+
* @param {*} viewname
|
|
632
|
+
* @param {object} opts
|
|
633
|
+
* @param {object[]} opts.columns
|
|
634
|
+
* @param {*} opts.layout
|
|
635
|
+
* @param {*} body
|
|
636
|
+
* @param {object} optsTwo
|
|
637
|
+
* @param {object} optsTwo.req
|
|
638
|
+
* @param {*} optsTwo.res
|
|
639
|
+
* @returns {Promise<object>}
|
|
640
|
+
*/
|
|
563
641
|
const run_action = async (
|
|
564
642
|
table_id,
|
|
565
643
|
viewname,
|
|
@@ -587,7 +665,9 @@ const run_action = async (
|
|
|
587
665
|
};
|
|
588
666
|
|
|
589
667
|
module.exports = {
|
|
668
|
+
/** @type {string} */
|
|
590
669
|
name: "Show",
|
|
670
|
+
/** @type {string} */
|
|
591
671
|
description: "Show a single row, with flexible layout",
|
|
592
672
|
get_state_fields,
|
|
593
673
|
configuration_workflow,
|
|
@@ -595,8 +675,14 @@ module.exports = {
|
|
|
595
675
|
runMany,
|
|
596
676
|
renderRows,
|
|
597
677
|
initial_config,
|
|
678
|
+
/** @type {boolean} */
|
|
598
679
|
display_state_form: false,
|
|
599
680
|
routes: { run_action },
|
|
681
|
+
/**
|
|
682
|
+
* @param {object} opts
|
|
683
|
+
* @param {object} opts.layout
|
|
684
|
+
* @returns {string[]}
|
|
685
|
+
*/
|
|
600
686
|
getStringsForI18n({ layout }) {
|
|
601
687
|
return getStringsForI18n(layout);
|
|
602
688
|
},
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @category saltcorn-data
|
|
3
|
+
* @module base-plugin/viewtemplates/viewable_fields
|
|
4
|
+
* @subcategory base-plugin
|
|
5
|
+
*/
|
|
1
6
|
const { post_btn, link } = require("@saltcorn/markup");
|
|
2
7
|
const { text, a, i } = require("@saltcorn/markup/tags");
|
|
3
8
|
const { getState } = require("../../db/state");
|
|
@@ -11,6 +16,16 @@ const { traverseSync } = require("../../models/layout");
|
|
|
11
16
|
const { structuredClone } = require("../../utils");
|
|
12
17
|
const db = require("../../db");
|
|
13
18
|
|
|
19
|
+
/**
|
|
20
|
+
* @function
|
|
21
|
+
* @param {string} viewname
|
|
22
|
+
* @param {Table|object} table
|
|
23
|
+
* @param {string} action_name
|
|
24
|
+
* @param {object} r
|
|
25
|
+
* @param {string} colId missing in contract
|
|
26
|
+
* @param {colIdNm} colIdNm missing in contract
|
|
27
|
+
* @returns {any}
|
|
28
|
+
*/
|
|
14
29
|
const action_url = contract(
|
|
15
30
|
is.fun([is.str, is_tablely, is.str, is.obj()], is.any),
|
|
16
31
|
(viewname, table, action_name, r, colId, colIdNm) => {
|
|
@@ -26,6 +41,23 @@ const action_url = contract(
|
|
|
26
41
|
}
|
|
27
42
|
);
|
|
28
43
|
|
|
44
|
+
/**
|
|
45
|
+
* @param {string} url
|
|
46
|
+
* @param {object} req
|
|
47
|
+
* @param {object} opts
|
|
48
|
+
* @param {string} opts.action_name
|
|
49
|
+
* @param {string} opts.action_label
|
|
50
|
+
* @param {*} opts.confirm
|
|
51
|
+
* @param {*} opts.rndid
|
|
52
|
+
* @param {string} opts.action_style
|
|
53
|
+
* @param {number} opts.action_size
|
|
54
|
+
* @param {*} opts.action_icon
|
|
55
|
+
* @param {string} opts.action_bgcol
|
|
56
|
+
* @param {string} opts.action_bordercol
|
|
57
|
+
* @param {string} opts.action_textcol
|
|
58
|
+
* @param {*} __
|
|
59
|
+
* @returns {object}
|
|
60
|
+
*/
|
|
29
61
|
const action_link = (
|
|
30
62
|
url,
|
|
31
63
|
req,
|
|
@@ -72,6 +104,12 @@ const action_link = (
|
|
|
72
104
|
btnClass: `${action_style || "btn-primary"} ${action_size || ""}`,
|
|
73
105
|
});
|
|
74
106
|
};
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @function
|
|
110
|
+
* @param {Field[]} fields
|
|
111
|
+
* @returns {function}
|
|
112
|
+
*/
|
|
75
113
|
const get_view_link_query = contract(
|
|
76
114
|
is.fun(is.array(is.class("Field")), is.fun(is.obj(), is.str)),
|
|
77
115
|
(fields) => {
|
|
@@ -91,6 +129,17 @@ const get_view_link_query = contract(
|
|
|
91
129
|
}
|
|
92
130
|
);
|
|
93
131
|
|
|
132
|
+
/**
|
|
133
|
+
* @function
|
|
134
|
+
* @param {object} opts
|
|
135
|
+
* @param {string} opts.link_text
|
|
136
|
+
* @param {boolean} opts.link_text_formula missing in contract
|
|
137
|
+
* @param {string} [opts.link_url]
|
|
138
|
+
* @param {boolean} opts.link_url_formula
|
|
139
|
+
* @param {boolean} opts.link_target_blank
|
|
140
|
+
* @param {Field[]} fields
|
|
141
|
+
* @returns {object}
|
|
142
|
+
*/
|
|
94
143
|
const make_link = contract(
|
|
95
144
|
is.fun(
|
|
96
145
|
[is.obj({ link_text: is.str }), is.array(is.class("Field"))],
|
|
@@ -123,6 +172,11 @@ const make_link = contract(
|
|
|
123
172
|
};
|
|
124
173
|
}
|
|
125
174
|
);
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* @param {string} s
|
|
178
|
+
* @returns {object}
|
|
179
|
+
*/
|
|
126
180
|
const parse_view_select = (s) => {
|
|
127
181
|
const colonSplit = s.split(":");
|
|
128
182
|
if (colonSplit.length === 1) return { type: "Own", viewname: s };
|
|
@@ -143,6 +197,23 @@ const parse_view_select = (s) => {
|
|
|
143
197
|
};
|
|
144
198
|
|
|
145
199
|
//todo: use above to simplify code
|
|
200
|
+
/**
|
|
201
|
+
* @function
|
|
202
|
+
* @param {object} opts
|
|
203
|
+
* @param {string} opts.view,
|
|
204
|
+
* @param {object} opts.view_label missing in contract
|
|
205
|
+
* @param {object} opts.in_modal
|
|
206
|
+
* @param {object} opts.view_label_formula
|
|
207
|
+
* @param {string} [opts.link_style = ""]
|
|
208
|
+
* @param {string} [opts.link_size = ""]
|
|
209
|
+
* @param {string} [opts.link_icon = ""]
|
|
210
|
+
* @param {string} [opts.textStyle = ""]
|
|
211
|
+
* @param {string} [opts.link_bgcol]
|
|
212
|
+
* @param {string} [opts.link_bordercol]
|
|
213
|
+
* @param {string} [opts.link_textcol]
|
|
214
|
+
* @param {Field[]} fields
|
|
215
|
+
* @returns {object}
|
|
216
|
+
*/
|
|
146
217
|
const view_linker = contract(
|
|
147
218
|
is.fun(
|
|
148
219
|
[is.obj({ view: is.str }), is.array(is.class("Field"))],
|
|
@@ -266,12 +337,27 @@ const view_linker = contract(
|
|
|
266
337
|
}
|
|
267
338
|
);
|
|
268
339
|
|
|
340
|
+
/**
|
|
341
|
+
* @param {string} nm
|
|
342
|
+
* @returns {boolean}
|
|
343
|
+
*/
|
|
269
344
|
const action_requires_write = (nm) => {
|
|
270
345
|
if (!nm) return false;
|
|
271
346
|
if (nm === "Delete") return true;
|
|
272
347
|
if (nm.startsWith("Toggle")) return true;
|
|
273
348
|
};
|
|
274
349
|
|
|
350
|
+
/**
|
|
351
|
+
* @function
|
|
352
|
+
* @param {string} viewname
|
|
353
|
+
* @param {Table|object} table
|
|
354
|
+
* @param {Fields[]} fields
|
|
355
|
+
* @param {object[]} columns
|
|
356
|
+
* @param {boolean} isShow
|
|
357
|
+
* @param {object} req
|
|
358
|
+
* @param {*} __
|
|
359
|
+
* @returns {object[]}
|
|
360
|
+
*/
|
|
275
361
|
const get_viewable_fields = contract(
|
|
276
362
|
is.fun(
|
|
277
363
|
[
|
|
@@ -439,6 +525,12 @@ const get_viewable_fields = contract(
|
|
|
439
525
|
})
|
|
440
526
|
.filter((v) => !!v)
|
|
441
527
|
);
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* @param {string} fname
|
|
531
|
+
* @param {object} req
|
|
532
|
+
* @returns {string}
|
|
533
|
+
*/
|
|
442
534
|
const sortlinkForName = (fname, req) => {
|
|
443
535
|
const { _sortby, _sortdesc } = req.query || {};
|
|
444
536
|
const desc =
|
|
@@ -449,6 +541,14 @@ const sortlinkForName = (fname, req) => {
|
|
|
449
541
|
: "true";
|
|
450
542
|
return `javascript:sortby('${text(fname)}', ${desc})`;
|
|
451
543
|
};
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* @param {object} column
|
|
547
|
+
* @param {object} f
|
|
548
|
+
* @param {object} req
|
|
549
|
+
* @param {*} __
|
|
550
|
+
* @returns {string}
|
|
551
|
+
*/
|
|
452
552
|
const headerLabelForName = (column, f, req, __) => {
|
|
453
553
|
const label = column.header_label
|
|
454
554
|
? text(__(column.header_label))
|
|
@@ -462,6 +562,14 @@ const headerLabelForName = (column, f, req, __) => {
|
|
|
462
562
|
: i({ class: "fas fa-caret-up" });
|
|
463
563
|
return label + arrow;
|
|
464
564
|
};
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* @function
|
|
568
|
+
* @param {Field[]} fields
|
|
569
|
+
* @param {object} state
|
|
570
|
+
* @param {boolean} [fuzzyStrings]
|
|
571
|
+
* @returns {object}
|
|
572
|
+
*/
|
|
465
573
|
const splitUniques = contract(
|
|
466
574
|
is.fun(
|
|
467
575
|
[is.array(is.class("Field")), is.obj(), is.maybe(is.bool)],
|
|
@@ -487,6 +595,16 @@ const splitUniques = contract(
|
|
|
487
595
|
return { uniques, nonUniques };
|
|
488
596
|
}
|
|
489
597
|
);
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
* @param {object} table
|
|
601
|
+
* @param {string} viewname
|
|
602
|
+
* @param {object[]} [columns]
|
|
603
|
+
* @param {object} layout0
|
|
604
|
+
* @param {boolean} id
|
|
605
|
+
* @param {object} req
|
|
606
|
+
* @returns {Promise<Form>}
|
|
607
|
+
*/
|
|
490
608
|
const getForm = async (table, viewname, columns, layout0, id, req) => {
|
|
491
609
|
const fields = await table.getFields();
|
|
492
610
|
|
|
@@ -556,6 +674,12 @@ const getForm = async (table, viewname, columns, layout0, id, req) => {
|
|
|
556
674
|
return form;
|
|
557
675
|
};
|
|
558
676
|
|
|
677
|
+
/**
|
|
678
|
+
* @param {object} table
|
|
679
|
+
* @param {object} req
|
|
680
|
+
* @param {object} fixed
|
|
681
|
+
* @returns {Promise<object>}
|
|
682
|
+
*/
|
|
559
683
|
const fill_presets = async (table, req, fixed) => {
|
|
560
684
|
const fields = await table.getFields();
|
|
561
685
|
Object.keys(fixed || {}).forEach((k) => {
|
package/contracts.js
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @category saltcorn-data
|
|
3
|
+
* @module contract
|
|
4
|
+
*/
|
|
1
5
|
const { contract, is } = require("contractis");
|
|
2
6
|
|
|
7
|
+
/**
|
|
8
|
+
* @type {function}
|
|
9
|
+
*/
|
|
3
10
|
const fieldlike = is.obj(
|
|
4
11
|
{
|
|
5
12
|
name: is.str,
|
|
@@ -9,8 +16,14 @@ const fieldlike = is.obj(
|
|
|
9
16
|
(o) => o.type || o.input_type
|
|
10
17
|
);
|
|
11
18
|
|
|
19
|
+
/**
|
|
20
|
+
* @type {function}
|
|
21
|
+
*/
|
|
12
22
|
const is_header = is.obj({ script: is.maybe(is.str) });
|
|
13
23
|
|
|
24
|
+
/**
|
|
25
|
+
* @type {function}
|
|
26
|
+
*/
|
|
14
27
|
const is_menu_item = is.obj({
|
|
15
28
|
label: is.str,
|
|
16
29
|
link: is.maybe(is.str),
|
|
@@ -24,6 +37,9 @@ const is_menu_item = is.obj({
|
|
|
24
37
|
),
|
|
25
38
|
});
|
|
26
39
|
|
|
40
|
+
/**
|
|
41
|
+
* @type {function}
|
|
42
|
+
*/
|
|
27
43
|
const is_layout_container = is.or(
|
|
28
44
|
is.eq(null),
|
|
29
45
|
is.obj({
|
|
@@ -34,6 +50,9 @@ const is_layout_container = is.or(
|
|
|
34
50
|
is.obj({})
|
|
35
51
|
);
|
|
36
52
|
|
|
53
|
+
/**
|
|
54
|
+
* @type {function}
|
|
55
|
+
*/
|
|
37
56
|
const is_layout = is.or(
|
|
38
57
|
is.obj(
|
|
39
58
|
{
|
|
@@ -61,6 +80,9 @@ const is_layout = is.or(
|
|
|
61
80
|
is.and(is_layout_container, is.obj({}))
|
|
62
81
|
);
|
|
63
82
|
|
|
83
|
+
/**
|
|
84
|
+
* @type {function}
|
|
85
|
+
*/
|
|
64
86
|
const is_plugin_wrap_arg = is.obj({
|
|
65
87
|
title: is.str,
|
|
66
88
|
body: is.or(is.str, is_layout),
|
|
@@ -81,6 +103,9 @@ const is_plugin_wrap_arg = is.obj({
|
|
|
81
103
|
headers: is.array(is_header),
|
|
82
104
|
});
|
|
83
105
|
|
|
106
|
+
/**
|
|
107
|
+
* @type {function}
|
|
108
|
+
*/
|
|
84
109
|
const is_plugin_authwrap_arg = is.obj({
|
|
85
110
|
title: is.str,
|
|
86
111
|
form: is.class("Form"),
|
|
@@ -106,8 +131,14 @@ const is_plugin_authwrap_arg = is.obj({
|
|
|
106
131
|
}),
|
|
107
132
|
});
|
|
108
133
|
|
|
134
|
+
/**
|
|
135
|
+
* @type {function}
|
|
136
|
+
*/
|
|
109
137
|
const is_plugin_wrap = is.fun(is_plugin_wrap_arg, is.str);
|
|
110
138
|
|
|
139
|
+
/**
|
|
140
|
+
* @type {function}
|
|
141
|
+
*/
|
|
111
142
|
const is_plugin_layout = is.obj({
|
|
112
143
|
wrap: is_plugin_wrap,
|
|
113
144
|
authWrap: is.maybe(is.fun(is_plugin_authwrap_arg, is.str)),
|
|
@@ -115,6 +146,9 @@ const is_plugin_layout = is.obj({
|
|
|
115
146
|
|
|
116
147
|
const is_attribute = is.obj({ name: is.str, type: is.str, required: is.bool });
|
|
117
148
|
|
|
149
|
+
/**
|
|
150
|
+
* @type {function}
|
|
151
|
+
*/
|
|
118
152
|
const is_plugin_type = is.obj({
|
|
119
153
|
name: is.str,
|
|
120
154
|
sql_name: is.str,
|
|
@@ -138,6 +172,9 @@ const is_plugin_type = is.obj({
|
|
|
138
172
|
presets: is.maybe(is.objVals(is.fun([], is.any))),
|
|
139
173
|
});
|
|
140
174
|
|
|
175
|
+
/**
|
|
176
|
+
* @type {function}
|
|
177
|
+
*/
|
|
141
178
|
const is_table_query = is.obj({
|
|
142
179
|
joinFields: is.maybe(is.objVals(is.obj({ ref: is.str, target: is.str }))),
|
|
143
180
|
aggregations: is.maybe(
|
|
@@ -157,6 +194,9 @@ const is_table_query = is.obj({
|
|
|
157
194
|
orderDesc: is.maybe(is.bool),
|
|
158
195
|
});
|
|
159
196
|
|
|
197
|
+
/**
|
|
198
|
+
* @type {function}
|
|
199
|
+
*/
|
|
160
200
|
const is_viewtemplate = is.obj({
|
|
161
201
|
name: is.str,
|
|
162
202
|
get_state_fields: is.maybe(
|
|
@@ -183,8 +223,16 @@ const is_plugin_function = is.obj({
|
|
|
183
223
|
isAsync: is.maybe(is.bool),
|
|
184
224
|
});
|
|
185
225
|
|
|
226
|
+
/**
|
|
227
|
+
*
|
|
228
|
+
* @param {*} a
|
|
229
|
+
* @returns {function}
|
|
230
|
+
*/
|
|
186
231
|
const is_maybe_cfg_fun = (a) => is.or(is.fun(is.obj, a), a, is.undefined);
|
|
187
232
|
|
|
233
|
+
/**
|
|
234
|
+
* @type {function}
|
|
235
|
+
*/
|
|
188
236
|
const is_plugin = is.obj({
|
|
189
237
|
sc_plugin_api_version: is.posint,
|
|
190
238
|
headers: is_maybe_cfg_fun(is.array(is_header)),
|
|
@@ -217,6 +265,9 @@ const is_plugin = is.obj({
|
|
|
217
265
|
dependencies: is.maybe(is.array(is.str)),
|
|
218
266
|
});
|
|
219
267
|
|
|
268
|
+
/**
|
|
269
|
+
* @type {function}
|
|
270
|
+
*/
|
|
220
271
|
const is_pack = is.obj({
|
|
221
272
|
tables: is.array(is.obj({ name: is.str, fields: is.array(fieldlike) })),
|
|
222
273
|
views: is.array(
|
|
@@ -224,6 +275,10 @@ const is_pack = is.obj({
|
|
|
224
275
|
),
|
|
225
276
|
plugins: is.array(is.obj({ name: is.str, source: is.str, location: is.str })),
|
|
226
277
|
});
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* @type {function}
|
|
281
|
+
*/
|
|
227
282
|
const is_column = is.obj({
|
|
228
283
|
type: is.one_of([
|
|
229
284
|
"Action",
|
|
@@ -235,6 +290,9 @@ const is_column = is.obj({
|
|
|
235
290
|
]),
|
|
236
291
|
});
|
|
237
292
|
|
|
293
|
+
/**
|
|
294
|
+
* @type {function}
|
|
295
|
+
*/
|
|
238
296
|
const is_tablely = is.or(is.class("Table"), is.obj({ external: is.eq(true) }));
|
|
239
297
|
|
|
240
298
|
module.exports = {
|