@saltcorn/server 0.9.4-beta.2 → 0.9.4-beta.21

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.
Files changed (182) hide show
  1. package/app.js +16 -1
  2. package/auth/admin.js +19 -3
  3. package/auth/routes.js +8 -2
  4. package/help/JavaScript action code.tmd +1 -0
  5. package/load_plugins.js +8 -2
  6. package/locales/en.json +34 -1
  7. package/markup/admin.js +22 -18
  8. package/package.json +10 -9
  9. package/public/dayjslocales/af.js +1 -0
  10. package/public/dayjslocales/am.js +1 -0
  11. package/public/dayjslocales/ar-dz.js +1 -0
  12. package/public/dayjslocales/ar-iq.js +1 -0
  13. package/public/dayjslocales/ar-kw.js +1 -0
  14. package/public/dayjslocales/ar-ly.js +1 -0
  15. package/public/dayjslocales/ar-ma.js +1 -0
  16. package/public/dayjslocales/ar-sa.js +1 -0
  17. package/public/dayjslocales/ar-tn.js +1 -0
  18. package/public/dayjslocales/ar.js +1 -0
  19. package/public/dayjslocales/az.js +1 -0
  20. package/public/dayjslocales/be.js +1 -0
  21. package/public/dayjslocales/bg.js +1 -0
  22. package/public/dayjslocales/bi.js +1 -0
  23. package/public/dayjslocales/bm.js +1 -0
  24. package/public/dayjslocales/bn-bd.js +1 -0
  25. package/public/dayjslocales/bn.js +1 -0
  26. package/public/dayjslocales/bo.js +1 -0
  27. package/public/dayjslocales/br.js +1 -0
  28. package/public/dayjslocales/bs.js +1 -0
  29. package/public/dayjslocales/ca.js +1 -0
  30. package/public/dayjslocales/cs.js +1 -0
  31. package/public/dayjslocales/cv.js +1 -0
  32. package/public/dayjslocales/cy.js +1 -0
  33. package/public/dayjslocales/da.js +1 -0
  34. package/public/dayjslocales/de-at.js +1 -0
  35. package/public/dayjslocales/de-ch.js +1 -0
  36. package/public/dayjslocales/de.js +1 -0
  37. package/public/dayjslocales/dv.js +1 -0
  38. package/public/dayjslocales/el.js +1 -0
  39. package/public/dayjslocales/en-au.js +1 -0
  40. package/public/dayjslocales/en-ca.js +1 -0
  41. package/public/dayjslocales/en-gb.js +1 -0
  42. package/public/dayjslocales/en-ie.js +1 -0
  43. package/public/dayjslocales/en-il.js +1 -0
  44. package/public/dayjslocales/en-in.js +1 -0
  45. package/public/dayjslocales/en-nz.js +1 -0
  46. package/public/dayjslocales/en-sg.js +1 -0
  47. package/public/dayjslocales/en-tt.js +1 -0
  48. package/public/dayjslocales/en.js +1 -0
  49. package/public/dayjslocales/eo.js +1 -0
  50. package/public/dayjslocales/es-do.js +1 -0
  51. package/public/dayjslocales/es-mx.js +1 -0
  52. package/public/dayjslocales/es-pr.js +1 -0
  53. package/public/dayjslocales/es-us.js +1 -0
  54. package/public/dayjslocales/es.js +1 -0
  55. package/public/dayjslocales/et.js +1 -0
  56. package/public/dayjslocales/eu.js +1 -0
  57. package/public/dayjslocales/fa.js +1 -0
  58. package/public/dayjslocales/fi.js +1 -0
  59. package/public/dayjslocales/fo.js +1 -0
  60. package/public/dayjslocales/fr-ca.js +1 -0
  61. package/public/dayjslocales/fr-ch.js +1 -0
  62. package/public/dayjslocales/fr.js +1 -0
  63. package/public/dayjslocales/fy.js +1 -0
  64. package/public/dayjslocales/ga.js +1 -0
  65. package/public/dayjslocales/gd.js +1 -0
  66. package/public/dayjslocales/gl.js +1 -0
  67. package/public/dayjslocales/gom-latn.js +1 -0
  68. package/public/dayjslocales/gu.js +1 -0
  69. package/public/dayjslocales/he.js +1 -0
  70. package/public/dayjslocales/hi.js +1 -0
  71. package/public/dayjslocales/hr.js +1 -0
  72. package/public/dayjslocales/ht.js +1 -0
  73. package/public/dayjslocales/hu.js +1 -0
  74. package/public/dayjslocales/hy-am.js +1 -0
  75. package/public/dayjslocales/id.js +1 -0
  76. package/public/dayjslocales/is.js +1 -0
  77. package/public/dayjslocales/it-ch.js +1 -0
  78. package/public/dayjslocales/it.js +1 -0
  79. package/public/dayjslocales/ja.js +1 -0
  80. package/public/dayjslocales/jv.js +1 -0
  81. package/public/dayjslocales/ka.js +1 -0
  82. package/public/dayjslocales/kk.js +1 -0
  83. package/public/dayjslocales/km.js +1 -0
  84. package/public/dayjslocales/kn.js +1 -0
  85. package/public/dayjslocales/ko.js +1 -0
  86. package/public/dayjslocales/ku.js +1 -0
  87. package/public/dayjslocales/ky.js +1 -0
  88. package/public/dayjslocales/lb.js +1 -0
  89. package/public/dayjslocales/lo.js +1 -0
  90. package/public/dayjslocales/lt.js +1 -0
  91. package/public/dayjslocales/lv.js +1 -0
  92. package/public/dayjslocales/me.js +1 -0
  93. package/public/dayjslocales/mi.js +1 -0
  94. package/public/dayjslocales/mk.js +1 -0
  95. package/public/dayjslocales/ml.js +1 -0
  96. package/public/dayjslocales/mn.js +1 -0
  97. package/public/dayjslocales/mr.js +1 -0
  98. package/public/dayjslocales/ms-my.js +1 -0
  99. package/public/dayjslocales/ms.js +1 -0
  100. package/public/dayjslocales/mt.js +1 -0
  101. package/public/dayjslocales/my.js +1 -0
  102. package/public/dayjslocales/nb.js +1 -0
  103. package/public/dayjslocales/ne.js +1 -0
  104. package/public/dayjslocales/nl-be.js +1 -0
  105. package/public/dayjslocales/nl.js +1 -0
  106. package/public/dayjslocales/nn.js +1 -0
  107. package/public/dayjslocales/oc-lnc.js +1 -0
  108. package/public/dayjslocales/pa-in.js +1 -0
  109. package/public/dayjslocales/pl.js +1 -0
  110. package/public/dayjslocales/pt-br.js +1 -0
  111. package/public/dayjslocales/pt.js +1 -0
  112. package/public/dayjslocales/rn.js +1 -0
  113. package/public/dayjslocales/ro.js +1 -0
  114. package/public/dayjslocales/ru.js +1 -0
  115. package/public/dayjslocales/rw.js +1 -0
  116. package/public/dayjslocales/sd.js +1 -0
  117. package/public/dayjslocales/se.js +1 -0
  118. package/public/dayjslocales/si.js +1 -0
  119. package/public/dayjslocales/sk.js +1 -0
  120. package/public/dayjslocales/sl.js +1 -0
  121. package/public/dayjslocales/sq.js +1 -0
  122. package/public/dayjslocales/sr-cyrl.js +1 -0
  123. package/public/dayjslocales/sr.js +1 -0
  124. package/public/dayjslocales/ss.js +1 -0
  125. package/public/dayjslocales/sv-fi.js +1 -0
  126. package/public/dayjslocales/sv.js +1 -0
  127. package/public/dayjslocales/sw.js +1 -0
  128. package/public/dayjslocales/ta.js +1 -0
  129. package/public/dayjslocales/te.js +1 -0
  130. package/public/dayjslocales/tet.js +1 -0
  131. package/public/dayjslocales/tg.js +1 -0
  132. package/public/dayjslocales/th.js +1 -0
  133. package/public/dayjslocales/tk.js +1 -0
  134. package/public/dayjslocales/tl-ph.js +1 -0
  135. package/public/dayjslocales/tlh.js +1 -0
  136. package/public/dayjslocales/tr.js +1 -0
  137. package/public/dayjslocales/tzl.js +1 -0
  138. package/public/dayjslocales/tzm-latn.js +1 -0
  139. package/public/dayjslocales/tzm.js +1 -0
  140. package/public/dayjslocales/ug-cn.js +1 -0
  141. package/public/dayjslocales/uk.js +1 -0
  142. package/public/dayjslocales/ur.js +1 -0
  143. package/public/dayjslocales/uz-latn.js +1 -0
  144. package/public/dayjslocales/uz.js +1 -0
  145. package/public/dayjslocales/vi.js +1 -0
  146. package/public/dayjslocales/x-pseudo.js +1 -0
  147. package/public/dayjslocales/yo.js +1 -0
  148. package/public/dayjslocales/zh-cn.js +1 -0
  149. package/public/dayjslocales/zh-hk.js +1 -0
  150. package/public/dayjslocales/zh-tw.js +1 -0
  151. package/public/dayjslocales/zh.js +1 -0
  152. package/public/gridedit.js +2 -2
  153. package/public/log_viewer_utils.js +156 -0
  154. package/public/saltcorn-builder.css +62 -3
  155. package/public/saltcorn-common.js +8 -0
  156. package/public/saltcorn.js +30 -9
  157. package/public/tabulator_bootstrap5.min.css +1 -0
  158. package/restart_watcher.js +1 -0
  159. package/routes/actions.js +175 -18
  160. package/routes/admin.js +77 -5
  161. package/routes/common_lists.js +344 -152
  162. package/routes/fields.js +29 -5
  163. package/routes/files.js +3 -1
  164. package/routes/homepage.js +2 -1
  165. package/routes/list.js +5 -0
  166. package/routes/page.js +30 -13
  167. package/routes/page_groupedit.js +104 -83
  168. package/routes/pageedit.js +23 -7
  169. package/routes/tables.js +56 -6
  170. package/routes/tag_entries.js +18 -5
  171. package/routes/tags.js +65 -12
  172. package/routes/utils.js +23 -2
  173. package/routes/view.js +21 -2
  174. package/routes/viewedit.js +70 -4
  175. package/serve.js +177 -10
  176. package/tests/admin.test.js +17 -11
  177. package/tests/page_group.test.js +1 -0
  178. package/tests/table.test.js +1 -5
  179. package/tests/view.test.js +115 -15
  180. package/tests/viewedit.test.js +52 -29
  181. package/wrapper.js +11 -3
  182. package/public/relation_helpers.js +0 -351
