@saltcorn/mobile-app 1.1.0-beta.11 → 1.1.0-beta.12
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/.babelrc +3 -0
- package/build_scripts/modify_android_manifest.js +47 -0
- package/build_scripts/modify_gradle_cfg.js +34 -0
- package/package.json +20 -11
- package/src/.eslintrc +21 -0
- package/src/helpers/api.js +41 -0
- package/src/helpers/auth.js +191 -0
- package/src/helpers/common.js +175 -0
- package/{www/js/utils/table_utils.js → src/helpers/db_schema.js} +18 -40
- package/src/helpers/file_system.js +102 -0
- package/{www/js/utils/global_utils.js → src/helpers/navigation.js} +169 -335
- package/src/helpers/offline_mode.js +645 -0
- package/src/index.js +20 -0
- package/src/init.js +424 -0
- package/src/routing/index.js +98 -0
- package/{www/js → src/routing}/mocks/request.js +5 -5
- package/{www/js → src/routing}/mocks/response.js +1 -1
- package/{www/js → src/routing}/routes/api.js +10 -15
- package/{www/js → src/routing}/routes/auth.js +12 -6
- package/{www/js → src/routing}/routes/delete.js +9 -6
- package/{www/js → src/routing}/routes/edit.js +9 -6
- package/src/routing/routes/error.js +6 -0
- package/{www/js → src/routing}/routes/fields.js +7 -2
- package/{www/js → src/routing}/routes/page.js +14 -9
- package/{www/js → src/routing}/routes/sync.js +9 -5
- package/{www/js → src/routing}/routes/view.js +16 -11
- package/{www/js/routes/common.js → src/routing/utils.js} +15 -13
- package/webpack.config.js +31 -0
- package/www/data/encoded_site_logo.js +1 -0
- package/www/index.html +23 -491
- package/www/js/{utils/iframe_view_utils.js → iframe_view_utils.js} +137 -269
- package/config.xml +0 -27
- package/res/icon/android/icon.png +0 -0
- package/res/screen/android/splash-icon.png +0 -0
- package/res/screen/ios/Default@2x~universal~anyany.png +0 -0
- package/www/js/routes/error.js +0 -5
- package/www/js/routes/init.js +0 -76
- package/www/js/utils/file_helpers.js +0 -108
- package/www/js/utils/offline_mode_helper.js +0 -625
|
@@ -30,8 +30,12 @@ async function execLink(url, linkSrc) {
|
|
|
30
30
|
showLoadSpinner();
|
|
31
31
|
if (url.startsWith("javascript:")) eval(url.substring(11));
|
|
32
32
|
else {
|
|
33
|
-
const { path, query } =
|
|
34
|
-
|
|
33
|
+
const { path, query } =
|
|
34
|
+
parent.saltcorn.mobileApp.navigation.splitPathQuery(url);
|
|
35
|
+
await parent.saltcorn.mobileApp.navigation.handleRoute(
|
|
36
|
+
`get${path}`,
|
|
37
|
+
query
|
|
38
|
+
);
|
|
35
39
|
}
|
|
36
40
|
} finally {
|
|
37
41
|
removeLoadSpinner();
|
|
@@ -39,8 +43,9 @@ async function execLink(url, linkSrc) {
|
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
async function runUrl(url, method = "get") {
|
|
42
|
-
const { path, query } =
|
|
43
|
-
|
|
46
|
+
const { path, query } =
|
|
47
|
+
parent.saltcorn.mobileApp.navigation.splitPathQuery(url);
|
|
48
|
+
const page = await parent.saltcorn.mobileApp.navigation.router.resolve({
|
|
44
49
|
pathname: `${method}${path}`,
|
|
45
50
|
query: query,
|
|
46
51
|
});
|
|
@@ -84,17 +89,23 @@ async function formSubmit(e, urlSuffix, viewname, noSubmitCb, matchingState) {
|
|
|
84
89
|
const tokens = entry[1].split("/");
|
|
85
90
|
const fileName = tokens[tokens.length - 1];
|
|
86
91
|
const directory = tokens.splice(0, tokens.length - 1).join("/");
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
92
|
+
const { buffer, file } =
|
|
93
|
+
await parent.saltcorn.mobileApp.fileSystem.readBinaryCordova(
|
|
94
|
+
fileName,
|
|
95
|
+
directory
|
|
96
|
+
);
|
|
97
|
+
files[entry[0]] = {
|
|
98
|
+
blob: new Blob([buffer], { type: file.type }),
|
|
99
|
+
fileObj: file,
|
|
100
|
+
};
|
|
90
101
|
} else if (!matchingState) urlParams.append(entry[0], entry[1]);
|
|
91
102
|
else data[entry[0]] = entry[1];
|
|
92
103
|
}
|
|
93
104
|
}
|
|
94
105
|
const queryStr = !matchingState
|
|
95
106
|
? urlParams.toString()
|
|
96
|
-
: parent.currentQuery() || "";
|
|
97
|
-
await parent.handleRoute(
|
|
107
|
+
: parent.saltcorn.mobileApp.navigation.currentQuery() || "";
|
|
108
|
+
await parent.saltcorn.mobileApp.navigation.handleRoute(
|
|
98
109
|
`post${urlSuffix}${viewname}`,
|
|
99
110
|
queryStr,
|
|
100
111
|
files,
|
|
@@ -116,13 +127,13 @@ async function inline_local_submit(e, opts1) {
|
|
|
116
127
|
urlParams.append(entry[0], entry[1]);
|
|
117
128
|
}
|
|
118
129
|
const url = form.attr("action");
|
|
119
|
-
await parent.router.resolve({
|
|
130
|
+
await parent.saltcorn.mobileApp.navigation.router.resolve({
|
|
120
131
|
pathname: `post${url}`,
|
|
121
132
|
query: urlParams.toString(),
|
|
122
133
|
});
|
|
123
134
|
inline_submit_success(e, form, opts);
|
|
124
135
|
} catch (error) {
|
|
125
|
-
parent.showAlerts([
|
|
136
|
+
parent.saltcorn.mobileApp.common.showAlerts([
|
|
126
137
|
{
|
|
127
138
|
type: "error",
|
|
128
139
|
msg: error.message ? error.message : "An error occured.",
|
|
@@ -145,7 +156,7 @@ async function saveAndContinue(e, action, k) {
|
|
|
145
156
|
const form = $(e).closest("form");
|
|
146
157
|
submitWithEmptyAction(form[0]);
|
|
147
158
|
const queryStr = new URLSearchParams(new FormData(form[0])).toString();
|
|
148
|
-
const res = await parent.router.resolve({
|
|
159
|
+
const res = await parent.saltcorn.mobileApp.navigation.router.resolve({
|
|
149
160
|
pathname: `post${action}`,
|
|
150
161
|
query: queryStr,
|
|
151
162
|
xhr: true,
|
|
@@ -162,95 +173,16 @@ async function saveAndContinue(e, action, k) {
|
|
|
162
173
|
}
|
|
163
174
|
}
|
|
164
175
|
|
|
165
|
-
async function loginRequest({ email, password, isSignup, isPublic }) {
|
|
166
|
-
const opts = isPublic
|
|
167
|
-
? {
|
|
168
|
-
method: "GET",
|
|
169
|
-
path: "/auth/login-with/jwt",
|
|
170
|
-
}
|
|
171
|
-
: isSignup
|
|
172
|
-
? {
|
|
173
|
-
method: "POST",
|
|
174
|
-
path: "/auth/signup",
|
|
175
|
-
body: {
|
|
176
|
-
email,
|
|
177
|
-
password,
|
|
178
|
-
},
|
|
179
|
-
}
|
|
180
|
-
: {
|
|
181
|
-
method: "GET",
|
|
182
|
-
path: "/auth/login-with/jwt",
|
|
183
|
-
params: {
|
|
184
|
-
email,
|
|
185
|
-
password,
|
|
186
|
-
},
|
|
187
|
-
};
|
|
188
|
-
const response = await parent.apiCall(opts);
|
|
189
|
-
return response.data;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
176
|
async function login(e, entryPoint, isSignup) {
|
|
193
177
|
try {
|
|
194
178
|
showLoadSpinner();
|
|
195
179
|
const formData = new FormData(e);
|
|
196
|
-
|
|
180
|
+
await parent.saltcorn.mobileApp.auth.login({
|
|
197
181
|
email: formData.get("email"),
|
|
198
182
|
password: formData.get("password"),
|
|
199
183
|
isSignup,
|
|
184
|
+
entryPoint,
|
|
200
185
|
});
|
|
201
|
-
if (typeof loginResult === "string") {
|
|
202
|
-
// use it as a token
|
|
203
|
-
const decodedJwt = parent.jwt_decode(loginResult);
|
|
204
|
-
const state = parent.saltcorn.data.state.getState();
|
|
205
|
-
const config = state.mobileConfig;
|
|
206
|
-
config.role_id = decodedJwt.user.role_id ? decodedJwt.user.role_id : 100;
|
|
207
|
-
config.user_name = decodedJwt.user.email;
|
|
208
|
-
config.user_id = decodedJwt.user.id;
|
|
209
|
-
config.language = decodedJwt.user.language;
|
|
210
|
-
config.user = decodedJwt.user;
|
|
211
|
-
config.isPublicUser = false;
|
|
212
|
-
config.isOfflineMode = false;
|
|
213
|
-
await parent.insertUser(config.user);
|
|
214
|
-
await parent.setJwt(loginResult);
|
|
215
|
-
config.jwt = loginResult;
|
|
216
|
-
await parent.i18next.changeLanguage(config.language);
|
|
217
|
-
const alerts = [];
|
|
218
|
-
if (config.allowOfflineMode) {
|
|
219
|
-
const { offlineUser, hasOfflineData } =
|
|
220
|
-
(await parent.offlineHelper.getLastOfflineSession()) || {};
|
|
221
|
-
if (!offlineUser || offlineUser === config.user_name) {
|
|
222
|
-
await parent.offlineHelper.sync();
|
|
223
|
-
} else {
|
|
224
|
-
if (hasOfflineData)
|
|
225
|
-
alerts.push({
|
|
226
|
-
type: "warning",
|
|
227
|
-
msg: `'${offlineUser}' has not yet uploaded offline data.`,
|
|
228
|
-
});
|
|
229
|
-
else {
|
|
230
|
-
await deleteOfflineData(true);
|
|
231
|
-
await parent.offlineHelper.sync();
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
alerts.push({
|
|
236
|
-
type: "success",
|
|
237
|
-
msg: parent.i18next.t("Welcome, %s!", {
|
|
238
|
-
postProcess: "sprintf",
|
|
239
|
-
sprintf: [config.user_name],
|
|
240
|
-
}),
|
|
241
|
-
});
|
|
242
|
-
parent.addRoute({ route: entryPoint, query: undefined });
|
|
243
|
-
const page = await parent.router.resolve({
|
|
244
|
-
pathname: entryPoint,
|
|
245
|
-
fullWrap: true,
|
|
246
|
-
alerts,
|
|
247
|
-
});
|
|
248
|
-
if (page.content) await parent.replaceIframe(page.content, page.isFile);
|
|
249
|
-
} else if (loginResult?.alerts) {
|
|
250
|
-
parent.showAlerts(loginResult?.alerts);
|
|
251
|
-
} else {
|
|
252
|
-
throw new Error("The login failed.");
|
|
253
|
-
}
|
|
254
186
|
} finally {
|
|
255
187
|
removeLoadSpinner();
|
|
256
188
|
}
|
|
@@ -259,77 +191,16 @@ async function login(e, entryPoint, isSignup) {
|
|
|
259
191
|
async function publicLogin(entryPoint) {
|
|
260
192
|
try {
|
|
261
193
|
showLoadSpinner();
|
|
262
|
-
|
|
263
|
-
if (typeof loginResult === "string") {
|
|
264
|
-
const config = parent.saltcorn.data.state.getState().mobileConfig;
|
|
265
|
-
config.user = {
|
|
266
|
-
role_id: 100,
|
|
267
|
-
user_name: "public",
|
|
268
|
-
language: "en",
|
|
269
|
-
};
|
|
270
|
-
// TODO remove these, use 'user' everywhere
|
|
271
|
-
config.role_id = 100;
|
|
272
|
-
config.user_name = "public";
|
|
273
|
-
config.language = "en";
|
|
274
|
-
|
|
275
|
-
config.isPublicUser = true;
|
|
276
|
-
await parent.setJwt(loginResult);
|
|
277
|
-
config.jwt = loginResult;
|
|
278
|
-
parent.i18next.changeLanguage(config.language);
|
|
279
|
-
parent.addRoute({ route: entryPoint, query: undefined });
|
|
280
|
-
const page = await parent.router.resolve({
|
|
281
|
-
pathname: entryPoint,
|
|
282
|
-
fullWrap: true,
|
|
283
|
-
alerts: [
|
|
284
|
-
{
|
|
285
|
-
type: "success",
|
|
286
|
-
msg: parent.i18next.t("Welcome to %s!", {
|
|
287
|
-
postProcess: "sprintf",
|
|
288
|
-
sprintf: [
|
|
289
|
-
parent.saltcorn.data.state.getState().getConfig("site_name") ||
|
|
290
|
-
"Saltcorn",
|
|
291
|
-
],
|
|
292
|
-
}),
|
|
293
|
-
},
|
|
294
|
-
],
|
|
295
|
-
});
|
|
296
|
-
if (page.content) await parent.replaceIframe(page.content, page.isFile);
|
|
297
|
-
} else if (loginResult?.alerts) {
|
|
298
|
-
parent.showAlerts(loginResult?.alerts);
|
|
299
|
-
} else {
|
|
300
|
-
throw new Error("The login failed.");
|
|
301
|
-
}
|
|
302
|
-
} catch (error) {
|
|
303
|
-
console.log(error);
|
|
304
|
-
parent.showAlerts([
|
|
305
|
-
{
|
|
306
|
-
type: "error",
|
|
307
|
-
msg: error.message ? error.message : "An error occured.",
|
|
308
|
-
},
|
|
309
|
-
]);
|
|
310
|
-
throw error;
|
|
194
|
+
await parent.saltcorn.mobileApp.auth.publicLogin(entryPoint);
|
|
311
195
|
} finally {
|
|
312
196
|
removeLoadSpinner();
|
|
313
197
|
}
|
|
314
198
|
}
|
|
315
199
|
|
|
316
200
|
async function logout() {
|
|
317
|
-
const config = parent.saltcorn.data.state.getState().mobileConfig;
|
|
318
201
|
try {
|
|
319
202
|
showLoadSpinner();
|
|
320
|
-
|
|
321
|
-
pathname: "get/auth/logout",
|
|
322
|
-
entryView: config.entry_point,
|
|
323
|
-
versionTag: config.version_tag,
|
|
324
|
-
});
|
|
325
|
-
await parent.replaceIframe(page.content);
|
|
326
|
-
} catch (error) {
|
|
327
|
-
parent.showAlerts([
|
|
328
|
-
{
|
|
329
|
-
type: "error",
|
|
330
|
-
msg: error.message ? error.message : "An error occured.",
|
|
331
|
-
},
|
|
332
|
-
]);
|
|
203
|
+
await parent.saltcorn.mobileApp.auth.logout();
|
|
333
204
|
} finally {
|
|
334
205
|
removeLoadSpinner();
|
|
335
206
|
}
|
|
@@ -339,7 +210,7 @@ async function signupFormSubmit(e, entryView) {
|
|
|
339
210
|
try {
|
|
340
211
|
await login(e, entryView, true);
|
|
341
212
|
} catch (error) {
|
|
342
|
-
parent.errorAlert(error);
|
|
213
|
+
parent.saltcorn.mobileApp.common.errorAlert(error);
|
|
343
214
|
}
|
|
344
215
|
}
|
|
345
216
|
|
|
@@ -353,7 +224,7 @@ async function loginFormSubmit(e, entryView) {
|
|
|
353
224
|
}
|
|
354
225
|
await login(e, safeEntryView, false);
|
|
355
226
|
} catch (error) {
|
|
356
|
-
parent.errorAlert(error);
|
|
227
|
+
parent.saltcorn.mobileApp.common.errorAlert(error);
|
|
357
228
|
}
|
|
358
229
|
}
|
|
359
230
|
|
|
@@ -363,8 +234,9 @@ async function local_post_btn(e) {
|
|
|
363
234
|
const form = $(e).closest("form");
|
|
364
235
|
const url = form.attr("action");
|
|
365
236
|
const method = form.attr("method");
|
|
366
|
-
const { path, query } =
|
|
367
|
-
|
|
237
|
+
const { path, query } =
|
|
238
|
+
parent.saltcorn.mobileApp.navigation.splitPathQuery(url);
|
|
239
|
+
await parent.saltcorn.mobileApp.navigation.handleRoute(
|
|
368
240
|
`${method}${path}`,
|
|
369
241
|
combineFormAndQuery(form, query)
|
|
370
242
|
);
|
|
@@ -382,7 +254,7 @@ async function stateFormSubmit(e, path) {
|
|
|
382
254
|
try {
|
|
383
255
|
showLoadSpinner();
|
|
384
256
|
const formQuery = new URLSearchParams(new FormData(e)).toString();
|
|
385
|
-
await parent.handleRoute(path, formQuery);
|
|
257
|
+
await parent.saltcorn.mobileApp.navigation.handleRoute(path, formQuery);
|
|
386
258
|
} finally {
|
|
387
259
|
removeLoadSpinner();
|
|
388
260
|
}
|
|
@@ -432,7 +304,7 @@ async function set_state_fields(kvs, href) {
|
|
|
432
304
|
try {
|
|
433
305
|
showLoadSpinner();
|
|
434
306
|
let queryParams = [];
|
|
435
|
-
let currentQuery = parent.currentQuery();
|
|
307
|
+
let currentQuery = parent.saltcorn.mobileApp.navigation.currentQuery();
|
|
436
308
|
if (Object.keys(kvs).some((k) => !is_paging_param(k))) {
|
|
437
309
|
currentQuery = invalidate_pagings(currentQuery);
|
|
438
310
|
}
|
|
@@ -446,7 +318,10 @@ async function set_state_fields(kvs, href) {
|
|
|
446
318
|
for (const [k, v] of new URLSearchParams(currentQuery).entries()) {
|
|
447
319
|
queryParams.push(`${k}=${v}`);
|
|
448
320
|
}
|
|
449
|
-
await parent.handleRoute(
|
|
321
|
+
await parent.saltcorn.mobileApp.navigation.handleRoute(
|
|
322
|
+
href,
|
|
323
|
+
queryParams.join("&")
|
|
324
|
+
);
|
|
450
325
|
} finally {
|
|
451
326
|
removeLoadSpinner();
|
|
452
327
|
}
|
|
@@ -455,8 +330,15 @@ async function set_state_fields(kvs, href) {
|
|
|
455
330
|
async function set_state_field(key, value) {
|
|
456
331
|
try {
|
|
457
332
|
showLoadSpinner();
|
|
458
|
-
const query = updateQueryStringParameter(
|
|
459
|
-
|
|
333
|
+
const query = updateQueryStringParameter(
|
|
334
|
+
parent.saltcorn.mobileApp.navigation.currentQuery(),
|
|
335
|
+
key,
|
|
336
|
+
value
|
|
337
|
+
);
|
|
338
|
+
await parent.saltcorn.mobileApp.navigation.handleRoute(
|
|
339
|
+
parent.saltcorn.mobileApp.navigation.currentLocation(),
|
|
340
|
+
query
|
|
341
|
+
);
|
|
460
342
|
} finally {
|
|
461
343
|
removeLoadSpinner();
|
|
462
344
|
}
|
|
@@ -465,9 +347,12 @@ async function set_state_field(key, value) {
|
|
|
465
347
|
async function unset_state_field(key) {
|
|
466
348
|
try {
|
|
467
349
|
showLoadSpinner();
|
|
468
|
-
const href = parent.currentLocation();
|
|
469
|
-
const query = removeQueryStringParameter(
|
|
470
|
-
|
|
350
|
+
const href = parent.saltcorn.mobileApp.navigation.currentLocation();
|
|
351
|
+
const query = removeQueryStringParameter(
|
|
352
|
+
parent.saltcorn.mobileApp.navigation.currentLocation(),
|
|
353
|
+
key
|
|
354
|
+
);
|
|
355
|
+
await parent.saltcorn.mobileApp.navigation.handleRoute(href, query);
|
|
471
356
|
} finally {
|
|
472
357
|
removeLoadSpinner();
|
|
473
358
|
}
|
|
@@ -479,7 +364,7 @@ async function sortby(k, desc, viewIdentifier) {
|
|
|
479
364
|
[`_${viewIdentifier}_sortby`]: k,
|
|
480
365
|
[`_${viewIdentifier}_sortdesc`]: desc ? "on" : { unset: true },
|
|
481
366
|
},
|
|
482
|
-
parent.currentLocation()
|
|
367
|
+
parent.saltcorn.mobileApp.navigation.currentLocation()
|
|
483
368
|
);
|
|
484
369
|
}
|
|
485
370
|
|
|
@@ -490,7 +375,7 @@ async function gopage(n, pagesize, viewIdentifier, extra) {
|
|
|
490
375
|
[`_${viewIdentifier}_page`]: n,
|
|
491
376
|
[`_${viewIdentifier}_pagesize`]: pagesize,
|
|
492
377
|
},
|
|
493
|
-
parent.currentLocation()
|
|
378
|
+
parent.saltcorn.mobileApp.navigation.currentLocation()
|
|
494
379
|
);
|
|
495
380
|
}
|
|
496
381
|
|
|
@@ -529,18 +414,19 @@ async function mobile_modal(url, opts = {}) {
|
|
|
529
414
|
if (opts.submitReload === false) $("#scmodal").addClass("no-submit-reload");
|
|
530
415
|
else $("#scmodal").removeClass("no-submit-reload");
|
|
531
416
|
try {
|
|
532
|
-
const { path, query } =
|
|
417
|
+
const { path, query } =
|
|
418
|
+
parent.saltcorn.mobileApp.navigation.splitPathQuery(url);
|
|
533
419
|
const mobileConfig = parent.saltcorn.data.state.getState().mobileConfig;
|
|
534
420
|
if (
|
|
535
421
|
mobileConfig.networkState === "none" &&
|
|
536
422
|
mobileConfig.allowOfflineMode &&
|
|
537
423
|
!mobileConfig.isOfflineMode
|
|
538
424
|
) {
|
|
539
|
-
await parent.
|
|
540
|
-
parent.clearHistory();
|
|
541
|
-
await parent.gotoEntryView();
|
|
425
|
+
await parent.saltcorn.mobileApp.offlineMode.startOfflineMode();
|
|
426
|
+
parent.saltcorn.mobileApp.navigation.clearHistory();
|
|
427
|
+
await parent.saltcorn.mobileApp.navigation.gotoEntryView();
|
|
542
428
|
} else {
|
|
543
|
-
const page = await parent.router.resolve({
|
|
429
|
+
const page = await parent.saltcorn.mobileApp.navigation.router.resolve({
|
|
544
430
|
pathname: `get${path}`,
|
|
545
431
|
query: query,
|
|
546
432
|
alerts: [],
|
|
@@ -553,7 +439,7 @@ async function mobile_modal(url, opts = {}) {
|
|
|
553
439
|
// onOpen onClose initialize_page?
|
|
554
440
|
}
|
|
555
441
|
} catch (error) {
|
|
556
|
-
parent.showAlerts([
|
|
442
|
+
parent.saltcorn.mobileApp.common.showAlerts([
|
|
557
443
|
{
|
|
558
444
|
type: "error",
|
|
559
445
|
msg: error.message ? error.message : "An error occured.",
|
|
@@ -569,14 +455,15 @@ function closeModal() {
|
|
|
569
455
|
async function local_post(url, args) {
|
|
570
456
|
try {
|
|
571
457
|
showLoadSpinner();
|
|
572
|
-
const result = await parent.router.resolve({
|
|
458
|
+
const result = await parent.saltcorn.mobileApp.navigation.router.resolve({
|
|
573
459
|
pathname: `post${url}`,
|
|
574
460
|
data: args,
|
|
575
461
|
});
|
|
576
|
-
if (result.redirect)
|
|
462
|
+
if (result.redirect)
|
|
463
|
+
await parent.saltcorn.mobileApp.navigation.handleRoute(result.redirect);
|
|
577
464
|
else await common_done(result, "", false);
|
|
578
465
|
} catch (error) {
|
|
579
|
-
parent.errorAlert(error);
|
|
466
|
+
parent.saltcorn.mobileApp.common.errorAlert(error);
|
|
580
467
|
} finally {
|
|
581
468
|
removeLoadSpinner();
|
|
582
469
|
}
|
|
@@ -585,17 +472,18 @@ async function local_post(url, args) {
|
|
|
585
472
|
async function local_post_json(url, data, cb) {
|
|
586
473
|
try {
|
|
587
474
|
showLoadSpinner();
|
|
588
|
-
const result = await parent.router.resolve({
|
|
475
|
+
const result = await parent.saltcorn.mobileApp.navigation.router.resolve({
|
|
589
476
|
pathname: `post${url}`,
|
|
590
477
|
data: data,
|
|
591
|
-
query: parent.currentQuery(),
|
|
478
|
+
query: parent.saltcorn.mobileApp.navigation.currentQuery(),
|
|
592
479
|
});
|
|
593
480
|
if (result.server_eval) await evalServerCode(url);
|
|
594
|
-
if (result.redirect)
|
|
481
|
+
if (result.redirect)
|
|
482
|
+
await parent.saltcorn.mobileApp.navigation.handleRoute(result.redirect);
|
|
595
483
|
else await common_done(result, "", false);
|
|
596
484
|
if (cb?.success) cb.success(result);
|
|
597
485
|
} catch (error) {
|
|
598
|
-
parent.errorAlert(error);
|
|
486
|
+
parent.saltcorn.mobileApp.common.errorAlert(error);
|
|
599
487
|
if (cb?.error) cb.error(error);
|
|
600
488
|
} finally {
|
|
601
489
|
removeLoadSpinner();
|
|
@@ -603,7 +491,7 @@ async function local_post_json(url, data, cb) {
|
|
|
603
491
|
}
|
|
604
492
|
|
|
605
493
|
async function evalServerCode(url) {
|
|
606
|
-
await parent.apiCall({
|
|
494
|
+
await parent.saltcorn.mobileApp.api.apiCall({
|
|
607
495
|
method: "POST",
|
|
608
496
|
path: url,
|
|
609
497
|
});
|
|
@@ -626,7 +514,7 @@ async function make_unique_field(
|
|
|
626
514
|
)}=${encodeURIComponent(value)}&fields=${encodeURIComponent(field_name)}`;
|
|
627
515
|
try {
|
|
628
516
|
// TODO ch support local tables
|
|
629
|
-
const response = await parent.apiCall({
|
|
517
|
+
const response = await parent.saltcorn.mobileApp.api.apiCall({
|
|
630
518
|
method: "GET",
|
|
631
519
|
path,
|
|
632
520
|
});
|
|
@@ -643,7 +531,7 @@ async function make_unique_field(
|
|
|
643
531
|
);
|
|
644
532
|
}
|
|
645
533
|
} catch (error) {
|
|
646
|
-
parent.showAlerts([
|
|
534
|
+
parent.saltcorn.mobileApp.common.showAlerts([
|
|
647
535
|
{
|
|
648
536
|
type: "error",
|
|
649
537
|
msg: "unable to 'make_unique_field'",
|
|
@@ -688,11 +576,14 @@ async function select_id(id) {
|
|
|
688
576
|
try {
|
|
689
577
|
showLoadSpinner();
|
|
690
578
|
const newQuery = updateQueryStringParameter(
|
|
691
|
-
parent.currentQuery(),
|
|
579
|
+
parent.saltcorn.mobileApp.navigation.currentQuery(),
|
|
692
580
|
"id",
|
|
693
581
|
id
|
|
694
582
|
);
|
|
695
|
-
await parent.handleRoute(
|
|
583
|
+
await parent.handleRoute(
|
|
584
|
+
parent.saltcorn.mobileApp.navigation.currentLocation(),
|
|
585
|
+
newQuery
|
|
586
|
+
);
|
|
696
587
|
} finally {
|
|
697
588
|
removeLoadSpinner();
|
|
698
589
|
}
|
|
@@ -703,9 +594,16 @@ async function check_state_field(that) {
|
|
|
703
594
|
showLoadSpinner();
|
|
704
595
|
const name = that.name;
|
|
705
596
|
const newQuery = that.checked
|
|
706
|
-
? updateQueryStringParameter(
|
|
597
|
+
? updateQueryStringParameter(
|
|
598
|
+
parent.saltcorn.mobileApp.navigation.currentQuery(),
|
|
599
|
+
name,
|
|
600
|
+
that.value
|
|
601
|
+
)
|
|
707
602
|
: removeQueryStringParameter(name);
|
|
708
|
-
await parent.handleRoute(
|
|
603
|
+
await parent.saltcorn.mobileApp.navigation.handleRoute(
|
|
604
|
+
parent.saltcorn.mobileApp.navigation.currentLocation(),
|
|
605
|
+
newQuery
|
|
606
|
+
);
|
|
709
607
|
} finally {
|
|
710
608
|
removeLoadSpinner();
|
|
711
609
|
}
|
|
@@ -714,7 +612,10 @@ async function check_state_field(that) {
|
|
|
714
612
|
async function clear_state() {
|
|
715
613
|
try {
|
|
716
614
|
showLoadSpinner();
|
|
717
|
-
await parent.handleRoute(
|
|
615
|
+
await parent.saltcorn.mobileApp.navigation.handleRoute(
|
|
616
|
+
parent.saltcorn.mobileApp.navigation.currentLocation(),
|
|
617
|
+
undefined
|
|
618
|
+
);
|
|
718
619
|
} finally {
|
|
719
620
|
removeLoadSpinner();
|
|
720
621
|
}
|
|
@@ -728,7 +629,7 @@ async function view_post(viewnameOrElem, route, data, onDone, sendState) {
|
|
|
728
629
|
.closest("[data-sc-embed-viewname]")
|
|
729
630
|
.attr("data-sc-embed-viewname");
|
|
730
631
|
const buildQuery = () => {
|
|
731
|
-
const query = parent.currentQuery();
|
|
632
|
+
const query = parent.saltcorn.mobileApp.navigation.currentQuery();
|
|
732
633
|
return query ? `?${query}` : "";
|
|
733
634
|
};
|
|
734
635
|
const mobileConfig = parent.saltcorn.data.state.getState().mobileConfig;
|
|
@@ -741,13 +642,13 @@ async function view_post(viewnameOrElem, route, data, onDone, sendState) {
|
|
|
741
642
|
mobileConfig.isOfflineMode ||
|
|
742
643
|
(view?.table_id && mobileConfig.localTableIds.indexOf(view.table_id) >= 0)
|
|
743
644
|
) {
|
|
744
|
-
respData = await parent.router.resolve({
|
|
645
|
+
respData = await parent.saltcorn.mobileApp.navigation.router.resolve({
|
|
745
646
|
pathname: `post/view/${viewname}/${route}`,
|
|
746
647
|
data,
|
|
747
648
|
query,
|
|
748
649
|
});
|
|
749
650
|
} else {
|
|
750
|
-
const response = await parent.apiCall({
|
|
651
|
+
const response = await parent.saltcorn.mobileApp.api.apiCall({
|
|
751
652
|
method: "POST",
|
|
752
653
|
path: "/view/" + viewname + "/" + route + query,
|
|
753
654
|
body: data,
|
|
@@ -760,7 +661,7 @@ async function view_post(viewnameOrElem, route, data, onDone, sendState) {
|
|
|
760
661
|
if (onDone) await onDone(respData);
|
|
761
662
|
await common_done(respData, viewname, false);
|
|
762
663
|
} catch (error) {
|
|
763
|
-
parent.errorAlert(error);
|
|
664
|
+
parent.saltcorn.mobileApp.common.errorAlert(error);
|
|
764
665
|
} finally {
|
|
765
666
|
removeLoadSpinner();
|
|
766
667
|
}
|
|
@@ -783,37 +684,41 @@ async function switchNetworkMode() {
|
|
|
783
684
|
const state = parent.saltcorn.data.state.getState();
|
|
784
685
|
const { isOfflineMode, networkState } = state.mobileConfig;
|
|
785
686
|
if (!isOfflineMode) {
|
|
786
|
-
await parent.
|
|
787
|
-
parent.clearHistory();
|
|
788
|
-
parent.addRoute({ route: "/" });
|
|
789
|
-
parent.addRoute({
|
|
790
|
-
|
|
687
|
+
await parent.saltcorn.mobileApp.offlineMode.startOfflineMode();
|
|
688
|
+
parent.saltcorn.mobileApp.navigation.clearHistory();
|
|
689
|
+
parent.saltcorn.mobileApp.navigation.addRoute({ route: "/" });
|
|
690
|
+
parent.saltcorn.mobileApp.navigation.addRoute({
|
|
691
|
+
route: "get/sync/sync_settings",
|
|
692
|
+
});
|
|
693
|
+
parent.saltcorn.mobileApp.common.showAlerts(
|
|
791
694
|
[
|
|
792
695
|
{
|
|
793
696
|
type: "info",
|
|
794
|
-
msg: parent.
|
|
697
|
+
msg: parent.saltcorn.mobileApp.offlineMode.getOfflineMsg(),
|
|
795
698
|
},
|
|
796
699
|
],
|
|
797
700
|
false
|
|
798
701
|
);
|
|
799
|
-
parent.clearAlerts();
|
|
702
|
+
parent.saltcorn.mobileApp.common.clearAlerts();
|
|
800
703
|
} else {
|
|
801
704
|
if (networkState === "none")
|
|
802
705
|
throw new Error("No internet connection is available.");
|
|
803
|
-
await parent.
|
|
804
|
-
parent.clearHistory();
|
|
805
|
-
parent.addRoute({ route: "/" });
|
|
806
|
-
parent.addRoute({
|
|
807
|
-
|
|
706
|
+
await parent.saltcorn.mobileApp.offlineMode.endOfflineMode();
|
|
707
|
+
parent.saltcorn.mobileApp.navigation.clearHistory();
|
|
708
|
+
parent.saltcorn.mobileApp.navigation.addRoute({ route: "/" });
|
|
709
|
+
parent.saltcorn.mobileApp.navigation.addRoute({
|
|
710
|
+
route: "get/sync/sync_settings",
|
|
711
|
+
});
|
|
712
|
+
parent.saltcorn.mobileApp.common.showAlerts([
|
|
808
713
|
{
|
|
809
714
|
type: "info",
|
|
810
715
|
msg: "You are online again.",
|
|
811
716
|
},
|
|
812
717
|
]);
|
|
813
|
-
parent.clearTopAlerts();
|
|
718
|
+
parent.saltcorn.mobileApp.common.clearTopAlerts();
|
|
814
719
|
}
|
|
815
720
|
} catch (error) {
|
|
816
|
-
parent.showAlerts([
|
|
721
|
+
parent.saltcorn.mobileApp.common.showAlerts([
|
|
817
722
|
{
|
|
818
723
|
type: "error",
|
|
819
724
|
msg: `Unable to change the network mode: ${
|
|
@@ -833,7 +738,7 @@ async function callSync() {
|
|
|
833
738
|
try {
|
|
834
739
|
const mobileConfig = parent.saltcorn.data.state.getState().mobileConfig;
|
|
835
740
|
if (mobileConfig.networkState === "none") {
|
|
836
|
-
parent.showAlerts([
|
|
741
|
+
parent.saltcorn.mobileApp.common.showAlerts([
|
|
837
742
|
{
|
|
838
743
|
type: "error",
|
|
839
744
|
msg: "You don't have an internet connection.",
|
|
@@ -842,10 +747,10 @@ async function callSync() {
|
|
|
842
747
|
} else {
|
|
843
748
|
const wasOffline = mobileConfig.isOfflineMode;
|
|
844
749
|
showLoadSpinner();
|
|
845
|
-
await parent.
|
|
846
|
-
parent.clearAlerts();
|
|
750
|
+
await parent.saltcorn.mobileApp.offlineMode.sync();
|
|
751
|
+
parent.saltcorn.mobileApp.common.clearAlerts();
|
|
847
752
|
if (!wasOffline) {
|
|
848
|
-
parent.showAlerts([
|
|
753
|
+
parent.saltcorn.mobileApp.common.showAlerts([
|
|
849
754
|
{
|
|
850
755
|
type: "info",
|
|
851
756
|
msg: "Synchronized your offline data.",
|
|
@@ -853,38 +758,41 @@ async function callSync() {
|
|
|
853
758
|
]);
|
|
854
759
|
} else {
|
|
855
760
|
setNetworSwitcherOn();
|
|
856
|
-
parent.clearHistory();
|
|
857
|
-
parent.addRoute({ route: "/" });
|
|
858
|
-
parent.addRoute({
|
|
859
|
-
|
|
761
|
+
parent.saltcorn.mobileApp.navigation.clearHistory();
|
|
762
|
+
parent.saltcorn.mobileApp.navigation.addRoute({ route: "/" });
|
|
763
|
+
parent.saltcorn.mobileApp.navigation.addRoute({
|
|
764
|
+
route: "get/sync/sync_settings",
|
|
765
|
+
});
|
|
766
|
+
parent.saltcorn.mobileApp.common.showAlerts([
|
|
860
767
|
{
|
|
861
768
|
type: "info",
|
|
862
769
|
msg: "Synchronized your offline data, you are online again.",
|
|
863
770
|
},
|
|
864
771
|
]);
|
|
865
|
-
parent.clearTopAlerts();
|
|
772
|
+
parent.saltcorn.mobileApp.common.clearTopAlerts();
|
|
866
773
|
}
|
|
867
774
|
}
|
|
868
775
|
} catch (error) {
|
|
869
776
|
console.log(error);
|
|
870
|
-
parent.errorAlert(error);
|
|
777
|
+
parent.saltcorn.mobileApp.common.errorAlert(error);
|
|
871
778
|
} finally {
|
|
872
779
|
removeLoadSpinner();
|
|
873
780
|
}
|
|
874
781
|
}
|
|
875
782
|
|
|
876
783
|
async function deleteOfflineDataClicked() {
|
|
877
|
-
const lastOfflineSession =
|
|
878
|
-
|
|
784
|
+
const lastOfflineSession =
|
|
785
|
+
await parent.saltcorn.mobileApp.offlineMode.getLastOfflineSession();
|
|
786
|
+
const { user } = parent.saltcorn.data.state.getState().mobileConfig;
|
|
879
787
|
if (!lastOfflineSession?.offlineUser) {
|
|
880
|
-
parent.showAlerts([
|
|
788
|
+
parent.saltcorn.mobileApp.common.showAlerts([
|
|
881
789
|
{
|
|
882
790
|
type: "error",
|
|
883
791
|
msg: "You don't have any offline data.",
|
|
884
792
|
},
|
|
885
793
|
]);
|
|
886
|
-
} else if (lastOfflineSession.offlineUser !==
|
|
887
|
-
parent.showAlerts([
|
|
794
|
+
} else if (lastOfflineSession.offlineUser !== user.email) {
|
|
795
|
+
parent.saltcorn.mobileApp.common.showAlerts([
|
|
888
796
|
{
|
|
889
797
|
type: "error",
|
|
890
798
|
msg: `The offline data is owned by '${lastOfflineSession.offlineUser}'.`,
|
|
@@ -895,30 +803,8 @@ async function deleteOfflineDataClicked() {
|
|
|
895
803
|
}
|
|
896
804
|
}
|
|
897
805
|
|
|
898
|
-
async function deleteOfflineData(noFeedback) {
|
|
899
|
-
const mobileConfig = parent.saltcorn.data.state.getState().mobileConfig;
|
|
900
|
-
try {
|
|
901
|
-
mobileConfig.inLoadState = true;
|
|
902
|
-
if (!noFeedback) showLoadSpinner();
|
|
903
|
-
await parent.offlineHelper.clearLocalData(false);
|
|
904
|
-
await parent.offlineHelper.setHasOfflineData(false);
|
|
905
|
-
if (!noFeedback)
|
|
906
|
-
parent.showAlerts([
|
|
907
|
-
{
|
|
908
|
-
type: "info",
|
|
909
|
-
msg: "Deleted your offline data.",
|
|
910
|
-
},
|
|
911
|
-
]);
|
|
912
|
-
} catch (error) {
|
|
913
|
-
parent.errorAlert(error);
|
|
914
|
-
} finally {
|
|
915
|
-
mobileConfig.inLoadState = false;
|
|
916
|
-
if (!noFeedback) removeLoadSpinner();
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
|
|
920
806
|
function showLoadSpinner() {
|
|
921
|
-
if (!parent.isHtmlFile()) {
|
|
807
|
+
if (!parent.saltcorn.mobileApp.navigation.isHtmlFile()) {
|
|
922
808
|
const spinner = $("#scspinner");
|
|
923
809
|
if (spinner.length === 0) {
|
|
924
810
|
$("body").append(`
|
|
@@ -961,7 +847,7 @@ function showLoadSpinner() {
|
|
|
961
847
|
}
|
|
962
848
|
|
|
963
849
|
function removeLoadSpinner() {
|
|
964
|
-
if (!parent.isHtmlFile()) {
|
|
850
|
+
if (!parent.saltcorn.mobileApp.navigation.isHtmlFile()) {
|
|
965
851
|
const spinner = $("#scspinner");
|
|
966
852
|
if (spinner.length > 0) {
|
|
967
853
|
const count = parseInt(spinner.attr("spinner-count")) - 1;
|
|
@@ -977,29 +863,11 @@ function removeLoadSpinner() {
|
|
|
977
863
|
* @param {*} fieldName
|
|
978
864
|
*/
|
|
979
865
|
async function getPicture(fieldName) {
|
|
980
|
-
const cameraOptions = {
|
|
981
|
-
quality: 50,
|
|
982
|
-
encodingType: parent.Camera.EncodingType.JPEG,
|
|
983
|
-
destinationType: parent.Camera.DestinationType.FILE_URI,
|
|
984
|
-
};
|
|
985
|
-
const getPictureWithPromise = () => {
|
|
986
|
-
return new Promise((resolve, reject) => {
|
|
987
|
-
parent.navigator.camera.getPicture(
|
|
988
|
-
(imageDate) => {
|
|
989
|
-
return resolve(imageDate);
|
|
990
|
-
},
|
|
991
|
-
(message) => {
|
|
992
|
-
return reject(message);
|
|
993
|
-
},
|
|
994
|
-
cameraOptions
|
|
995
|
-
);
|
|
996
|
-
});
|
|
997
|
-
};
|
|
998
866
|
try {
|
|
999
867
|
const form = $(`#cptbtn${fieldName}`).closest("form");
|
|
1000
868
|
const onsubmit = form.attr("onsubmit");
|
|
1001
869
|
form.attr("onsubmit", "javascript:void(0)");
|
|
1002
|
-
const fileURI = await
|
|
870
|
+
const fileURI = await parent.saltcorn.mobileApp.common.takePhoto("uri");
|
|
1003
871
|
form.attr("onsubmit", onsubmit);
|
|
1004
872
|
const inputId = `input${fieldName}`;
|
|
1005
873
|
form.find(`#${inputId}`).remove();
|
|
@@ -1009,7 +877,7 @@ async function getPicture(fieldName) {
|
|
|
1009
877
|
const tokens = fileURI.split("/");
|
|
1010
878
|
$(`#cpt-file-name-${fieldName}`).text(tokens[tokens.length - 1]);
|
|
1011
879
|
} catch (error) {
|
|
1012
|
-
parent.errorAlert(error);
|
|
880
|
+
parent.saltcorn.mobileApp.common.errorAlert(error);
|
|
1013
881
|
}
|
|
1014
882
|
}
|
|
1015
883
|
|
|
@@ -1024,7 +892,7 @@ async function updateMatchingRows(e, viewname) {
|
|
|
1024
892
|
true
|
|
1025
893
|
);
|
|
1026
894
|
} catch (error) {
|
|
1027
|
-
parent.errorAlert(error);
|
|
895
|
+
parent.saltcorn.mobileApp.common.errorAlert(error);
|
|
1028
896
|
}
|
|
1029
897
|
}
|
|
1030
898
|
|