@saltcorn/mobile-app 0.9.5-beta.17 → 0.9.5-beta.19

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@saltcorn/mobile-app",
3
3
  "displayName": "Saltcorn mobile app",
4
- "version": "0.9.5-beta.17",
4
+ "version": "0.9.5-beta.19",
5
5
  "description": "Apache Cordova application with @saltcorn/markup",
6
6
  "main": "index.js",
7
7
  "scripts": {
package/www/index.html CHANGED
@@ -228,12 +228,15 @@
228
228
  if (mobileConfig.user_id) await gotoEntryView();
229
229
  else {
230
230
  const decodedJwt = jwt_decode(mobileConfig.jwt);
231
+ mobileConfig.user = decodedJwt.user;
232
+ // TODO remove these, use 'user' everywhere
231
233
  mobileConfig.role_id = decodedJwt.user.role_id
232
234
  ? decodedJwt.user.role_id
233
235
  : 100;
234
236
  mobileConfig.user_id = decodedJwt.user.id;
235
237
  mobileConfig.user_name = decodedJwt.user.email;
236
238
  mobileConfig.language = decodedJwt.user.language;
239
+
237
240
  mobileConfig.isPublicUser = false;
238
241
  }
239
242
  addRoute({ route: entryPoint, query: undefined });
@@ -364,12 +367,15 @@
364
367
  if ((networkDisabled && jwt) || (await checkJWT(jwt))) {
365
368
  const mobileConfig = state.mobileConfig;
366
369
  const decodedJwt = jwt_decode(mobileConfig.jwt);
370
+ mobileConfig.user = decodedJwt.user;
371
+ // TODO remove these, use 'user' everywhere
367
372
  mobileConfig.role_id = decodedJwt.user.role_id
368
373
  ? decodedJwt.user.role_id
369
374
  : 100;
370
375
  mobileConfig.user_id = decodedJwt.user.id;
371
376
  mobileConfig.user_name = decodedJwt.user.email;
372
377
  mobileConfig.language = decodedJwt.user.language;
378
+
373
379
  mobileConfig.isPublicUser = false;
374
380
  await i18next.changeLanguage(mobileConfig.language);
375
381
  if (mobileConfig.allowOfflineMode) {
@@ -419,9 +425,12 @@
419
425
  if (page.content) await replaceIframe(page.content, page.isFile);
420
426
  } else if (isPublicJwt(jwt)) {
421
427
  const config = state.mobileConfig;
428
+ config.user = { role_id: 100, user_name: "public", language: "en" };
429
+ // TODO remove these, use 'user' everywhere
422
430
  config.role_id = 100;
423
431
  config.user_name = "public";
424
432
  config.language = "en";
433
+
425
434
  config.isPublicUser = true;
426
435
  i18next.changeLanguage(config.language);
427
436
  addRoute({ route: entryPoint, query: undefined });
@@ -35,10 +35,7 @@ function MobileRequest({
35
35
  const mobileCfg = saltcorn.data.state.getState().mobileConfig;
36
36
  return mobileCfg?.language ? mobileCfg.language : "en";
37
37
  },
38
- user: {
39
- id: userId,
40
- role_id: roleId,
41
- },
38
+ user: cfg.user,
42
39
  flash: (type, msg) => {
43
40
  flashMessages.push({ type, msg });
44
41
  },
@@ -1,4 +1,4 @@
1
- /*global sbAdmin2Layout, apiCall, removeJwt, saltcorn, clearHistory*/
1
+ /*global sbAdmin2Layout, apiCall, removeJwt, saltcorn, clearHistory, MobileRequest, MobileResponse, getHeaders*/
2
2
 
3
3
  const prepareAuthForm = () => {
4
4
  return new saltcorn.data.models.Form({
@@ -35,11 +35,40 @@ const getAuthLinks = (current, entryPoint) => {
35
35
  return links;
36
36
  };
37
37
 
38
- const renderLoginView = (entryPoint, versionTag, alerts = []) => {
38
+ const renderLoginView = async (entryPoint, versionTag, alerts = []) => {
39
+ const state = saltcorn.data.state.getState();
39
40
  const form = prepareAuthForm(entryPoint);
40
41
  form.onSubmit = `javascript:loginFormSubmit(this, '${entryPoint}')`;
41
42
  form.submitLabel = "Login";
42
- return sbAdmin2Layout().authWrap({
43
+ const layout = sbAdmin2Layout();
44
+ const login_form_name = state.getConfig("login_form", "");
45
+ if (login_form_name) {
46
+ const login_form = saltcorn.data.models.View.findOne({
47
+ name: login_form_name,
48
+ });
49
+ if (login_form) {
50
+ const req = new MobileRequest();
51
+ const res = new MobileResponse();
52
+ const resp = await login_form.run_possibly_on_page({}, req, res);
53
+ if (login_form.default_render_page) {
54
+ return layout.wrap({
55
+ title: "Login",
56
+ no_menu: true,
57
+ body: resp,
58
+ alerts: [],
59
+ role: req.user ? req.user.role_id : 100,
60
+ req,
61
+ headers: getHeaders(),
62
+ brand: {
63
+ name: state.getConfig("site_name") || "Saltcorn",
64
+ logo: state.mobileConfig.encodedSiteLogo,
65
+ },
66
+ });
67
+ }
68
+ }
69
+ }
70
+
71
+ return layout.authWrap({
43
72
  title: "login",
44
73
  form: form,
45
74
  authLinks: getAuthLinks("login", entryPoint),
@@ -72,7 +101,7 @@ const renderSignupView = (entryPoint, versionTag) => {
72
101
  const getLoginView = async (context) => {
73
102
  const mobileConfig = saltcorn.data.state.getState().mobileConfig;
74
103
  return {
75
- content: renderLoginView(
104
+ content: await renderLoginView(
76
105
  mobileConfig.entry_point,
77
106
  mobileConfig.version_tag,
78
107
  context.alerts ? context.alerts : []
@@ -97,7 +126,7 @@ const logoutAction = async () => {
97
126
  clearHistory();
98
127
  config.jwt = undefined;
99
128
  return {
100
- content: renderLoginView(config.entry_point, config.version_tag),
129
+ content: await renderLoginView(config.entry_point, config.version_tag),
101
130
  };
102
131
  } else {
103
132
  console.log("unable to logout");
@@ -1,7 +1,8 @@
1
1
  /*global saltcorn, offlineHelper*/
2
2
 
3
3
  const getHeaders = () => {
4
- const config = saltcorn.data.state.getState().mobileConfig;
4
+ const state = saltcorn.data.state.getState();
5
+ const config = state.mobileConfig;
5
6
  const versionTag = config.version_tag;
6
7
  const stdHeaders = [
7
8
  { css: `static_assets/${versionTag}/saltcorn.css` },
@@ -9,7 +10,13 @@ const getHeaders = () => {
9
10
  { script: `static_assets/${versionTag}/dayjs.min.js` },
10
11
  { script: "js/utils/iframe_view_utils.js" },
11
12
  ];
12
- return [...stdHeaders, ...config.pluginHeaders];
13
+
14
+ let from_cfg = [];
15
+ if (state.getConfig("page_custom_css", ""))
16
+ from_cfg.push({ style: state.getConfig("page_custom_css", "") });
17
+ if (state.getConfig("page_custom_html", ""))
18
+ from_cfg.push({ headerTag: state.getConfig("page_custom_html", "") });
19
+ return [...stdHeaders, ...config.pluginHeaders, ...from_cfg];
13
20
  };
14
21
 
15
22
  const parseQuery = (queryStr) => {
@@ -27,13 +27,25 @@ async function execLink(url, linkSrc) {
27
27
  } else
28
28
  try {
29
29
  showLoadSpinner();
30
- const { path, query } = parent.splitPathQuery(url);
31
- await parent.handleRoute(`get${path}`, query);
30
+ if (url.startsWith("javascript:")) eval(url.substring(11));
31
+ else {
32
+ const { path, query } = parent.splitPathQuery(url);
33
+ await parent.handleRoute(`get${path}`, query);
34
+ }
32
35
  } finally {
33
36
  removeLoadSpinner();
34
37
  }
35
38
  }
36
39
 
40
+ async function runUrl(url, method = "get") {
41
+ const { path, query } = parent.splitPathQuery(url);
42
+ const page = await parent.router.resolve({
43
+ pathname: `${method}${path}`,
44
+ query: query,
45
+ });
46
+ return page.content;
47
+ }
48
+
37
49
  async function execNavbarLink(url) {
38
50
  $(".navbar-toggler").click();
39
51
  execLink(url);
@@ -186,14 +198,10 @@ async function login(e, entryPoint, isSignup) {
186
198
  config.user_name = decodedJwt.user.email;
187
199
  config.user_id = decodedJwt.user.id;
188
200
  config.language = decodedJwt.user.language;
201
+ config.user = decodedJwt.user;
189
202
  config.isPublicUser = false;
190
203
  config.isOfflineMode = false;
191
- await parent.insertUser({
192
- id: config.user_id,
193
- email: config.user_name,
194
- role_id: config.role_id,
195
- language: config.language,
196
- });
204
+ await parent.insertUser(config.user);
197
205
  await parent.setJwt(loginResult);
198
206
  config.jwt = loginResult;
199
207
  await parent.i18next.changeLanguage(config.language);
@@ -245,9 +253,16 @@ async function publicLogin(entryPoint) {
245
253
  const loginResult = await loginRequest({ isPublic: true });
246
254
  if (typeof loginResult === "string") {
247
255
  const config = parent.saltcorn.data.state.getState().mobileConfig;
256
+ config.user = {
257
+ role_id: 100,
258
+ user_name: "public",
259
+ language: "en",
260
+ };
261
+ // TODO remove these, use 'user' everywhere
248
262
  config.role_id = 100;
249
263
  config.user_name = "public";
250
264
  config.language = "en";
265
+
251
266
  config.isPublicUser = true;
252
267
  await parent.setJwt(loginResult);
253
268
  config.jwt = loginResult;
@@ -321,7 +336,13 @@ async function signupFormSubmit(e, entryView) {
321
336
 
322
337
  async function loginFormSubmit(e, entryView) {
323
338
  try {
324
- await login(e, entryView, false);
339
+ let safeEntryView = entryView;
340
+ if (!safeEntryView) {
341
+ const config = parent.saltcorn.data.state.getState().mobileConfig;
342
+ if (!config.entry_point) throw new Error("Unable to find an entry-point");
343
+ safeEntryView = config.entry_point;
344
+ }
345
+ await login(e, safeEntryView, false);
325
346
  } catch (error) {
326
347
  parent.errorAlert(error);
327
348
  }
@@ -464,6 +485,10 @@ async function gopage(n, pagesize, viewIdentifier, extra) {
464
485
  );
465
486
  }
466
487
 
488
+ function ajax_modal(url, opts = {}) {
489
+ mobile_modal(url, opts);
490
+ }
491
+
467
492
  async function mobile_modal(url, opts = {}) {
468
493
  if ($("#scmodal").length === 0) {
469
494
  $("body").append(`<div id="scmodal" class="modal">
@@ -473,6 +498,13 @@ async function mobile_modal(url, opts = {}) {
473
498
  <h5 class="modal-title">Modal title</h5>
474
499
  <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
475
500
  </button>
501
+ <div
502
+ id="modal-toasts-area"
503
+ class="toast-container position-fixed top-0 start-50 p-0"
504
+ style: "z-index: 7000;"
505
+ aria-live="polite"
506
+ aria-atomic="true">
507
+ </div>
476
508
  </div>
477
509
  <div class="modal-body">
478
510
  <p>Modal body text goes here.</p>