@saltcorn/mobile-app 0.8.6-beta.4 → 0.8.6-beta.6
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/package.json +1 -1
- package/www/index.html +2 -1
- package/www/js/routes/api.js +39 -0
- package/www/js/routes/common.js +3 -3
- package/www/js/routes/delete.js +2 -5
- package/www/js/routes/init.js +5 -1
- package/www/js/utils/global_utils.js +8 -2
- package/www/js/utils/iframe_view_utils.js +37 -1
- package/www/js/utils/table_utils.js +8 -0
package/package.json
CHANGED
package/www/index.html
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
<script src="js/routes/auth.js"></script>
|
|
19
19
|
<script src="js/routes/delete.js"></script>
|
|
20
20
|
<script src="js/routes/edit.js"></script>
|
|
21
|
+
<script src="js/routes/api.js"></script>
|
|
21
22
|
<script src="js/routes/error.js"></script>
|
|
22
23
|
<script src="js/routes/page.js"></script>
|
|
23
24
|
<script src="js/routes/view.js"></script>
|
|
@@ -180,7 +181,7 @@
|
|
|
180
181
|
const onResume = async () => {
|
|
181
182
|
const state = saltcorn.data.state.getState();
|
|
182
183
|
const mobileConfig = state.mobileConfig;
|
|
183
|
-
if (mobileConfig
|
|
184
|
+
if (mobileConfig?.allowOfflineMode) {
|
|
184
185
|
mobileConfig.networkState = navigator.connection.type;
|
|
185
186
|
if (
|
|
186
187
|
mobileConfig.networkState === "none" &&
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/*global saltcorn, apiCall*/
|
|
2
|
+
|
|
3
|
+
// post/api/:tableName/:id
|
|
4
|
+
const updateTableRow = async (context) => {
|
|
5
|
+
const { tableName, id } = context.params;
|
|
6
|
+
const mobileConfig = saltcorn.data.state.getState().mobileConfig;
|
|
7
|
+
const user = {
|
|
8
|
+
id: mobileConfig.user_id,
|
|
9
|
+
role_id: mobileConfig.role_id || 100,
|
|
10
|
+
};
|
|
11
|
+
const table = saltcorn.data.models.Table.findOne({ name: tableName });
|
|
12
|
+
if (!table) throw new Error(`The table '${tableName}' does not exist.`);
|
|
13
|
+
if (
|
|
14
|
+
mobileConfig.isOfflineMode ||
|
|
15
|
+
mobileConfig.localTableIds.indexOf(table.id) >= 0
|
|
16
|
+
) {
|
|
17
|
+
const row = {};
|
|
18
|
+
for (const [k, v] of new URLSearchParams(context.query).entries()) {
|
|
19
|
+
row[k] = v;
|
|
20
|
+
}
|
|
21
|
+
const errors = await saltcorn.data.web_mobile_commons.prepare_update_row(
|
|
22
|
+
table,
|
|
23
|
+
row,
|
|
24
|
+
id
|
|
25
|
+
);
|
|
26
|
+
if (errors.length > 0) throw new Error(errors.join(", "));
|
|
27
|
+
const ins_res = await table.tryUpdateRow(row, id, user);
|
|
28
|
+
if (ins_res.error)
|
|
29
|
+
throw new Error(`Update ${table.name} error: ${ins_res.error}`);
|
|
30
|
+
return { ins_res };
|
|
31
|
+
} else {
|
|
32
|
+
const response = await apiCall({
|
|
33
|
+
method: "POST",
|
|
34
|
+
path: `/api/${tableName}/${id}`,
|
|
35
|
+
body: context.query,
|
|
36
|
+
});
|
|
37
|
+
return response.data;
|
|
38
|
+
}
|
|
39
|
+
};
|
package/www/js/routes/common.js
CHANGED
|
@@ -64,13 +64,13 @@ const getMenu = (req) => {
|
|
|
64
64
|
const authItems = mobileCfg.isPublicUser
|
|
65
65
|
? [
|
|
66
66
|
{
|
|
67
|
-
link: "javascript:
|
|
67
|
+
link: "javascript:execNavbarLink('/auth/login')",
|
|
68
68
|
label: req.__("Login"),
|
|
69
69
|
},
|
|
70
70
|
...(allowSignup
|
|
71
71
|
? [
|
|
72
72
|
{
|
|
73
|
-
link: "javascript:
|
|
73
|
+
link: "javascript:execNavbarLink('/auth/signup')",
|
|
74
74
|
label: req.__("Sign up"),
|
|
75
75
|
},
|
|
76
76
|
]
|
|
@@ -107,7 +107,7 @@ const getMenu = (req) => {
|
|
|
107
107
|
section: "Network",
|
|
108
108
|
items: [
|
|
109
109
|
{
|
|
110
|
-
link: "javascript:
|
|
110
|
+
link: "javascript:execNavbarLink('/sync/sync_settings')",
|
|
111
111
|
icon: "fas fa-sync",
|
|
112
112
|
label: "Network",
|
|
113
113
|
},
|
package/www/js/routes/delete.js
CHANGED
|
@@ -9,14 +9,11 @@ const deleteRows = async (context) => {
|
|
|
9
9
|
if (isOfflineMode || localTableIds.indexOf(table.id) >= 0) {
|
|
10
10
|
if (role_id <= table.min_role_write) {
|
|
11
11
|
await table.deleteRows({ id });
|
|
12
|
-
|
|
12
|
+
// TODO 'table.is_owner' check?
|
|
13
|
+
} else throw new Error(i18next.t("Not authorized"));
|
|
13
14
|
if (isOfflineMode && !(await offlineHelper.hasOfflineRows())) {
|
|
14
15
|
await offlineHelper.setOfflineSession(null);
|
|
15
16
|
}
|
|
16
|
-
// TODO 'table.is_owner' check?
|
|
17
|
-
else {
|
|
18
|
-
throw new Error(i18next.t("Not authorized"));
|
|
19
|
-
}
|
|
20
17
|
} else {
|
|
21
18
|
await apiCall({ method: "POST", path: `/delete/${name}/${id}` });
|
|
22
19
|
}
|
package/www/js/routes/init.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*global postView, postViewRoute, getView, postToggleField, deleteRows, postPageAction, getPage, getLoginView, logoutAction, getSignupView, getErrorView, window, getSyncSettingsView, getAskDeleteOfflineData, getAskUploadNotEnded */
|
|
1
|
+
/*global postView, postViewRoute, getView, postToggleField, deleteRows, postPageAction, getPage, getLoginView, logoutAction, getSignupView, getErrorView, window, getSyncSettingsView, getAskDeleteOfflineData, getAskUploadNotEnded, updateTableRow */
|
|
2
2
|
// TODO module namespacese
|
|
3
3
|
|
|
4
4
|
const initRoutes = async () => {
|
|
@@ -15,6 +15,10 @@ const initRoutes = async () => {
|
|
|
15
15
|
path: "get/view/:viewname",
|
|
16
16
|
action: getView,
|
|
17
17
|
},
|
|
18
|
+
{
|
|
19
|
+
path: "post/api/:tableName/:id",
|
|
20
|
+
action: updateTableRow,
|
|
21
|
+
},
|
|
18
22
|
{
|
|
19
23
|
path: "post/edit/toggle/:name/:id/:field_name",
|
|
20
24
|
action: postToggleField,
|
|
@@ -209,11 +209,17 @@ async function handleRoute(route, query, files) {
|
|
|
209
209
|
: [],
|
|
210
210
|
});
|
|
211
211
|
if (page.redirect) {
|
|
212
|
-
if (
|
|
212
|
+
if (
|
|
213
|
+
page.redirect.startsWith("http://localhost") ||
|
|
214
|
+
page.redirect === "undefined"
|
|
215
|
+
) {
|
|
213
216
|
await gotoEntryView();
|
|
214
217
|
} else {
|
|
215
218
|
const { path, query } = splitPathQuery(page.redirect);
|
|
216
|
-
await handleRoute(
|
|
219
|
+
await handleRoute(
|
|
220
|
+
path.startsWith("/") && path.length > 1 ? `get${path}` : path,
|
|
221
|
+
query
|
|
222
|
+
);
|
|
217
223
|
}
|
|
218
224
|
} else if (page.content) {
|
|
219
225
|
if (!page.replaceIframe) await replaceIframeInnerContent(page.content);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*eslint-env browser*/
|
|
2
|
-
/*global $, submitWithEmptyAction, is_paging_param, bootstrap, common_done, unique_field_from_rows*/
|
|
2
|
+
/*global $, submitWithEmptyAction, is_paging_param, bootstrap, common_done, unique_field_from_rows, inline_submit_success*/
|
|
3
3
|
|
|
4
4
|
function combineFormAndQuery(form, query) {
|
|
5
5
|
let paramsList = [];
|
|
@@ -24,6 +24,11 @@ async function execLink(url) {
|
|
|
24
24
|
await parent.handleRoute(`get${path}`, query);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
async function execNavbarLink(url) {
|
|
28
|
+
$(".navbar-toggler").click();
|
|
29
|
+
execLink(url);
|
|
30
|
+
}
|
|
31
|
+
|
|
27
32
|
/**
|
|
28
33
|
*
|
|
29
34
|
* @param {*} e
|
|
@@ -42,6 +47,31 @@ async function formSubmit(e, urlSuffix, viewname) {
|
|
|
42
47
|
await parent.handleRoute(`post${urlSuffix}${viewname}`, queryStr, files);
|
|
43
48
|
}
|
|
44
49
|
|
|
50
|
+
async function inline_local_submit(e, opts1) {
|
|
51
|
+
try {
|
|
52
|
+
e.preventDefault();
|
|
53
|
+
const opts = JSON.parse(decodeURIComponent(opts1 || "") || "{}");
|
|
54
|
+
const form = $(e.target).closest("form");
|
|
55
|
+
const urlParams = new URLSearchParams();
|
|
56
|
+
for (const entry of new FormData(form[0]).entries()) {
|
|
57
|
+
urlParams.append(entry[0], entry[1]);
|
|
58
|
+
}
|
|
59
|
+
const url = form.attr("action");
|
|
60
|
+
await parent.router.resolve({
|
|
61
|
+
pathname: `post${url}`,
|
|
62
|
+
query: urlParams.toString(),
|
|
63
|
+
});
|
|
64
|
+
inline_submit_success(e, form, opts);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
parent.showAlerts([
|
|
67
|
+
{
|
|
68
|
+
type: "error",
|
|
69
|
+
msg: error.message ? error.message : "An error occured.",
|
|
70
|
+
},
|
|
71
|
+
]);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
45
75
|
async function saveAndContinue(e, action, k) {
|
|
46
76
|
const form = $(e).closest("form");
|
|
47
77
|
submitWithEmptyAction(form[0]);
|
|
@@ -105,6 +135,12 @@ async function login(e, entryPoint, isSignup) {
|
|
|
105
135
|
config.language = decodedJwt.user.language;
|
|
106
136
|
config.isPublicUser = false;
|
|
107
137
|
config.isOfflineMode = false;
|
|
138
|
+
await parent.insertUser({
|
|
139
|
+
id: config.user_id,
|
|
140
|
+
email: config.user_name,
|
|
141
|
+
role_id: config.role_id,
|
|
142
|
+
language: config.language,
|
|
143
|
+
});
|
|
108
144
|
await parent.setJwt(loginResult);
|
|
109
145
|
config.jwt = loginResult;
|
|
110
146
|
await parent.i18next.changeLanguage(config.language);
|
|
@@ -114,3 +114,11 @@ async function setJwt(jwt) {
|
|
|
114
114
|
await removeJwt();
|
|
115
115
|
await saltcorn.data.db.insert(jwtTableName, { jwt: jwt });
|
|
116
116
|
}
|
|
117
|
+
|
|
118
|
+
async function insertUser({ id, email, role_id, language }) {
|
|
119
|
+
await saltcorn.data.db.insert(
|
|
120
|
+
"users",
|
|
121
|
+
{ id, email, role_id, language },
|
|
122
|
+
{ ignoreExisting: true }
|
|
123
|
+
);
|
|
124
|
+
}
|