@saltcorn/server 1.1.1-beta.8 → 1.1.1-rc.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/CHANGELOG.md +37 -1
- package/auth/admin.js +1 -0
- package/locales/en.json +9 -1
- package/markup/admin.js +15 -10
- package/package.json +9 -9
- package/public/saltcorn-common.js +85 -1
- package/public/saltcorn.css +39 -0
- package/public/saltcorn.js +17 -4
- package/routes/actions.js +17 -1
- package/routes/admin.js +29 -25
- package/routes/api.js +68 -5
- package/routes/common_lists.js +67 -16
- package/routes/fields.js +113 -2
- package/routes/list.js +9 -8
- package/routes/menu.js +3 -3
- package/routes/search.js +91 -11
- package/routes/tables.js +18 -4
- package/routes/tag_entries.js +43 -1
- package/routes/tags.js +1 -0
- package/routes/utils.js +15 -0
- package/serve.js +17 -13
- package/tests/api.test.js +13 -0
- package/tests/clientjs.test.js +20 -0
- package/tests/files.test.js +1 -1
- package/wrapper.js +31 -1
package/serve.js
CHANGED
|
@@ -99,20 +99,24 @@ const ensurePluginsFolder = async () => {
|
|
|
99
99
|
const staticDeps = ["@saltcorn/markup", "@saltcorn/data", "jest"];
|
|
100
100
|
const allPluginFolders = new Set();
|
|
101
101
|
await eachTenant(async () => {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
for (const plugin of allPlugins) {
|
|
106
|
-
const tokens =
|
|
107
|
-
plugin.source === "npm"
|
|
108
|
-
? plugin.location.split("/")
|
|
109
|
-
: plugin.name.split("/");
|
|
110
|
-
const pluginDir = path.join(
|
|
111
|
-
rootFolder,
|
|
112
|
-
plugin.source === "git" ? "git_plugins" : "plugins_folder",
|
|
113
|
-
...tokens
|
|
102
|
+
try {
|
|
103
|
+
const allPlugins = (await Plugin.find()).filter(
|
|
104
|
+
(p) => !["base", "sbadmin2"].includes(p.name)
|
|
114
105
|
);
|
|
115
|
-
|
|
106
|
+
for (const plugin of allPlugins) {
|
|
107
|
+
const tokens =
|
|
108
|
+
plugin.source === "npm"
|
|
109
|
+
? plugin.location.split("/")
|
|
110
|
+
: plugin.name.split("/");
|
|
111
|
+
const pluginDir = path.join(
|
|
112
|
+
rootFolder,
|
|
113
|
+
plugin.source === "git" ? "git_plugins" : "plugins_folder",
|
|
114
|
+
...tokens
|
|
115
|
+
);
|
|
116
|
+
allPluginFolders.add(pluginDir);
|
|
117
|
+
}
|
|
118
|
+
} catch {
|
|
119
|
+
//ignore
|
|
116
120
|
}
|
|
117
121
|
});
|
|
118
122
|
for (const folder of allPluginFolders) {
|
package/tests/api.test.js
CHANGED
|
@@ -107,6 +107,19 @@ describe("API read", () => {
|
|
|
107
107
|
)
|
|
108
108
|
);
|
|
109
109
|
});
|
|
110
|
+
it("should get books limit", async () => {
|
|
111
|
+
const app = await getApp({ disableCsrf: true });
|
|
112
|
+
await request(app)
|
|
113
|
+
.get("/api/books/?limit=1&offset=1&sortBy=pages")
|
|
114
|
+
.expect(
|
|
115
|
+
succeedJsonWith(
|
|
116
|
+
(rows) =>
|
|
117
|
+
rows.length == 1 &&
|
|
118
|
+
rows[0].author === "Herman Melville" &&
|
|
119
|
+
rows[0].pages === 967
|
|
120
|
+
)
|
|
121
|
+
);
|
|
122
|
+
});
|
|
110
123
|
it("should handle fkey args ", async () => {
|
|
111
124
|
const loginCookie = await getAdminLoginCookie();
|
|
112
125
|
const app = await getApp({ disableCsrf: true });
|
package/tests/clientjs.test.js
CHANGED
|
@@ -54,6 +54,26 @@ test("updateQueryStringParameter", () => {
|
|
|
54
54
|
"AK"
|
|
55
55
|
)
|
|
56
56
|
).toBe("/foo?publisher.publisher->name=AK");
|
|
57
|
+
expect(
|
|
58
|
+
updateQueryStringParameter(
|
|
59
|
+
"/foo?factor.Factors->focus_area.Focus%20area->short_name=Leadership",
|
|
60
|
+
"factor.Factors->focus_area.Focus%20area->short_name",
|
|
61
|
+
"Marketing"
|
|
62
|
+
)
|
|
63
|
+
).toBe("/foo?factor.Factors->focus_area.Focus%20area->short_name=Marketing");
|
|
64
|
+
expect(
|
|
65
|
+
updateQueryStringParameter(
|
|
66
|
+
"/foo?factor.Factors%20(Solaris)->focus_area.Focus%20area%20(Solaris)->short_name=Leadership",
|
|
67
|
+
"factor.Factors%20(Solaris)->focus_area.Focus%20area%20(Solaris)->short_name",
|
|
68
|
+
"Marketing"
|
|
69
|
+
)
|
|
70
|
+
).toBe(
|
|
71
|
+
"/foo?factor.Factors%20(Solaris)->focus_area.Focus%20area%20(Solaris)->short_name=Marketing"
|
|
72
|
+
);
|
|
73
|
+
expect(removeQueryStringParameter("/foo?name=Bar&factor.Factors%20(Solaris)->focus_area.Focus%20area%20(Solaris)->short_name=Leadership", "factor.Factors%20(Solaris)->focus_area.Focus%20area%20(Solaris)->short_name")).toBe(
|
|
74
|
+
"/foo?name=Bar"
|
|
75
|
+
);
|
|
76
|
+
|
|
57
77
|
expect(updateQueryStringParameter("/foo", "_or_field", ["baz", "bar"])).toBe(
|
|
58
78
|
"/foo?_or_field=baz&_or_field=bar"
|
|
59
79
|
);
|
package/tests/files.test.js
CHANGED
|
@@ -407,7 +407,7 @@ describe("visible_entries test", () => {
|
|
|
407
407
|
.set("Cookie", staffCookie);
|
|
408
408
|
expect(resp.statusCode).toBe(200);
|
|
409
409
|
expect(
|
|
410
|
-
resp.body.directories.find((file) => file.filename === "subsubfolder")
|
|
410
|
+
resp.body.directories.find((file) => file.filename === "_sc_test_subfolder_one/subsubfolder")
|
|
411
411
|
).toBeDefined();
|
|
412
412
|
});
|
|
413
413
|
|
package/wrapper.js
CHANGED
|
@@ -96,6 +96,7 @@ const get_menu = (req) => {
|
|
|
96
96
|
const canEditViews = state.getConfig("min_role_edit_views", 1) >= role;
|
|
97
97
|
const canEditPages = state.getConfig("min_role_edit_pages", 1) >= role;
|
|
98
98
|
const canEditTriggers = state.getConfig("min_role_edit_triggers", 1) >= role;
|
|
99
|
+
const canEditMenu = state.getConfig("min_role_edit_menu", 1) >= role;
|
|
99
100
|
const isAdmin = role === 1;
|
|
100
101
|
const hasAdmin =
|
|
101
102
|
isAdmin ||
|
|
@@ -103,6 +104,7 @@ const get_menu = (req) => {
|
|
|
103
104
|
canInspectTables ||
|
|
104
105
|
canEditPages ||
|
|
105
106
|
canEditViews ||
|
|
107
|
+
canEditMenu ||
|
|
106
108
|
canEditTriggers;
|
|
107
109
|
/*
|
|
108
110
|
* Admin Menu items
|
|
@@ -128,13 +130,41 @@ const get_menu = (req) => {
|
|
|
128
130
|
icon: "far fa-file",
|
|
129
131
|
label: req.__("Pages"),
|
|
130
132
|
});
|
|
131
|
-
if (canEditTriggers && !isAdmin)
|
|
133
|
+
if (canEditTriggers && !canEditMenu && !isAdmin)
|
|
132
134
|
adminItems.push({
|
|
133
135
|
link: "/actions",
|
|
134
136
|
altlinks: ["/events", "/eventlog", "/crashlog"],
|
|
135
137
|
icon: "fas fa-calendar-check",
|
|
136
138
|
label: req.__("Triggers"),
|
|
137
139
|
});
|
|
140
|
+
if (canEditMenu && !isAdmin) {
|
|
141
|
+
const subitems = [
|
|
142
|
+
{
|
|
143
|
+
link: "/menu",
|
|
144
|
+
altlinks: [
|
|
145
|
+
"/site-structure",
|
|
146
|
+
"/search/config",
|
|
147
|
+
"/library/list",
|
|
148
|
+
"/tenant/list",
|
|
149
|
+
],
|
|
150
|
+
icon: "fas fa-compass",
|
|
151
|
+
label: req.__("Menu"),
|
|
152
|
+
},
|
|
153
|
+
];
|
|
154
|
+
if (canEditTriggers)
|
|
155
|
+
subitems.push({
|
|
156
|
+
link: "/actions",
|
|
157
|
+
altlinks: ["/events", "/eventlog", "/crashlog"],
|
|
158
|
+
icon: "fas fa-calendar-check",
|
|
159
|
+
label: req.__("Triggers"),
|
|
160
|
+
});
|
|
161
|
+
adminItems.push({
|
|
162
|
+
label: req.__("Settings"),
|
|
163
|
+
icon: "fas fa-wrench",
|
|
164
|
+
subitems,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
138
168
|
if (isAdmin)
|
|
139
169
|
adminItems.push({
|
|
140
170
|
label: req.__("Settings"),
|