@saltcorn/server 1.1.0-beta.13 → 1.1.0-beta.15
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/auth/admin.js +1 -1
- package/locales/en.json +15 -1
- package/locales/pl.json +19 -2
- package/markup/admin.js +1 -0
- package/package.json +9 -9
- package/public/mermaid.min.js +1077 -792
- package/public/saltcorn-common.js +53 -38
- package/public/saltcorn.js +37 -11
- package/routes/actions.js +937 -4
- package/routes/eventlog.js +36 -0
- package/routes/fields.js +4 -0
- package/routes/tables.js +58 -20
package/routes/eventlog.js
CHANGED
|
@@ -81,6 +81,31 @@ const logSettingsForm = async (req) => {
|
|
|
81
81
|
input_type: "date",
|
|
82
82
|
attributes: { minDate: new Date(), maxDate: hoursFuture(24 * 7 * 2) },
|
|
83
83
|
},
|
|
84
|
+
{
|
|
85
|
+
input_type: "section_header",
|
|
86
|
+
label: req.__("Delete old workflow runs with status after days"),
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: "delete_finished_workflows_days",
|
|
90
|
+
label: req.__("Finished"),
|
|
91
|
+
type: "Integer",
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: "delete_error_workflows_days",
|
|
95
|
+
label: req.__("Error"),
|
|
96
|
+
type: "Integer",
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: "delete_waiting_workflows_days",
|
|
100
|
+
label: req.__("Waiting"),
|
|
101
|
+
type: "Integer",
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
{
|
|
105
|
+
name: "delete_running_workflows_days",
|
|
106
|
+
label: req.__("Running"),
|
|
107
|
+
type: "Integer",
|
|
108
|
+
},
|
|
84
109
|
{
|
|
85
110
|
input_type: "section_header",
|
|
86
111
|
label: req.__("Which events should be logged?"),
|
|
@@ -143,6 +168,10 @@ router.get(
|
|
|
143
168
|
"next_weekly_event",
|
|
144
169
|
{}
|
|
145
170
|
);
|
|
171
|
+
["error", "finished", "running", "waiting"].forEach((k) => {
|
|
172
|
+
let cfgk = `delete_${k}_workflows_days`;
|
|
173
|
+
form.values[cfgk] = getState().getConfig(cfgk);
|
|
174
|
+
});
|
|
146
175
|
|
|
147
176
|
send_events_page({
|
|
148
177
|
res,
|
|
@@ -348,6 +377,13 @@ router.post(
|
|
|
348
377
|
delete form.values[k];
|
|
349
378
|
}
|
|
350
379
|
}
|
|
380
|
+
for (const status of ["error", "finished", "running", "waiting"]) {
|
|
381
|
+
let k = `delete_${status}_workflows_days`;
|
|
382
|
+
if (form.values[k]) {
|
|
383
|
+
await getState().setConfig(k, form.values[k]);
|
|
384
|
+
delete form.values[k];
|
|
385
|
+
}
|
|
386
|
+
}
|
|
351
387
|
|
|
352
388
|
await getState().setConfig("event_log_settings", form.values);
|
|
353
389
|
|
package/routes/fields.js
CHANGED
|
@@ -301,6 +301,10 @@ const fieldFlow = (req) =>
|
|
|
301
301
|
if (context.id) {
|
|
302
302
|
const field = await Field.findOne({ id: context.id });
|
|
303
303
|
try {
|
|
304
|
+
if (fldRow.label && field.label != fldRow.label) {
|
|
305
|
+
fldRow.name = Field.labelToName(fldRow.label);
|
|
306
|
+
}
|
|
307
|
+
|
|
304
308
|
await field.update(fldRow);
|
|
305
309
|
} catch (e) {
|
|
306
310
|
return {
|
package/routes/tables.js
CHANGED
|
@@ -56,7 +56,7 @@ const {
|
|
|
56
56
|
} = require("@saltcorn/data/models/discovery");
|
|
57
57
|
const { getState } = require("@saltcorn/data/db/state");
|
|
58
58
|
const { cardHeaderTabs } = require("@saltcorn/markup/layout_utils");
|
|
59
|
-
const { tablesList, viewsList } = require("./common_lists");
|
|
59
|
+
const { tablesList, viewsList, getTriggerList } = require("./common_lists");
|
|
60
60
|
const {
|
|
61
61
|
InvalidConfiguration,
|
|
62
62
|
removeAllWhiteSpace,
|
|
@@ -757,6 +757,8 @@ router.get(
|
|
|
757
757
|
const triggers = table.id ? Trigger.find({ table_id: table.id }) : [];
|
|
758
758
|
triggers.sort(comparingCaseInsensitive("name"));
|
|
759
759
|
let fieldCard;
|
|
760
|
+
const nPrimaryKeys = fields.filter((f) => f.primary_key).length;
|
|
761
|
+
|
|
760
762
|
if (fields.length === 0) {
|
|
761
763
|
fieldCard = [
|
|
762
764
|
h4(req.__(`No fields defined in %s table`, table.name)),
|
|
@@ -818,28 +820,25 @@ router.get(
|
|
|
818
820
|
{ hover: true }
|
|
819
821
|
);
|
|
820
822
|
fieldCard = [
|
|
823
|
+
nPrimaryKeys > 1 &&
|
|
824
|
+
div(
|
|
825
|
+
{ class: "alert alert-danger", role: "alert" },
|
|
826
|
+
i({ class: "fas fa-exclamation-triangle" }),
|
|
827
|
+
"This table has composite primary keys which is not supported in Saltcorn. A procedure to introduce a single autoincrementing primary key is available.",
|
|
828
|
+
post_btn(
|
|
829
|
+
`/table/repair-composite-primary/${table.id}`,
|
|
830
|
+
"Add autoincrementing primary key",
|
|
831
|
+
req.csrfToken(),
|
|
832
|
+
{ btnClass: "btn-danger" }
|
|
833
|
+
)
|
|
834
|
+
),
|
|
835
|
+
|
|
821
836
|
tableHtml,
|
|
822
837
|
inbound_refs.length > 0
|
|
823
838
|
? req.__("Inbound keys: ") +
|
|
824
839
|
inbound_refs.map((tnm) => link(`/table/${tnm}`, tnm)).join(", ") +
|
|
825
840
|
"<br>"
|
|
826
841
|
: "",
|
|
827
|
-
triggers.length
|
|
828
|
-
? req.__("Table triggers: ") +
|
|
829
|
-
triggers
|
|
830
|
-
.map((t) =>
|
|
831
|
-
link(
|
|
832
|
-
`/actions/configure/${
|
|
833
|
-
t.id
|
|
834
|
-
}?on_done_redirect=${encodeURIComponent(
|
|
835
|
-
`table/${table.name}`
|
|
836
|
-
)}`,
|
|
837
|
-
t.name
|
|
838
|
-
)
|
|
839
|
-
)
|
|
840
|
-
.join(", ") +
|
|
841
|
-
"<br>"
|
|
842
|
-
: "",
|
|
843
842
|
!table.external &&
|
|
844
843
|
!table.provider_name &&
|
|
845
844
|
a(
|
|
@@ -851,7 +850,8 @@ router.get(
|
|
|
851
850
|
),
|
|
852
851
|
];
|
|
853
852
|
}
|
|
854
|
-
|
|
853
|
+
let viewCard;
|
|
854
|
+
let triggerCard = "";
|
|
855
855
|
if (fields.length > 0) {
|
|
856
856
|
const views = await View.find(
|
|
857
857
|
table.id ? { table_id: table.id } : { exttable_name: table.name }
|
|
@@ -884,6 +884,25 @@ router.get(
|
|
|
884
884
|
req.__("Create view")
|
|
885
885
|
),
|
|
886
886
|
};
|
|
887
|
+
|
|
888
|
+
triggerCard = {
|
|
889
|
+
type: "card",
|
|
890
|
+
id: "table-triggers",
|
|
891
|
+
title: req.__("Triggers on table"),
|
|
892
|
+
contents:
|
|
893
|
+
(triggers.length
|
|
894
|
+
? await getTriggerList(triggers, req)
|
|
895
|
+
: p("Triggers run actions in response to events on this table")) +
|
|
896
|
+
a(
|
|
897
|
+
{
|
|
898
|
+
href: `/actions/new?table=${encodeURIComponent(
|
|
899
|
+
table.name
|
|
900
|
+
)}&on_done_redirect=${encodeURIComponent(`table/${table.name}`)}`,
|
|
901
|
+
class: "btn btn-primary",
|
|
902
|
+
},
|
|
903
|
+
req.__("Create trigger")
|
|
904
|
+
),
|
|
905
|
+
};
|
|
887
906
|
}
|
|
888
907
|
const models = await Model.find({ table_id: table.id });
|
|
889
908
|
const modelCard = div(
|
|
@@ -1078,6 +1097,7 @@ router.get(
|
|
|
1078
1097
|
]
|
|
1079
1098
|
: []),
|
|
1080
1099
|
...(viewCard ? [viewCard] : []),
|
|
1100
|
+
...(triggerCard ? [triggerCard] : []),
|
|
1081
1101
|
{
|
|
1082
1102
|
type: "card",
|
|
1083
1103
|
title: req.__("Edit table properties"),
|
|
@@ -1111,7 +1131,7 @@ router.post(
|
|
|
1111
1131
|
const v = req.body;
|
|
1112
1132
|
if (typeof v.id === "undefined" && typeof v.external === "undefined") {
|
|
1113
1133
|
// insert
|
|
1114
|
-
v.name = v.name.trim()
|
|
1134
|
+
v.name = v.name.trim();
|
|
1115
1135
|
const { name, ...rest } = v;
|
|
1116
1136
|
const alltables = await Table.find({});
|
|
1117
1137
|
const existing_tables = [
|
|
@@ -1162,6 +1182,7 @@ router.post(
|
|
|
1162
1182
|
let notify = "";
|
|
1163
1183
|
if (!rest.versioned) rest.versioned = false;
|
|
1164
1184
|
if (!rest.has_sync_info) rest.has_sync_info = false;
|
|
1185
|
+
rest.is_user_group = !!rest.is_user_group;
|
|
1165
1186
|
if (rest.ownership_field_id === "_formula") {
|
|
1166
1187
|
rest.ownership_field_id = null;
|
|
1167
1188
|
const fmlValidRes = expressionValidator(rest.ownership_formula);
|
|
@@ -1922,7 +1943,7 @@ router.post(
|
|
|
1922
1943
|
const table = Table.findOne({ name });
|
|
1923
1944
|
|
|
1924
1945
|
try {
|
|
1925
|
-
await table.deleteRows({}, req.user);
|
|
1946
|
+
await table.deleteRows({}, req.user, true);
|
|
1926
1947
|
req.flash("success", req.__("Deleted all rows"));
|
|
1927
1948
|
} catch (e) {
|
|
1928
1949
|
req.flash("error", e.message);
|
|
@@ -2074,3 +2095,20 @@ router.post(
|
|
|
2074
2095
|
respondWorkflow(table, workflow, wfres, req, res);
|
|
2075
2096
|
})
|
|
2076
2097
|
);
|
|
2098
|
+
|
|
2099
|
+
router.post(
|
|
2100
|
+
"/repair-composite-primary/:id",
|
|
2101
|
+
isAdmin,
|
|
2102
|
+
error_catcher(async (req, res) => {
|
|
2103
|
+
const { id } = req.params;
|
|
2104
|
+
|
|
2105
|
+
const table = Table.findOne({ id });
|
|
2106
|
+
if (!table) {
|
|
2107
|
+
req.flash("error", `Table not found`);
|
|
2108
|
+
res.redirect(`/table`);
|
|
2109
|
+
return;
|
|
2110
|
+
}
|
|
2111
|
+
await table.repairCompositePrimary();
|
|
2112
|
+
res.redirect(`/table/${table.id}`);
|
|
2113
|
+
})
|
|
2114
|
+
);
|