@@ -382,13 +382,13 @@ describe("actions", () => {
382
382
  .send("table_id=2")
383
383
  .send("name=mynewaction")
384
384
  .send("when_trigger=Insert")
385
- .expect(toRedirect("/actions/configure/1"));
385
+ .expect(toRedirect("/actions/configure/3"));
386
386
  });
387
387
  it("show edit", async () => {
388
388
  const app = await getApp({ disableCsrf: true });
389
389
  const loginCookie = await getAdminLoginCookie();
390
390
  await request(app)
391
- .get("/actions/edit/1")
391
+ .get("/actions/edit/3")
392
392
  .set("Cookie", loginCookie)
393
393
  .expect(toInclude("Edit trigger"))
394
394
  .expect(toInclude("run_js_code"));
@@ -397,7 +397,7 @@ describe("actions", () => {
397
397
  const app = await getApp({ disableCsrf: true });
398
398
  const loginCookie = await getAdminLoginCookie();
399
399
  await request(app)
400
- .get("/actions/configure/1")
400
+ .get("/actions/configure/3")
401
401
  .set("Cookie", loginCookie)
402
402
  .expect(toInclude("Configure trigger"))
403
403
  .expect(toInclude("Code"));
@@ -406,7 +406,7 @@ describe("actions", () => {
406
406
  const app = await getApp({ disableCsrf: true });
407
407
  const loginCookie = await getAdminLoginCookie();
408
408
  await request(app)
409
- .post("/actions/configure/1")
409
+ .post("/actions/configure/3")
410
410
  .set("Cookie", loginCookie)
411
411
  .send("code=console.log(12345678)")
412
412
  .expect(toRedirect("/actions/"));
@@ -415,7 +415,7 @@ describe("actions", () => {
415
415
  const app = await getApp({ disableCsrf: true });
416
416
  const loginCookie = await getAdminLoginCookie();
417
417
  await request(app)
418
- .get("/actions/testrun/1")
418
+ .get("/actions/testrun/3")
419
419
  .set("Cookie", loginCookie)
420
420
  .expect(toInclude("12345678"));
421
421
  });
@@ -423,7 +423,7 @@ describe("actions", () => {
423
423
  const app = await getApp({ disableCsrf: true });
424
424
  const loginCookie = await getAdminLoginCookie();
425
425
  await request(app)
426
- .post("/actions/configure/1")
426
+ .post("/actions/configure/3")
427
427
  .set("Cookie", loginCookie)
428
428
  .send("code=1")
429
429
  .expect(toRedirect("/actions/"));
@@ -432,7 +432,7 @@ describe("actions", () => {
432
432
  const app = await getApp({ disableCsrf: true });
433
433
  const loginCookie = await getAdminLoginCookie();
434
434
  await request(app)
435
- .get("/actions/testrun/1")
435
+ .get("/actions/testrun/2")
436
436
  .set("Cookie", loginCookie)
437
437
  .expect(toRedirect("/actions/"));
438
438
  });
@@ -446,9 +446,9 @@ describe("actions", () => {
446
446
  .send("action=run_js_code")
447
447
  .send("when_trigger=API+call")
448
448
  .send("min_role=1")
449
- .expect(toRedirect("/actions/configure/2"));
449
+ .expect(toRedirect("/actions/configure/4"));
450
450
  await request(app)
451
- .post("/actions/configure/2")
451
+ .post("/actions/configure/4")
452
452
  .set("Cookie", loginCookie)
453
453
  .send("code=return 27")
454
454
  .expect(toRedirect("/actions/"));
@@ -463,7 +463,7 @@ describe("actions", () => {
463
463
  const app = await getApp({ disableCsrf: true });
464
464
  const loginCookie = await getAdminLoginCookie();
465
465
  await request(app)
466
- .post("/actions/delete/1")
466
+ .post("/actions/delete/3")
467
467
  .set("Cookie", loginCookie)
468
468
  .expect(toRedirect("/actions/"));
469
469
  });
@@ -555,7 +555,7 @@ describe("diagram", () => {
555
555
  });
556
556
 
557
557
  /**
558
- * Diagram tests
558
+ * Tags tests
559
559
  */
560
560
  describe("tags", () => {
561
561
  itShouldRedirectUnauthToLogin("/tag");
@@ -604,6 +604,12 @@ describe("tags", () => {
604
604
  .expect(toRedirect("/tag"));
605
605
  });
606
606
  });
607
+
608
+ describe("server logs viewer", () => {
609
+ itShouldRedirectUnauthToLogin("/admin/dev/logs_viewer");
610
+ itShouldIncludeTextForAdmin("/admin/dev/logs_viewer", "Server logs");
611
+ });
612
+
607
613
  /**
608
614
  * Clear all tests
609
615
  */
@@ -73,6 +73,7 @@ describe("edit Page groups", () => {
73
73
  name: nameAfterUpdate,
74
74
  description: null,
75
75
  min_role: 100,
76
+ random_allocation: false,
76
77
  });
77
78
  });
78
79
 
@@ -254,11 +254,7 @@ Gordon Kane, 218`;
254
254
  await request(app)
255
255
  .get("/table/")
256
256
  .set("Cookie", loginCookie)
257
- .expect(
258
- toInclude(
259
- "cannot drop table books because other objects depend on it"
260
- )
261
- );
257
+ .expect(toInclude("has views. Delete these first"));
262
258
  });
263
259
  });
264
260
  describe("deletion to table with row ownership", () => {
@@ -419,6 +419,10 @@ describe("update matching rows", () => {
419
419
  await field.update({ is_unique: false });
420
420
  });
421
421
 
422
+ afterAll(async () => {
423
+ await resetToFixtures();
424
+ });
425
+
422
426
  it("update matching books normal", async () => {
423
427
  const table = Table.findOne({ name: "books" });
424
428
  await updateMatchingRows({
@@ -755,7 +759,7 @@ describe("relation path to query and state", () => {
755
759
  .expect(toNotInclude("album B"));
756
760
  });
757
761
 
758
- it("OneToOneSHow", async () => {
762
+ it("OneToOneShow", async () => {
759
763
  const app = await getApp({ disableCsrf: true });
760
764
  const loginCookie = await getAdminLoginCookie();
761
765
  await request(app)
@@ -805,7 +809,7 @@ describe("relation path to query and state", () => {
805
809
  .expect(toInclude(`value="artist B"`));
806
810
  });
807
811
 
808
- it("Parent", async () => {
812
+ it("Parent one layer", async () => {
809
813
  const app = await getApp({ disableCsrf: true });
810
814
  const loginCookie = await getAdminLoginCookie();
811
815
  await request(app)
@@ -833,6 +837,28 @@ describe("relation path to query and state", () => {
833
837
  .expect(toInclude("No row selected"));
834
838
  });
835
839
 
840
+ it("Parent two layers", async () => {
841
+ const app = await getApp({ disableCsrf: true });
842
+ const loginCookie = await getAdminLoginCookie();
843
+ await request(app)
844
+ .get(`/view/show_patient_with_publisher?id=2`)
845
+ .set("Cookie", loginCookie)
846
+ // view link
847
+ .expect(toInclude("/view/show_publisher?.patients.favbook.publisher=2"))
848
+ // embedded show
849
+ .expect(toInclude("Michael Douglas"))
850
+ .expect(toInclude("AK Press"));
851
+
852
+ await request(app)
853
+ .get(`/view/show_patient_with_publisher?id=1`)
854
+ .set("Cookie", loginCookie)
855
+ // view link
856
+ .expect(toInclude("/view/show_publisher?.patients.favbook.publisher=1"))
857
+ // embedded show
858
+ .expect(toInclude("Kirk Douglas"))
859
+ .expect(toInclude("No row selected"));
860
+ });
861
+
836
862
  it("RelationPath", async () => {
837
863
  const app = await getApp({ disableCsrf: true });
838
864
  const loginCookie = await getAdminLoginCookie();
@@ -873,11 +899,23 @@ describe("edit-in-edit with relation path and legacy", () => {
873
899
  const app = await getApp({ disableCsrf: true });
874
900
  const loginCookie = await getAdminLoginCookie();
875
901
  await request(app)
876
- .get("/view/edit_department_with_edit_in_edit_legacy?id=1")
902
+ .get("/view/edit_department_with_edit_in_edit_relation_path?id=1")
877
903
  .set("Cookie", loginCookie)
878
904
  .expect(toInclude("add_repeater"));
879
-
880
- // TODO post
905
+ await request(app)
906
+ .post("/view/edit_department_with_edit_in_edit_relation_path?id=1")
907
+ .set("Cookie", loginCookie)
908
+ .send({
909
+ department_0: "1",
910
+ department_1: "1",
911
+ id: "1",
912
+ id_0: "1",
913
+ id_1: "2",
914
+ name: "my_department",
915
+ name_0: "manager",
916
+ name_1: "my_employee",
917
+ })
918
+ .expect(toRedirect("/"));
881
919
  });
882
920
 
883
921
  it("edit-in-edit with relation path two layer", async () => {
@@ -887,10 +925,21 @@ describe("edit-in-edit with relation path and legacy", () => {
887
925
  .get("/view/edit_cover_with_edit_artist_on_album_rel_path?id=1")
888
926
  .set("Cookie", loginCookie)
889
927
  .expect(toInclude("add_repeater"));
890
-
891
- // TODO post
928
+ await request(app)
929
+ .post("/view/edit_cover_with_edit_artist_on_album_rel_path?id=1")
930
+ .set("Cookie", loginCookie)
931
+ .send({
932
+ album_0: "1",
933
+ album_1: "1",
934
+ artist_0: "1",
935
+ artist_1: "2",
936
+ id: "1",
937
+ id_0: "1",
938
+ id_1: "3",
939
+ name: "green cover",
940
+ })
941
+ .expect(toRedirect("/"));
892
942
  });
893
-
894
943
  it("edit-in-edit legacy one layer", async () => {
895
944
  const app = await getApp({ disableCsrf: true });
896
945
  const loginCookie = await getAdminLoginCookie();
@@ -898,8 +947,20 @@ describe("edit-in-edit with relation path and legacy", () => {
898
947
  .get("/view/edit_department_with_edit_in_edit_legacy?id=1")
899
948
  .set("Cookie", loginCookie)
900
949
  .expect(toInclude("add_repeater"));
901
-
902
- // TODO post
950
+ await request(app)
951
+ .post("/view/edit_department_with_edit_in_edit_legacy?id=1")
952
+ .set("Cookie", loginCookie)
953
+ .send({
954
+ department_0: "1",
955
+ department_1: "1",
956
+ id: "1",
957
+ id_0: "1",
958
+ id_1: "2",
959
+ name: "my_department",
960
+ name_0: "manager",
961
+ name_1: "my_employee",
962
+ })
963
+ .expect(toRedirect("/"));
903
964
  });
904
965
 
905
966
  it("edit-in-edit with relation path two layer", async () => {
@@ -909,8 +970,20 @@ describe("edit-in-edit with relation path and legacy", () => {
909
970
  .get("/view/edit_cover_with_edit_artist_on_album_rel_path?id=1")
910
971
  .set("Cookie", loginCookie)
911
972
  .expect(toInclude("add_repeater"));
912
-
913
- // TODO post
973
+ await request(app)
974
+ .post("/view/edit_cover_with_edit_artist_on_album_rel_path?id=1")
975
+ .set("Cookie", loginCookie)
976
+ .send({
977
+ album_0: "1",
978
+ album_1: "1",
979
+ artist_0: "1",
980
+ artist_1: "2",
981
+ id: "1",
982
+ id_0: "1",
983
+ id_1: "3",
984
+ name: "green cover",
985
+ })
986
+ .expect(toRedirect("/"));
914
987
  });
915
988
 
916
989
  it("edit-in-edit legacy two layer", async () => {
@@ -920,8 +993,20 @@ describe("edit-in-edit with relation path and legacy", () => {
920
993
  .get("/view/edit_cover_with_edit_artist_on_album_legacy?id=1")
921
994
  .set("Cookie", loginCookie)
922
995
  .expect(toInclude("add_repeater"));
923
-
924
- // TODO post
996
+ await request(app)
997
+ .post("/view/edit_cover_with_edit_artist_on_album_legacy?id=1")
998
+ .set("Cookie", loginCookie)
999
+ .send({
1000
+ album_0: "1",
1001
+ album_1: "1",
1002
+ artist_0: "1",
1003
+ artist_1: "2",
1004
+ id: "1",
1005
+ id_0: "1",
1006
+ id_1: "3",
1007
+ name: "green cover",
1008
+ })
1009
+ .expect(toRedirect("/"));
925
1010
  });
926
1011
  });
927
1012
 
@@ -982,6 +1067,21 @@ describe("legacy relations with relation path", () => {
982
1067
  await request(app)
983
1068
  .get("/view/authoredit_with_show?id=1")
984
1069
  .set("Cookie", loginCookie)
985
- .expect(toInclude(["Herman Melville", "agi"]));
1070
+ .expect(toInclude("Herman Melville"));
1071
+ });
1072
+
1073
+ it("edit-view with independent list", async () => {
1074
+ const app = await getApp({ disableCsrf: true });
1075
+ const loginCookie = await getAdminLoginCookie();
1076
+ await request(app)
1077
+ .get("/view/authoredit_with_independent_list")
1078
+ .set("Cookie", loginCookie)
1079
+ .expect(toInclude("Herman Melville"))
1080
+ .expect(toInclude("Delete"));
1081
+ await request(app)
1082
+ .get("/view/authoredit_with_independent_list?id=1")
1083
+ .set("Cookie", loginCookie)
1084
+ .expect(toInclude("Herman Melville"))
1085
+ .expect(toInclude("Delete"));
986
1086
  });
987
1087
  });
@@ -78,6 +78,37 @@ describe("viewedit edit endpoint", () => {
78
78
  });
79
79
 
80
80
  describe("viewedit new List", () => {
81
+ const columns = [
82
+ { type: "Field", field_name: "author" },
83
+ { type: "Field", field_name: "pages" },
84
+ ];
85
+ const layout = {
86
+ besides: [
87
+ {
88
+ contents: {
89
+ type: "field",
90
+ fieldview: "as_text",
91
+ field_name: "author",
92
+ configuration: {},
93
+ },
94
+ alignment: "Default",
95
+ header_label: "Author",
96
+ col_width_units: "px",
97
+ },
98
+ {
99
+ contents: {
100
+ type: "field",
101
+ fieldview: "show",
102
+ field_name: "pages",
103
+ configuration: {},
104
+ },
105
+ alignment: "Default",
106
+ header_label: "Pages",
107
+ col_width_units: "px",
108
+ },
109
+ ],
110
+ list_columns: true,
111
+ };
81
112
  itShouldRedirectUnauthToLogin("/viewedit/new");
82
113
 
83
114
  it("show new view", async () => {
@@ -117,11 +148,8 @@ describe("viewedit new List", () => {
117
148
  .post("/viewedit/config/mybooklist")
118
149
  .send("contextEnc=" + ctx)
119
150
  .send("stepName=Columns")
120
- .send("type_0=Field")
121
- .send("field_name_0=author")
122
- .send("type_1=Field")
123
- .send("field_name_1=pages")
124
- .send("create_view_display=Link")
151
+ .send("columns=" + encodeURIComponent(JSON.stringify(columns)))
152
+ .send("layout=" + encodeURIComponent(JSON.stringify(layout)))
125
153
  .set("Cookie", loginCookie)
126
154
  .expect(toInclude("Default state"));
127
155
  });
@@ -205,6 +233,23 @@ describe("viewedit new List", () => {
205
233
  });
206
234
 
207
235
  describe("viewedit new List with one field", () => {
236
+ const columns = [{ type: "Field", field_name: "author", state_field: "on" }];
237
+ const layout = {
238
+ besides: [
239
+ {
240
+ contents: {
241
+ type: "field",
242
+ fieldview: "as_text",
243
+ field_name: "author",
244
+ configuration: {},
245
+ },
246
+ alignment: "Default",
247
+ header_label: "Author",
248
+ col_width_units: "px",
249
+ },
250
+ ],
251
+ list_columns: true,
252
+ };
208
253
  it("submit new view", async () => {
209
254
  const loginCookie = await getAdminLoginCookie();
210
255
 
@@ -234,9 +279,8 @@ describe("viewedit new List with one field", () => {
234
279
  .post("/viewedit/config/mybooklist1")
235
280
  .send("contextEnc=" + ctx)
236
281
  .send("stepName=Columns")
237
- .send("type_0=Field")
238
- .send("field_name_0=author")
239
- .send("create_view_display=Link")
282
+ .send("columns=" + encodeURIComponent(JSON.stringify(columns)))
283
+ .send("layout=" + encodeURIComponent(JSON.stringify(layout)))
240
284
  .set("Cookie", loginCookie)
241
285
  .expect(toInclude("Default state"));
242
286
  });
@@ -360,27 +404,6 @@ describe("viewedit new Show", () => {
360
404
  .send("columns=" + encodeURIComponent(JSON.stringify(columns)))
361
405
  .send("layout=" + encodeURIComponent(JSON.stringify(layout)))
362
406
  .set("Cookie", loginCookie)
363
- .expect(toInclude("Set page title"));
364
- });
365
- it("save new view page title", async () => {
366
- const loginCookie = await getAdminLoginCookie();
367
- const table = Table.findOne({ name: "books" });
368
-
369
- const ctx = encodeURIComponent(
370
- JSON.stringify({
371
- table_id: table.id,
372
- viewname: "mybook",
373
- layout,
374
- columns,
375
- })
376
- );
377
-
378
- const app = await getApp({ disableCsrf: true });
379
- await request(app)
380
- .post("/viewedit/config/mybook")
381
- .send("contextEnc=" + ctx)
382
- .send("stepName=Set+page+title")
383
- .set("Cookie", loginCookie)
384
407
  .expect(toRedirect("/viewedit"));
385
408
  });
386
409
  it("should show new view", async () => {
package/wrapper.js CHANGED
@@ -185,18 +185,25 @@ const get_headers = (req, version_tag, description, extras = []) => {
185
185
  },
186
186
  ]
187
187
  : [];
188
+ const locale = req.getLocale();
188
189
  const stdHeaders = [
189
190
  {
190
191
  headerTag: `<script>var _sc_loglevel = ${
191
192
  state.logLevel
192
- }, _sc_globalCsrf = "${req.csrfToken()}", _sc_version_tag = "${version_tag}";</script>`,
193
+ }, _sc_globalCsrf = "${req.csrfToken()}", _sc_version_tag = "${version_tag}"${
194
+ locale ? `, _sc_locale = "${locale}"` : ""
195
+ };</script>`,
193
196
  },
194
197
  { css: `/static_assets/${version_tag}/saltcorn.css` },
195
198
  { script: `/static_assets/${version_tag}/saltcorn-common.js` },
196
199
  { script: `/static_assets/${version_tag}/saltcorn.js` },
197
200
  { script: `/static_assets/${version_tag}/dayjs.min.js` },
198
- { script: `/static_assets/${version_tag}/relation_helpers.js` },
199
201
  ];
202
+ if (locale !== "en") {
203
+ stdHeaders.push({
204
+ script: `/static_assets/${version_tag}/dayjslocales/${locale}.js`,
205
+ });
206
+ }
200
207
  let from_cfg = [];
201
208
  if (state.getConfig("page_custom_css", ""))
202
209
  from_cfg.push({ style: state.getConfig("page_custom_css", "") });
@@ -350,7 +357,8 @@ module.exports = (version_tag) =>
350
357
  menu: no_menu ? undefined : get_menu(req),
351
358
  currentUrl,
352
359
  originalUrl: req.originalUrl,
353
-
360
+ requestFluidLayout:
361
+ typeof opts === "string" ? false : opts.requestFluidLayout,
354
362
  alerts,
355
363
  body: html.length === 1 ? html[0] : html.join(""),
356
364
  headers: get_headers(req, version_tag, opts.description, pageHeaders),