@saltcorn/server 1.1.1-rc.3 → 1.1.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/locales/en.json +2 -1
- package/locales/pl.json +31 -1
- package/package.json +9 -9
- package/public/saltcorn-common.js +11 -0
- package/routes/actions.js +11 -87
- package/routes/api.js +13 -9
- package/routes/list.js +1 -1
- package/routes/menu.js +13 -2
- package/routes/tables.js +1 -0
package/locales/en.json
CHANGED
|
@@ -1551,5 +1551,6 @@
|
|
|
1551
1551
|
"Show results in": "Show results in",
|
|
1552
1552
|
"Show results from each table in this type of element": "Show results from each table in this type of element",
|
|
1553
1553
|
"Search syntax help": "Search syntax help",
|
|
1554
|
-
"Search syntax": "Search syntax"
|
|
1554
|
+
"Search syntax": "Search syntax",
|
|
1555
|
+
"Maximum role": "Maximum role"
|
|
1555
1556
|
}
|
package/locales/pl.json
CHANGED
|
@@ -1521,7 +1521,37 @@
|
|
|
1521
1521
|
"OK": "OK",
|
|
1522
1522
|
"Step settings": "Ustawienia kroku",
|
|
1523
1523
|
"Action settings": "Ustawienia akcji",
|
|
1524
|
+
"Keystore file is not applied for debug builds.": "Plik Keystore nie jest stosowany dla kompilacji debug.",
|
|
1524
1525
|
"Workflow": "Przepływ pracy",
|
|
1525
1526
|
"Previous runs": "Poprzednie uruchomienia",
|
|
1526
|
-
"The workflow the user will be interacting with.": "Przepływ pracy, z którym użytkownik będzie wchodził w interakcję."
|
|
1527
|
+
"The workflow the user will be interacting with.": "Przepływ pracy, z którym użytkownik będzie wchodził w interakcję.",
|
|
1528
|
+
"Delete old workflow runs with status after days": "Usuń stare uruchomienia przepływu pracy ze statusem po określonej liczbie dni",
|
|
1529
|
+
"Finished": "Zakończone",
|
|
1530
|
+
"Error": "Błąd",
|
|
1531
|
+
"Waiting": "Oczekujące",
|
|
1532
|
+
"Running": "Uruchomione",
|
|
1533
|
+
"Minimum role to access search page": "Minimalna rola do uzyskania dostępu do strony wyszukiwania",
|
|
1534
|
+
"Edit tables": "Edytuj tabele",
|
|
1535
|
+
"Minimum role to edit tables": "Minimalna rola do edycji tabel",
|
|
1536
|
+
"Edit views": "Edytuj widoki",
|
|
1537
|
+
"Minimum role to edit views": "Minimalna rola do edycji widoków",
|
|
1538
|
+
"Edit pages": "Edytuj strony",
|
|
1539
|
+
"Minimum role to edit pages": "Minimalna rola do edycji stron",
|
|
1540
|
+
"Edit triggers": "Edytuj wyzwalacze",
|
|
1541
|
+
"Minimum role to edit triggers": "Minimalna rola do edycji wyzwalaczy",
|
|
1542
|
+
"Development permissions": "Uprawnienia deweloperskie",
|
|
1543
|
+
"Inspect tables": "Inspekcja tabel",
|
|
1544
|
+
"Minimum role to inspect (see, without editing) tables": "Minimalna rola do inspekcji (podglądu bez edycji) tabel",
|
|
1545
|
+
"Home pages": "Strony główne",
|
|
1546
|
+
"The home page is the page that is served when the user visits the home location (/). This can be set for each user role.": "Strona główna to strona, która jest wyświetlana, gdy użytkownik odwiedza stronę startową (/). Można ją ustawić dla każdej roli użytkownika.",
|
|
1547
|
+
"Trigger %s deleted": "Wyzwalacz %s usunięty",
|
|
1548
|
+
"Edit menu": "Edytuj menu",
|
|
1549
|
+
"Minimum role to edit menu": "Minimalna rola do edycji menu",
|
|
1550
|
+
"Full-text search index is not available as the table contains Key fields (%s) with the \"Include in full-text search\" option enabled. Disable this before creating a Full-text search index": "Indeks wyszukiwania pełnotekstowego jest niedostępny, ponieważ tabela zawiera pola kluczowe (%s) z włączoną opcją „Uwzględnij w wyszukiwaniu pełnotekstowym”. Wyłącz tę opcję przed utworzeniem indeksu wyszukiwania pełnotekstowego.",
|
|
1551
|
+
"Share Extension Provisioning Profile": "Profil Provisioning Share Extension",
|
|
1552
|
+
"Show results in": "Pokaż wyniki w",
|
|
1553
|
+
"Show results from each table in this type of element": "Pokaż wyniki z każdej tabeli w tym typie elementu",
|
|
1554
|
+
"Search syntax help": "Pomoc dotycząca składni wyszukiwania",
|
|
1555
|
+
"Search syntax": "Składnia wyszukiwania",
|
|
1556
|
+
"Maximum role": "Maksymalna rola"
|
|
1527
1557
|
}
|
package/package.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saltcorn/server",
|
|
3
|
-
"version": "1.1.1
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Server app for Saltcorn, open-source no-code platform",
|
|
5
5
|
"homepage": "https://saltcorn.com",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"@aws-sdk/client-s3": "^3.451.0",
|
|
10
|
-
"@saltcorn/base-plugin": "1.1.1
|
|
11
|
-
"@saltcorn/builder": "1.1.1
|
|
12
|
-
"@saltcorn/data": "1.1.1
|
|
13
|
-
"@saltcorn/admin-models": "1.1.1
|
|
14
|
-
"@saltcorn/filemanager": "1.1.1
|
|
15
|
-
"@saltcorn/markup": "1.1.1
|
|
16
|
-
"@saltcorn/plugins-loader": "1.1.1
|
|
17
|
-
"@saltcorn/sbadmin2": "1.1.1
|
|
10
|
+
"@saltcorn/base-plugin": "1.1.1",
|
|
11
|
+
"@saltcorn/builder": "1.1.1",
|
|
12
|
+
"@saltcorn/data": "1.1.1",
|
|
13
|
+
"@saltcorn/admin-models": "1.1.1",
|
|
14
|
+
"@saltcorn/filemanager": "1.1.1",
|
|
15
|
+
"@saltcorn/markup": "1.1.1",
|
|
16
|
+
"@saltcorn/plugins-loader": "1.1.1",
|
|
17
|
+
"@saltcorn/sbadmin2": "1.1.1",
|
|
18
18
|
"@socket.io/cluster-adapter": "^0.2.1",
|
|
19
19
|
"@socket.io/sticky": "^1.0.1",
|
|
20
20
|
"adm-zip": "0.5.10",
|
|
@@ -2116,6 +2116,17 @@ function select_by_view_click(element, event, required) {
|
|
|
2116
2116
|
}
|
|
2117
2117
|
}
|
|
2118
2118
|
|
|
2119
|
+
function restrict_options(selector, restriction) {
|
|
2120
|
+
$(selector)
|
|
2121
|
+
.find("option")
|
|
2122
|
+
.each(function () {
|
|
2123
|
+
const $o = $(this);
|
|
2124
|
+
const val = $o.val();
|
|
2125
|
+
if (Array.isArray(restriction))
|
|
2126
|
+
if (val && !restriction.find((rid) => rid == val)) $o.remove();
|
|
2127
|
+
});
|
|
2128
|
+
}
|
|
2129
|
+
|
|
2119
2130
|
const observer = new IntersectionObserver(
|
|
2120
2131
|
(entries, observer) => {
|
|
2121
2132
|
entries.forEach((entry) => {
|
package/routes/actions.js
CHANGED
|
@@ -505,83 +505,6 @@ router.post(
|
|
|
505
505
|
})
|
|
506
506
|
);
|
|
507
507
|
|
|
508
|
-
function genWorkflowDiagram(steps) {
|
|
509
|
-
const stepNames = steps.map((s) => s.name);
|
|
510
|
-
const nodeLines = steps.map(
|
|
511
|
-
(s) => ` ${s.mmname}["\`**${s.name}**
|
|
512
|
-
${s.action_name}\`"]:::wfstep${s.id}${s.only_if ? "@{ shape: hex }" : ""}`
|
|
513
|
-
);
|
|
514
|
-
|
|
515
|
-
nodeLines.unshift(` _Start@{ shape: circle, label: "Start" }`);
|
|
516
|
-
const linkLines = [];
|
|
517
|
-
let step_ix = 0;
|
|
518
|
-
for (const step of steps) {
|
|
519
|
-
if (step.initial_step)
|
|
520
|
-
linkLines.push(
|
|
521
|
-
` _Start-- <i class="fas fa-plus add-btw-nodes btw-nodes-${0}-${
|
|
522
|
-
step.name
|
|
523
|
-
}"></i> ---${step.mmname}`
|
|
524
|
-
);
|
|
525
|
-
if (stepNames.includes(step.next_step)) {
|
|
526
|
-
linkLines.push(
|
|
527
|
-
` ${step.mmname} -- <i class="fas fa-plus add-btw-nodes btw-nodes-${step.id}-${step.next_step}"></i> --- ${step.mmnext}`
|
|
528
|
-
);
|
|
529
|
-
} else if (step.next_step) {
|
|
530
|
-
let found = false;
|
|
531
|
-
for (const otherStep of stepNames)
|
|
532
|
-
if (step.next_step.includes(otherStep)) {
|
|
533
|
-
linkLines.push(
|
|
534
|
-
` ${step.mmname} --> ${WorkflowStep.mmescape(otherStep)}`
|
|
535
|
-
);
|
|
536
|
-
found = true;
|
|
537
|
-
}
|
|
538
|
-
if (!found) {
|
|
539
|
-
linkLines.push(
|
|
540
|
-
` ${step.mmname}-- <a href="/actions/stepedit/${step.trigger_id}/${step.id}">Error: missing next step in ${step.mmname}</a> ---_End_${step.mmname}`
|
|
541
|
-
);
|
|
542
|
-
nodeLines.push(
|
|
543
|
-
` _End_${step.mmname}:::wfadd${step.id}@{ shape: circle, label: "<i class='fas fa-plus with-link'></i>" }`
|
|
544
|
-
);
|
|
545
|
-
}
|
|
546
|
-
} else if (!step.next_step) {
|
|
547
|
-
linkLines.push(` ${step.mmname} --> _End_${step.mmname}`);
|
|
548
|
-
nodeLines.push(
|
|
549
|
-
` _End_${step.mmname}:::wfadd${step.id}@{ shape: circle, label: "<i class='fas fa-plus with-link'></i>" }`
|
|
550
|
-
);
|
|
551
|
-
}
|
|
552
|
-
if (step.action_name === "ForLoop") {
|
|
553
|
-
linkLines.push(
|
|
554
|
-
` ${step.mmname}-.->${WorkflowStep.mmescape(
|
|
555
|
-
step.configuration.loop_body_initial_step
|
|
556
|
-
)}`
|
|
557
|
-
);
|
|
558
|
-
}
|
|
559
|
-
if (step.action_name === "EndForLoop") {
|
|
560
|
-
// TODO this is not correct. improve.
|
|
561
|
-
let forStep;
|
|
562
|
-
for (let i = step_ix; i >= 0; i -= 1) {
|
|
563
|
-
if (steps[i].action_name === "ForLoop") {
|
|
564
|
-
forStep = steps[i];
|
|
565
|
-
break;
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
if (forStep) linkLines.push(` ${step.mmname} --> ${forStep.mmname}`);
|
|
569
|
-
}
|
|
570
|
-
step_ix += 1;
|
|
571
|
-
}
|
|
572
|
-
if (!steps.length || !steps.find((s) => s.initial_step)) {
|
|
573
|
-
linkLines.push(` _Start --> _End`);
|
|
574
|
-
nodeLines.push(
|
|
575
|
-
` _End:::wfaddstart@{ shape: circle, label: "<i class='fas fa-plus with-link'></i>" }`
|
|
576
|
-
);
|
|
577
|
-
}
|
|
578
|
-
const fc =
|
|
579
|
-
"flowchart TD\n" + nodeLines.join("\n") + "\n" + linkLines.join("\n");
|
|
580
|
-
//console.log(fc);
|
|
581
|
-
|
|
582
|
-
return fc;
|
|
583
|
-
}
|
|
584
|
-
|
|
585
508
|
const getWorkflowConfig = async (req, id, table, trigger) => {
|
|
586
509
|
let steps = await WorkflowStep.find(
|
|
587
510
|
{ trigger_id: trigger.id },
|
|
@@ -627,7 +550,7 @@ const getWorkflowConfig = async (req, id, table, trigger) => {
|
|
|
627
550
|
}
|
|
628
551
|
return (
|
|
629
552
|
copilot_form +
|
|
630
|
-
pre({ class: "mermaid" },
|
|
553
|
+
pre({ class: "mermaid" }, WorkflowStep.generate_diagram(steps)) +
|
|
631
554
|
script(
|
|
632
555
|
{ defer: "defer" },
|
|
633
556
|
`function tryAddWFNodes() {
|
|
@@ -1700,7 +1623,7 @@ router.get(
|
|
|
1700
1623
|
req,
|
|
1701
1624
|
active_sub: "Workflow runs",
|
|
1702
1625
|
page_title: req.__(`Workflow runs`),
|
|
1703
|
-
sub2_page: trigger
|
|
1626
|
+
sub2_page: trigger?.name,
|
|
1704
1627
|
contents: {
|
|
1705
1628
|
above: [
|
|
1706
1629
|
{
|
|
@@ -1712,15 +1635,16 @@ router.get(
|
|
|
1712
1635
|
{ class: "table table-condensed w-unset" },
|
|
1713
1636
|
tbody(
|
|
1714
1637
|
tr(th("Run ID"), td(run.id)),
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1638
|
+
trigger &&
|
|
1639
|
+
tr(
|
|
1640
|
+
th("Trigger"),
|
|
1641
|
+
td(
|
|
1642
|
+
a(
|
|
1643
|
+
{ href: `/actions/configure/${trigger.id}` },
|
|
1644
|
+
trigger.name
|
|
1645
|
+
)
|
|
1721
1646
|
)
|
|
1722
|
-
)
|
|
1723
|
-
),
|
|
1647
|
+
),
|
|
1724
1648
|
tr(th("Started at"), td(localeDateTime(run.started_at))),
|
|
1725
1649
|
tr(th("Started by user"), td(run.started_by)),
|
|
1726
1650
|
tr(th("Status"), td(run.status)),
|
package/routes/api.js
CHANGED
|
@@ -350,6 +350,13 @@ router.get(
|
|
|
350
350
|
const orderByField =
|
|
351
351
|
(sortBy || tabulator_sort) && table.getField(sortBy || tabulator_sort);
|
|
352
352
|
|
|
353
|
+
const use_limit = tabulator_pagination_format
|
|
354
|
+
? +tabulator_size
|
|
355
|
+
: limit && +limit;
|
|
356
|
+
const use_offset = tabulator_pagination_format
|
|
357
|
+
? +tabulator_size * (+tabulator_page - 1)
|
|
358
|
+
: offset && +offset;
|
|
359
|
+
|
|
353
360
|
await passport.authenticate(
|
|
354
361
|
["api-bearer", "jwt"],
|
|
355
362
|
{ session: false },
|
|
@@ -360,12 +367,8 @@ router.get(
|
|
|
360
367
|
const joinOpts = {
|
|
361
368
|
forUser: req.user || user || { role_id: 100 },
|
|
362
369
|
forPublic: !(req.user || user),
|
|
363
|
-
limit:
|
|
364
|
-
|
|
365
|
-
: limit && +limit,
|
|
366
|
-
offset: tabulator_pagination_format
|
|
367
|
-
? +tabulator_size * (+tabulator_page - 1)
|
|
368
|
-
: offset && +offset,
|
|
370
|
+
limit: use_limit,
|
|
371
|
+
offset: use_offset,
|
|
369
372
|
orderDesc:
|
|
370
373
|
(sortDesc && sortDesc !== "false") || tabulator_dir == "desc",
|
|
371
374
|
orderBy: orderByField?.name || "id",
|
|
@@ -406,9 +409,10 @@ router.get(
|
|
|
406
409
|
rows = await table.getJoinedRows({
|
|
407
410
|
where: qstate,
|
|
408
411
|
joinFields,
|
|
409
|
-
limit:
|
|
410
|
-
offset:
|
|
411
|
-
orderDesc:
|
|
412
|
+
limit: use_limit,
|
|
413
|
+
offset: use_offset,
|
|
414
|
+
orderDesc:
|
|
415
|
+
(sortDesc && sortDesc !== "false") || tabulator_dir == "desc",
|
|
412
416
|
orderBy: orderByField?.name || undefined,
|
|
413
417
|
forPublic: !(req.user || user),
|
|
414
418
|
forUser: req.user || user,
|
package/routes/list.js
CHANGED
package/routes/menu.js
CHANGED
|
@@ -9,7 +9,11 @@ const Router = require("express-promise-router");
|
|
|
9
9
|
|
|
10
10
|
//const Field = require("@saltcorn/data/models/field");
|
|
11
11
|
const Form = require("@saltcorn/data/models/form");
|
|
12
|
-
const {
|
|
12
|
+
const {
|
|
13
|
+
isAdmin,
|
|
14
|
+
error_catcher,
|
|
15
|
+
isAdminOrHasConfigMinRole,
|
|
16
|
+
} = require("./utils.js");
|
|
13
17
|
const { getState } = require("@saltcorn/data/db/state");
|
|
14
18
|
//const File = require("@saltcorn/data/models/file");
|
|
15
19
|
const User = require("@saltcorn/data/models/user");
|
|
@@ -307,6 +311,13 @@ const menuForm = async (req) => {
|
|
|
307
311
|
input_type: "select",
|
|
308
312
|
options: roles.map((r) => ({ label: r.role, value: r.id })),
|
|
309
313
|
},
|
|
314
|
+
{
|
|
315
|
+
name: "max_role",
|
|
316
|
+
label: req.__("Maximum role"),
|
|
317
|
+
class: "item-menu",
|
|
318
|
+
input_type: "select",
|
|
319
|
+
options: roles.map((r) => ({ label: r.role, value: r.id })),
|
|
320
|
+
},
|
|
310
321
|
{
|
|
311
322
|
name: "disable_on_mobile",
|
|
312
323
|
label: req.__("Disable on mobile"),
|
|
@@ -566,7 +577,7 @@ const jQMEtoMenu = (menu_items) =>
|
|
|
566
577
|
*/
|
|
567
578
|
router.post(
|
|
568
579
|
"/",
|
|
569
|
-
isAdminOrHasConfigMinRole("min_role_edit_menu"),
|
|
580
|
+
isAdminOrHasConfigMinRole("min_role_edit_menu"),
|
|
570
581
|
error_catcher(async (req, res) => {
|
|
571
582
|
const new_menu = req.body;
|
|
572
583
|
const menu_items = jQMEtoMenu(new_menu);
|