@saltcorn/server 1.3.0-beta.1 → 1.3.0-beta.11

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 (408) hide show
  1. package/CHANGELOG.md +17 -1
  2. package/app.js +21 -8
  3. package/auth/routes.js +137 -12
  4. package/docs/assets/search.js +1 -1
  5. package/docs/classes/_saltcorn_common_code.Relation.html +10 -10
  6. package/docs/classes/_saltcorn_common_code.RelationsFinder.html +5 -5
  7. package/docs/classes/_saltcorn_data.models.Crash.html +17 -17
  8. package/docs/classes/_saltcorn_data.models.EventLog-1.html +19 -19
  9. package/docs/classes/_saltcorn_data.models.Field.html +90 -73
  10. package/docs/classes/_saltcorn_data.models.FieldRepeat.html +16 -16
  11. package/docs/classes/_saltcorn_data.models.File-1.html +48 -48
  12. package/docs/classes/_saltcorn_data.models.Form-1.html +46 -38
  13. package/docs/classes/_saltcorn_data.models.Library.html +13 -13
  14. package/docs/classes/_saltcorn_data.models.Page.html +24 -24
  15. package/docs/classes/_saltcorn_data.models.PageGroup-1.html +25 -25
  16. package/docs/classes/_saltcorn_data.models.Plugin.html +25 -25
  17. package/docs/classes/_saltcorn_data.models.Role.html +9 -9
  18. package/docs/classes/_saltcorn_data.models.Table-1.html +95 -93
  19. package/docs/classes/_saltcorn_data.models.TableConstraint.html +14 -14
  20. package/docs/classes/_saltcorn_data.models.Trigger.html +39 -39
  21. package/docs/classes/_saltcorn_data.models.User.html +48 -48
  22. package/docs/classes/_saltcorn_data.models.View-1.html +105 -53
  23. package/docs/classes/_saltcorn_data.models.Workflow.html +17 -17
  24. package/docs/classes/_saltcorn_data.models.WorkflowRun.html +35 -35
  25. package/docs/classes/_saltcorn_data.models.WorkflowStep.html +25 -25
  26. package/docs/classes/_saltcorn_data.models.WorkflowTrace.html +18 -18
  27. package/docs/classes/_saltcorn_mobile_builder.MobileBuilder.html +36 -36
  28. package/docs/enums/_saltcorn_common_code.RelationType.html +7 -7
  29. package/docs/enums/_saltcorn_common_code.ViewDisplayType.html +4 -4
  30. package/docs/functions/_saltcorn_admin_models.backup.create_backup.html +1 -1
  31. package/docs/functions/_saltcorn_admin_models.backup.create_csv_from_rows.html +1 -1
  32. package/docs/functions/_saltcorn_admin_models.backup.restore.html +5 -3
  33. package/docs/functions/_saltcorn_admin_models.pack.add_to_menu.html +1 -1
  34. package/docs/functions/_saltcorn_admin_models.pack.can_install_pack.html +1 -1
  35. package/docs/functions/_saltcorn_admin_models.pack.fetch_available_packs.html +1 -1
  36. package/docs/functions/_saltcorn_admin_models.pack.fetch_pack_by_name.html +1 -1
  37. package/docs/functions/_saltcorn_admin_models.pack.install_pack.html +1 -1
  38. package/docs/functions/_saltcorn_admin_models.pack.library_pack.html +1 -1
  39. package/docs/functions/_saltcorn_admin_models.pack.model_instance_pack.html +1 -1
  40. package/docs/functions/_saltcorn_admin_models.pack.model_pack.html +1 -1
  41. package/docs/functions/_saltcorn_admin_models.pack.page_group_pack.html +1 -1
  42. package/docs/functions/_saltcorn_admin_models.pack.page_pack.html +1 -1
  43. package/docs/functions/_saltcorn_admin_models.pack.plugin_pack.html +1 -1
  44. package/docs/functions/_saltcorn_admin_models.pack.role_pack.html +1 -1
  45. package/docs/functions/_saltcorn_admin_models.pack.table_pack.html +1 -1
  46. package/docs/functions/_saltcorn_admin_models.pack.trigger_pack.html +1 -1
  47. package/docs/functions/_saltcorn_admin_models.pack.uninstall_pack.html +1 -1
  48. package/docs/functions/_saltcorn_admin_models.pack.view_pack.html +1 -1
  49. package/docs/functions/_saltcorn_admin_models.tenant.copy_tenant_template.html +1 -1
  50. package/docs/functions/_saltcorn_admin_models.tenant.create_tenant.html +1 -1
  51. package/docs/functions/_saltcorn_admin_models.tenant.deleteTenant.html +1 -1
  52. package/docs/functions/_saltcorn_admin_models.tenant.domain_sanitize.html +1 -1
  53. package/docs/functions/_saltcorn_admin_models.tenant.eachTenant.html +1 -1
  54. package/docs/functions/_saltcorn_admin_models.tenant.getAllTenantRows.html +1 -1
  55. package/docs/functions/_saltcorn_admin_models.tenant.getAllTenants.html +1 -1
  56. package/docs/functions/_saltcorn_admin_models.tenant.insertTenant.html +1 -1
  57. package/docs/functions/_saltcorn_admin_models.tenant.switchToTenant.html +1 -1
  58. package/docs/functions/_saltcorn_common_code.buildTableCaches.html +1 -1
  59. package/docs/functions/_saltcorn_common_code.parseLegacyRelation.html +1 -1
  60. package/docs/functions/_saltcorn_common_code.parseRelationPath.html +1 -1
  61. package/docs/functions/_saltcorn_data.models.config.check_email_mask.html +1 -1
  62. package/docs/functions/_saltcorn_data.models.config.deleteConfig.html +1 -1
  63. package/docs/functions/_saltcorn_data.models.config.getAllConfig.html +1 -1
  64. package/docs/functions/_saltcorn_data.models.config.getConfig.html +1 -1
  65. package/docs/functions/_saltcorn_data.models.config.get_base_url.html +1 -1
  66. package/docs/functions/_saltcorn_data.models.config.get_latest_npm_version.html +1 -1
  67. package/docs/functions/_saltcorn_data.models.config.remove_from_menu.html +1 -1
  68. package/docs/functions/_saltcorn_data.models.config.save_menu_items.html +1 -1
  69. package/docs/functions/_saltcorn_data.models.config.setConfig.html +1 -1
  70. package/docs/functions/_saltcorn_data.models.discovery.discover_tables.html +1 -1
  71. package/docs/functions/_saltcorn_data.models.discovery.discoverable_tables.html +1 -1
  72. package/docs/functions/_saltcorn_data.models.discovery.findType.html +1 -1
  73. package/docs/functions/_saltcorn_data.models.discovery.get_existing_views.html +1 -1
  74. package/docs/functions/_saltcorn_data.models.discovery.implement_discovery.html +1 -1
  75. package/docs/functions/_saltcorn_data.models.email.getMailTransport.html +1 -1
  76. package/docs/functions/_saltcorn_data.models.email.send_verification_email.html +1 -1
  77. package/docs/functions/_saltcorn_data.models.email.viewToEmailHtml.html +1 -1
  78. package/docs/functions/_saltcorn_data.models.expression.apply_calculated_fields.html +1 -1
  79. package/docs/functions/_saltcorn_data.models.expression.apply_calculated_fields_stored.html +1 -1
  80. package/docs/functions/_saltcorn_data.models.expression.eval_expression.html +1 -1
  81. package/docs/functions/_saltcorn_data.models.expression.expressionValidator.html +1 -1
  82. package/docs/functions/_saltcorn_data.models.expression.get_async_expression_function.html +1 -1
  83. package/docs/functions/_saltcorn_data.models.expression.get_expression_function.html +1 -1
  84. package/docs/functions/_saltcorn_data.models.expression.jsexprToWhere.html +1 -1
  85. package/docs/functions/_saltcorn_data.models.expression.recalculate_for_stored.html +1 -1
  86. package/docs/functions/_saltcorn_data.models.expression.transform_for_async.html +1 -1
  87. package/docs/functions/_saltcorn_data.models.layout.eachView.html +1 -1
  88. package/docs/functions/_saltcorn_data.models.layout.getStringsForI18n.html +1 -1
  89. package/docs/functions/_saltcorn_data.models.layout.getViews.html +1 -1
  90. package/docs/functions/_saltcorn_data.models.layout.translateLayout.html +1 -1
  91. package/docs/functions/_saltcorn_data.models.layout.traverse.html +1 -1
  92. package/docs/functions/_saltcorn_data.models.layout.traverseSync.html +1 -1
  93. package/docs/functions/_saltcorn_data.models.random.all_views.html +1 -1
  94. package/docs/functions/_saltcorn_data.models.random.fill_table_row.html +1 -1
  95. package/docs/functions/_saltcorn_data.models.random.initial_view.html +1 -1
  96. package/docs/functions/_saltcorn_data.models.random.random_table.html +1 -1
  97. package/docs/functions/_saltcorn_db_common.buildInsertBulkSql.html +1 -1
  98. package/docs/functions/_saltcorn_db_common.buildInsertSql.html +1 -1
  99. package/docs/functions/_saltcorn_db_common.doCount.html +1 -1
  100. package/docs/functions/_saltcorn_db_common.doDeleteWhere.html +1 -1
  101. package/docs/functions/_saltcorn_db_common.doListScTables.html +1 -1
  102. package/docs/functions/_saltcorn_db_common.doListTables.html +1 -1
  103. package/docs/functions/_saltcorn_db_common.doListUserDefinedTables.html +1 -1
  104. package/docs/functions/_saltcorn_db_common.do_add_index.html +1 -1
  105. package/docs/functions/_saltcorn_db_common.do_drop_index.html +1 -1
  106. package/docs/functions/_saltcorn_db_common.ftsFieldsSqlExpr.html +1 -1
  107. package/docs/functions/_saltcorn_db_common.mkSelectOptions.html +1 -1
  108. package/docs/functions/_saltcorn_db_common.mkVal.html +1 -1
  109. package/docs/functions/_saltcorn_db_common.mkWhere.html +1 -1
  110. package/docs/functions/_saltcorn_db_common.multi_tenant.enable_multi_tenant.html +1 -1
  111. package/docs/functions/_saltcorn_db_common.multi_tenant.getRequestContext.html +1 -1
  112. package/docs/functions/_saltcorn_db_common.multi_tenant.getTenantSchema.html +1 -1
  113. package/docs/functions/_saltcorn_db_common.multi_tenant.init.html +1 -1
  114. package/docs/functions/_saltcorn_db_common.multi_tenant.is_it_multi_tenant.html +1 -1
  115. package/docs/functions/_saltcorn_db_common.multi_tenant.runWithTenant.html +1 -1
  116. package/docs/functions/_saltcorn_db_common.orderByIsObject.html +1 -1
  117. package/docs/functions/_saltcorn_db_common.orderByIsOperator.html +1 -1
  118. package/docs/functions/_saltcorn_db_common.prefixFieldsInWhere.html +1 -1
  119. package/docs/functions/_saltcorn_db_common.reprAsJson.html +1 -1
  120. package/docs/functions/_saltcorn_db_common.slugify.html +1 -1
  121. package/docs/functions/_saltcorn_db_common.sqlBinOp.html +1 -1
  122. package/docs/functions/_saltcorn_db_common.sqlFun.html +1 -1
  123. package/docs/functions/_saltcorn_db_common.sqlsanitize.html +1 -1
  124. package/docs/functions/_saltcorn_db_common.sqlsanitizeAllowDots.html +1 -1
  125. package/docs/functions/_saltcorn_db_common.subSelectWhere.html +1 -1
  126. package/docs/functions/_saltcorn_db_common.tryCatchInTransaction.html +1 -1
  127. package/docs/functions/_saltcorn_db_common.withTransaction.html +1 -1
  128. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.androidFeatures.html +1 -1
  129. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.androidPermissions.html +1 -1
  130. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.buildTablesFile.html +1 -1
  131. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.copyPrepopulatedDb.html +1 -1
  132. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.copyServerFiles.html +1 -1
  133. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.copyShareExtFiles.html +1 -1
  134. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.copySiteLogo.html +1 -1
  135. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.copyTranslationFiles.html +1 -1
  136. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.createSqliteDb.html +1 -1
  137. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.decodeProvisioningProfile.html +1 -1
  138. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.extractDomain.html +1 -1
  139. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.generateAndroidVersionCode.html +1 -1
  140. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.modifyAndroidManifest.html +1 -1
  141. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.modifyConfigXml.html +1 -1
  142. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.modifyGradleConfig.html +1 -1
  143. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.modifyInfoPlist.html +1 -1
  144. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.modifyXcodeProjectFile.html +1 -1
  145. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.prepAppIcon.html +1 -1
  146. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.prepareAppIcon.html +1 -1
  147. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.prepareBuildDir.html +1 -1
  148. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.prepareExportOptionsPlist.html +1 -1
  149. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.prepareSplashIcon.html +1 -1
  150. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.prepareSplashPage.html +1 -1
  151. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.writeCapacitorConfig.html +1 -1
  152. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.writeCfgFile.html +1 -1
  153. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.writeDataExtractionRules.html +1 -1
  154. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.writeNetworkSecurityConfig.html +1 -1
  155. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.writePodfile.html +1 -1
  156. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.writePrivacyInfo.html +1 -1
  157. package/docs/functions/_saltcorn_mobile_builder.package_bundle_utils.bundleMobileAppCode.html +1 -1
  158. package/docs/functions/_saltcorn_mobile_builder.package_bundle_utils.bundlePackagesAndPlugins.html +1 -1
  159. package/docs/functions/_saltcorn_mobile_builder.package_bundle_utils.copyMobileAppDirs.html +1 -1
  160. package/docs/functions/_saltcorn_mobile_builder.package_bundle_utils.copyPublicDirs.html +1 -1
  161. package/docs/functions/_saltcorn_sqlite.add_index.html +1 -1
  162. package/docs/functions/_saltcorn_sqlite.add_unique_constraint.html +1 -1
  163. package/docs/functions/_saltcorn_sqlite.begin.html +1 -1
  164. package/docs/functions/_saltcorn_sqlite.changeConnection.html +1 -1
  165. package/docs/functions/_saltcorn_sqlite.close.html +1 -1
  166. package/docs/functions/_saltcorn_sqlite.commit.html +1 -1
  167. package/docs/functions/_saltcorn_sqlite.count.html +1 -1
  168. package/docs/functions/_saltcorn_sqlite.deleteWhere.html +1 -1
  169. package/docs/functions/_saltcorn_sqlite.dropTable.html +1 -1
  170. package/docs/functions/_saltcorn_sqlite.dropTables.html +1 -1
  171. package/docs/functions/_saltcorn_sqlite.drop_index.html +1 -1
  172. package/docs/functions/_saltcorn_sqlite.drop_reset_schema.html +1 -1
  173. package/docs/functions/_saltcorn_sqlite.drop_unique_constraint.html +1 -1
  174. package/docs/functions/_saltcorn_sqlite.getVersion.html +1 -1
  175. package/docs/functions/_saltcorn_sqlite.get_db_filepath.html +1 -1
  176. package/docs/functions/_saltcorn_sqlite.get_sql_logging.html +1 -1
  177. package/docs/functions/_saltcorn_sqlite.init.html +1 -1
  178. package/docs/functions/_saltcorn_sqlite.insert.html +1 -1
  179. package/docs/functions/_saltcorn_sqlite.listScTables.html +1 -1
  180. package/docs/functions/_saltcorn_sqlite.listTables.html +1 -1
  181. package/docs/functions/_saltcorn_sqlite.listUserDefinedTables.html +1 -1
  182. package/docs/functions/_saltcorn_sqlite.query.html +1 -1
  183. package/docs/functions/_saltcorn_sqlite.rollback.html +1 -1
  184. package/docs/functions/_saltcorn_sqlite.select.html +1 -1
  185. package/docs/functions/_saltcorn_sqlite.selectMaybeOne.html +1 -1
  186. package/docs/functions/_saltcorn_sqlite.selectOne.html +1 -1
  187. package/docs/functions/_saltcorn_sqlite.set_sql_logging.html +1 -1
  188. package/docs/functions/_saltcorn_sqlite.sql_log.html +1 -1
  189. package/docs/functions/_saltcorn_sqlite.update.html +1 -1
  190. package/docs/functions/_saltcorn_sqlite.updateWhere.html +1 -1
  191. package/docs/functions/_saltcorn_sqlite_mobile.add_index.html +1 -1
  192. package/docs/functions/_saltcorn_sqlite_mobile.add_unique_constraint.html +1 -1
  193. package/docs/functions/_saltcorn_sqlite_mobile.count.html +1 -1
  194. package/docs/functions/_saltcorn_sqlite_mobile.deleteWhere.html +1 -1
  195. package/docs/functions/_saltcorn_sqlite_mobile.drop_index.html +1 -1
  196. package/docs/functions/_saltcorn_sqlite_mobile.drop_reset_schema.html +1 -1
  197. package/docs/functions/_saltcorn_sqlite_mobile.drop_unique_constraint.html +1 -1
  198. package/docs/functions/_saltcorn_sqlite_mobile.init.html +1 -1
  199. package/docs/functions/_saltcorn_sqlite_mobile.insert.html +1 -1
  200. package/docs/functions/_saltcorn_sqlite_mobile.insertRows.html +1 -1
  201. package/docs/functions/_saltcorn_sqlite_mobile.listScTables.html +1 -1
  202. package/docs/functions/_saltcorn_sqlite_mobile.listTables.html +1 -1
  203. package/docs/functions/_saltcorn_sqlite_mobile.listUserDefinedTables.html +1 -1
  204. package/docs/functions/_saltcorn_sqlite_mobile.query.html +1 -1
  205. package/docs/functions/_saltcorn_sqlite_mobile.select.html +1 -1
  206. package/docs/functions/_saltcorn_sqlite_mobile.selectMaybeOne.html +1 -1
  207. package/docs/functions/_saltcorn_sqlite_mobile.selectOne.html +1 -1
  208. package/docs/functions/_saltcorn_sqlite_mobile.setConnectionObject.html +1 -1
  209. package/docs/functions/_saltcorn_sqlite_mobile.tableExists.html +1 -1
  210. package/docs/functions/_saltcorn_sqlite_mobile.time.html +1 -1
  211. package/docs/functions/_saltcorn_sqlite_mobile.update.html +1 -1
  212. package/docs/functions/_saltcorn_types.ModelAbstracts.abstract_field.instanceOfField.html +1 -1
  213. package/docs/functions/_saltcorn_types.ModelAbstracts.abstract_page.instanceOfPage.html +1 -1
  214. package/docs/functions/_saltcorn_types.ModelAbstracts.abstract_view.instanceOfView.html +1 -1
  215. package/docs/functions/_saltcorn_types.Types.base_types.instanceOWithHtmlFile.html +1 -1
  216. package/docs/functions/_saltcorn_types.Types.common_types.instanceOfErrorMsg.html +1 -1
  217. package/docs/functions/_saltcorn_types.Types.common_types.instanceOfSuccessMsg.html +1 -1
  218. package/docs/functions/_saltcorn_types.Types.common_types.instanceOfType.html +1 -1
  219. package/docs/functions/_saltcorn_types.generators.generateBool.html +1 -1
  220. package/docs/functions/_saltcorn_types.generators.generateString.html +1 -1
  221. package/docs/functions/_saltcorn_types.generators.num_between.html +1 -1
  222. package/docs/functions/_saltcorn_types.generators.oneOf.html +1 -1
  223. package/docs/interfaces/_saltcorn_mobile_builder.common_build_utils.ScCapacitorConfig.html +10 -10
  224. package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_field.AbstractField.html +15 -15
  225. package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_field.AbstractFieldRepeat.html +3 -3
  226. package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_form.AbstractForm.html +33 -26
  227. package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_page.AbstractPage.html +7 -7
  228. package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_role.AbstractRole.html +3 -3
  229. package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_table.AbstractTable.html +11 -11
  230. package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_trigger.AbstractTrigger.html +16 -16
  231. package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_view.AbstractView.html +10 -10
  232. package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_workflow.AbstractWorkflow.html +13 -13
  233. package/docs/modules/_saltcorn_admin_models.backup.html +1 -1
  234. package/docs/modules/_saltcorn_admin_models.html +1 -1
  235. package/docs/modules/_saltcorn_admin_models.pack.html +1 -1
  236. package/docs/modules/_saltcorn_admin_models.tenant.html +1 -1
  237. package/docs/modules/_saltcorn_common_code.html +1 -1
  238. package/docs/modules/_saltcorn_data.html +7 -5
  239. package/docs/modules/_saltcorn_data.models.EventLog.html +2 -2
  240. package/docs/modules/_saltcorn_data.models.File.html +2 -2
  241. package/docs/modules/_saltcorn_data.models.Form.html +2 -2
  242. package/docs/modules/_saltcorn_data.models.PageGroup.html +2 -2
  243. package/docs/modules/_saltcorn_data.models.Table.html +2 -2
  244. package/docs/modules/_saltcorn_data.models.View.html +2 -2
  245. package/docs/modules/_saltcorn_data.models.config.html +1 -1
  246. package/docs/modules/_saltcorn_data.models.discovery.html +1 -1
  247. package/docs/modules/_saltcorn_data.models.email.html +1 -1
  248. package/docs/modules/_saltcorn_data.models.expression.html +1 -1
  249. package/docs/modules/_saltcorn_data.models.html +1 -1
  250. package/docs/modules/_saltcorn_data.models.layout.html +1 -1
  251. package/docs/modules/_saltcorn_data.models.random.html +1 -1
  252. package/docs/modules/_saltcorn_data.models.scheduler.html +1 -1
  253. package/docs/modules/_saltcorn_data.plugin_helper.html +1 -1
  254. package/docs/modules/_saltcorn_data.utils.html +1 -1
  255. package/docs/modules/_saltcorn_db_common.html +2 -2
  256. package/docs/modules/_saltcorn_db_common.multi_tenant.html +1 -1
  257. package/docs/modules/_saltcorn_markup.html +2 -2
  258. package/docs/modules/_saltcorn_mobile_builder.common_build_utils.html +1 -1
  259. package/docs/modules/_saltcorn_mobile_builder.html +1 -1
  260. package/docs/modules/_saltcorn_mobile_builder.package_bundle_utils.html +1 -1
  261. package/docs/modules/_saltcorn_sqlite.html +1 -1
  262. package/docs/modules/_saltcorn_sqlite_mobile.html +1 -1
  263. package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_field.html +1 -1
  264. package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_form.html +1 -1
  265. package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_library.html +1 -1
  266. package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_page.html +1 -1
  267. package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_plugin.html +1 -1
  268. package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_role.html +1 -1
  269. package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_table.html +1 -1
  270. package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_trigger.html +1 -1
  271. package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_view.html +1 -1
  272. package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_workflow.html +1 -1
  273. package/docs/modules/_saltcorn_types.ModelAbstracts.html +1 -1
  274. package/docs/modules/_saltcorn_types.Types.base_types.html +1 -1
  275. package/docs/modules/_saltcorn_types.Types.common_types.html +1 -1
  276. package/docs/modules/_saltcorn_types.Types.html +1 -1
  277. package/docs/modules/_saltcorn_types.generators.html +1 -1
  278. package/docs/modules/_saltcorn_types.html +1 -1
  279. package/docs/types/_saltcorn_data.models.EventLog.EventLogCfg.html +1 -1
  280. package/docs/types/_saltcorn_data.models.File.FileCfg.html +1 -1
  281. package/docs/types/_saltcorn_data.models.Form.AdditionalButton.html +1 -1
  282. package/docs/types/_saltcorn_data.models.Form.FormCfg.html +4 -2
  283. package/docs/types/_saltcorn_data.models.PageGroup.ScreenInfoParams.html +1 -1
  284. package/docs/types/_saltcorn_data.models.Table.ChildRelations.html +1 -1
  285. package/docs/types/_saltcorn_data.models.Table.ParentRelations.html +1 -1
  286. package/docs/types/_saltcorn_data.models.Table.RelationData.html +1 -1
  287. package/docs/types/_saltcorn_data.models.View.FindViewsPred.html +1 -1
  288. package/docs/types/_saltcorn_db_common.AggregationOptions.html +4 -2
  289. package/docs/types/_saltcorn_db_common.CoordOpts.html +1 -1
  290. package/docs/types/_saltcorn_db_common.DatabaseClient.html +1 -1
  291. package/docs/types/_saltcorn_db_common.JoinField.html +1 -1
  292. package/docs/types/_saltcorn_db_common.JoinFields.html +1 -1
  293. package/docs/types/_saltcorn_db_common.JoinOptions.html +1 -1
  294. package/docs/types/_saltcorn_db_common.JsonPath.html +1 -1
  295. package/docs/types/_saltcorn_db_common.JsonPathElem.html +1 -1
  296. package/docs/types/_saltcorn_db_common.Operator.html +1 -1
  297. package/docs/types/_saltcorn_db_common.PartialSome.html +1 -1
  298. package/docs/types/_saltcorn_db_common.PrimaryKeyValue.html +1 -1
  299. package/docs/types/_saltcorn_db_common.Row.html +1 -1
  300. package/docs/types/_saltcorn_db_common.SelectOptions.html +3 -3
  301. package/docs/types/_saltcorn_db_common.SqlAndValues.html +1 -1
  302. package/docs/types/_saltcorn_db_common.StrongRow.html +1 -1
  303. package/docs/types/_saltcorn_db_common.SubselectOptions.html +1 -1
  304. package/docs/types/_saltcorn_db_common.Value.html +1 -1
  305. package/docs/types/_saltcorn_db_common.Where.html +1 -1
  306. package/docs/types/_saltcorn_mobile_builder.IosCfg.html +1 -1
  307. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_field.FieldCfg.html +1 -1
  308. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_field.InputType.html +1 -1
  309. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_form.AdditionalButton.html +1 -1
  310. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_library.LibraryCfg.html +1 -1
  311. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_library.LibraryPack.html +1 -1
  312. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_page.PageCfg.html +1 -1
  313. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_page.PagePack.html +1 -1
  314. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_plugin.PluginCfg.html +1 -1
  315. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_plugin.PluginPack.html +1 -1
  316. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_role.RoleCfg.html +1 -1
  317. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_role.RolePack.html +1 -1
  318. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_table.TableCfg.html +1 -1
  319. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_table.TablePack.html +1 -1
  320. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_trigger.TriggerCfg.html +1 -1
  321. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_trigger.TriggerPack.html +1 -1
  322. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_view.ViewCfg.html +1 -1
  323. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_view.ViewPack.html +1 -1
  324. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_workflow.ConfigWorkflowStep.html +1 -1
  325. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_workflow.RunResult.html +1 -1
  326. package/docs/types/_saltcorn_types.Types.base_types.Action.html +1 -1
  327. package/docs/types/_saltcorn_types.Types.base_types.AuthenticationMethod.html +1 -1
  328. package/docs/types/_saltcorn_types.Types.base_types.CalcJoinfield.html +1 -1
  329. package/docs/types/_saltcorn_types.Types.base_types.CapacitorPlugin.html +1 -1
  330. package/docs/types/_saltcorn_types.Types.base_types.CodePagePack.html +1 -1
  331. package/docs/types/_saltcorn_types.Types.base_types.Column.html +1 -1
  332. package/docs/types/_saltcorn_types.Types.base_types.ConnectObjType.html +1 -1
  333. package/docs/types/_saltcorn_types.Types.base_types.ConnectedObjects.html +1 -1
  334. package/docs/types/_saltcorn_types.Types.base_types.CopilotSkill.html +1 -1
  335. package/docs/types/_saltcorn_types.Types.base_types.ErrorObj.html +1 -1
  336. package/docs/types/_saltcorn_types.Types.base_types.FieldLike.html +1 -1
  337. package/docs/types/_saltcorn_types.Types.base_types.FieldView.html +1 -1
  338. package/docs/types/_saltcorn_types.Types.base_types.Header.html +1 -1
  339. package/docs/types/_saltcorn_types.Types.base_types.JoinFieldOption.html +1 -1
  340. package/docs/types/_saltcorn_types.Types.base_types.Layout.html +1 -1
  341. package/docs/types/_saltcorn_types.Types.base_types.MobileConfig.html +1 -1
  342. package/docs/types/_saltcorn_types.Types.base_types.ModelPattern.html +1 -1
  343. package/docs/types/_saltcorn_types.Types.base_types.Pack.html +1 -1
  344. package/docs/types/_saltcorn_types.Types.base_types.Plugin.html +1 -1
  345. package/docs/types/_saltcorn_types.Types.base_types.PluginFunction.html +1 -1
  346. package/docs/types/_saltcorn_types.Types.base_types.PluginLayout.html +1 -1
  347. package/docs/types/_saltcorn_types.Types.base_types.PluginRoute.html +1 -1
  348. package/docs/types/_saltcorn_types.Types.base_types.PluginSourceType.html +1 -1
  349. package/docs/types/_saltcorn_types.Types.base_types.PluginType.html +1 -1
  350. package/docs/types/_saltcorn_types.Types.base_types.PluginWrap.html +1 -1
  351. package/docs/types/_saltcorn_types.Types.base_types.PluginWrapArg.html +1 -1
  352. package/docs/types/_saltcorn_types.Types.base_types.RelationOption.html +1 -1
  353. package/docs/types/_saltcorn_types.Types.base_types.Req.html +1 -1
  354. package/docs/types/_saltcorn_types.Types.base_types.Res.html +1 -1
  355. package/docs/types/_saltcorn_types.Types.base_types.ResultType.html +1 -1
  356. package/docs/types/_saltcorn_types.Types.base_types.RouteAction.html +1 -1
  357. package/docs/types/_saltcorn_types.Types.base_types.RunExtra.html +1 -1
  358. package/docs/types/_saltcorn_types.Types.base_types.SlugStepType.html +1 -1
  359. package/docs/types/_saltcorn_types.Types.base_types.StepResType.html +1 -1
  360. package/docs/types/_saltcorn_types.Types.base_types.SubField.html +1 -1
  361. package/docs/types/_saltcorn_types.Types.base_types.TableProvider.html +1 -1
  362. package/docs/types/_saltcorn_types.Types.base_types.TableQuery.html +1 -1
  363. package/docs/types/_saltcorn_types.Types.base_types.Tablely.html +1 -1
  364. package/docs/types/_saltcorn_types.Types.base_types.ViewTemplate.html +1 -1
  365. package/docs/types/_saltcorn_types.Types.common_types.ErrorMessage.html +1 -1
  366. package/docs/types/_saltcorn_types.Types.common_types.GenObj.html +1 -1
  367. package/docs/types/_saltcorn_types.Types.common_types.ReqRes.html +1 -1
  368. package/docs/types/_saltcorn_types.Types.common_types.ResultMessage.html +1 -1
  369. package/docs/types/_saltcorn_types.Types.common_types.SuccessMessage.html +1 -1
  370. package/docs/types/_saltcorn_types.Types.common_types.Type.html +1 -1
  371. package/docs/variables/_saltcorn_data.db.html +1 -1
  372. package/docs/variables/_saltcorn_data.migrations.html +1 -1
  373. package/docs/variables/_saltcorn_data.models.config.available_languages.html +1 -1
  374. package/docs/variables/_saltcorn_data.models.config.configTypes.html +1 -1
  375. package/docs/variables/_saltcorn_data.models.scheduler.runScheduler.html +1 -1
  376. package/docs/variables/_saltcorn_data.plugin_helper.run_action_column.html +1 -1
  377. package/docs/variables/_saltcorn_data.utils.NotAuthorized.html +1 -1
  378. package/docs/variables/_saltcorn_data.utils.sleep.html +1 -1
  379. package/docs/variables/_saltcorn_db_common.multi_tenant.tenantNamespace.html +1 -1
  380. package/help/Template tables.tmd +9 -0
  381. package/locales/en.json +16 -1
  382. package/locales/pt.json +2 -2
  383. package/markup/admin.js +11 -2
  384. package/package.json +9 -9
  385. package/public/assets/databases/databases.json +3 -0
  386. package/public/assets/databases/prepopulated.db +0 -0
  387. package/public/assets/sql-wasm.wasm +0 -0
  388. package/public/gridedit.js +3 -2
  389. package/public/saltcorn-common.js +114 -42
  390. package/public/saltcorn.css +8 -0
  391. package/public/saltcorn.js +9 -1
  392. package/routes/admin.js +59 -50
  393. package/routes/api.js +55 -2
  394. package/routes/files.js +12 -0
  395. package/routes/homepage.js +23 -1
  396. package/routes/list.js +4 -3
  397. package/routes/menu.js +14 -0
  398. package/routes/notifications.js +12 -0
  399. package/routes/page.js +30 -1
  400. package/routes/registry.js +64 -4
  401. package/routes/search.js +10 -0
  402. package/routes/tables.js +137 -59
  403. package/routes/view.js +37 -1
  404. package/routes/viewedit.js +1 -1
  405. package/serve.js +41 -1
  406. package/systemd.js +1 -1
  407. package/tests/api.test.js +51 -0
  408. package/tests/clientjs.test.js +16 -0
@@ -151,8 +151,25 @@ function valid_js_var_name(s) {
151
151
  return !!s.match(/^[a-zA-Z_$][a-zA-Z_$0-9]*$/);
152
152
  }
153
153
 
154
+ function add_extra_state(base_url, extra_state_fml, row) {
155
+ //console.log("add_extra_state", { base_url, extra_state_fml, row });
156
+ if (!extra_state_fml) return base_url;
157
+ let extra_state = new Function(
158
+ "row",
159
+ `{${Object.keys(row).join(",")}}`,
160
+ "return " + extra_state_fml
161
+ )(row, row);
162
+ let qs = Object.entries(extra_state)
163
+ .map(([k, v]) => `${k}=${encodeURIComponent(v)}`)
164
+ .join("&");
165
+ let sepChar = base_url.includes("?") ? "&" : "?";
166
+ return base_url + sepChar + qs;
167
+ }
168
+
154
169
  const apply_showif_fetching_urls = new Set();
155
170
 
171
+ const global_fetch_options_cache = {};
172
+
156
173
  function apply_showif() {
157
174
  const isNode = getIsNode();
158
175
  $("[data-show-if]").each(function (ix, element) {
@@ -294,6 +311,9 @@ function apply_showif() {
294
311
  qss.push(...dynwhere.dereference.map((d) => `dereference=${d}`));
295
312
  else qss.push(`dereference=${dynwhere.dereference}`);
296
313
  }
314
+ if (!dynwhere.label_formula && dynwhere.summary_field && dynwhere.refname) {
315
+ qss.push(`fields=${dynwhere.summary_field},${dynwhere.refname}`);
316
+ }
297
317
  const qs = qss.join("&");
298
318
  let current = e.attr("data-selected");
299
319
  if (current === "null") current = null;
@@ -380,36 +400,27 @@ function apply_showif() {
380
400
  e.selectize()[0].selectize.setValue(currentDataOption);
381
401
  }
382
402
  };
383
-
384
- const cache = e.prop("data-fetch-options-cache") || {};
403
+ if (!global_fetch_options_cache[dynwhere.table])
404
+ global_fetch_options_cache[dynwhere.table] = {};
405
+ const cache = global_fetch_options_cache[dynwhere.table] || {};
385
406
  if (cache[qs] === "fetching") {
386
407
  // do nothing, this will be activated by someone else
387
408
  } else if (cache[qs]) {
388
409
  activate(cache[qs], qs);
389
410
  } else {
390
- e.prop("data-fetch-options-cache", {
391
- ...cache,
392
- [qs]: "fetching",
393
- });
411
+ cache[qs] = "fetching";
394
412
  apply_showif_fetching_urls.add(`/api/${dynwhere.table}?${qs}`);
395
413
  $.ajax(`/api/${dynwhere.table}?${qs}`)
396
414
  .then((resp) => {
415
+ const cacheNow = global_fetch_options_cache[dynwhere.table] || {};
397
416
  if (resp.success) {
398
417
  if (window._sc_loglevel > 4)
399
418
  console.log("dynwhere fetch", qs, resp.success);
400
-
401
419
  activate(resp.success, qs);
402
- const cacheNow = e.prop("data-fetch-options-cache") || {};
403
- e.prop("data-fetch-options-cache", {
404
- ...cacheNow,
405
- [qs]: resp.success,
406
- });
420
+ cacheNow[qs] = resp.success;
421
+ apply_showif();
407
422
  } else {
408
- const cacheNow = e.prop("data-fetch-options-cache") || {};
409
- e.prop("data-fetch-options-cache", {
410
- ...cacheNow,
411
- [qs]: undefined,
412
- });
423
+ cacheNow[qs] = undefined;
413
424
  }
414
425
  })
415
426
  .fail(checkNetworkError)
@@ -428,6 +439,49 @@ function apply_showif() {
428
439
  });
429
440
  });
430
441
  });
442
+ $("[data-view-source]").each(function (ix, element) {
443
+ const e = $(element);
444
+ const rec = get_form_record(e);
445
+ const current = e.attr("data-view-source-current");
446
+ const encFml = e.attr("data-view-source");
447
+ const needFields = e.attr("data-view-source-need-fields");
448
+ if (needFields) {
449
+ const isSet = (v) => v !== null && v !== "" && typeof v !== "undefined";
450
+ if (needFields.split(",").some((k) => !isSet(rec[k]))) return;
451
+ }
452
+ const fml = decodeURIComponent(encFml);
453
+ //console.log("fml", fml);
454
+
455
+ const viewname = e.attr("data-sc-embed-viewname");
456
+
457
+ const newUrl = new Function("row", "return " + fml)(rec);
458
+ //console.log("current-new", current, newUrl);
459
+
460
+ if (current && current == newUrl) return;
461
+
462
+ e.attr("data-view-source-current", newUrl); // to prevent concurrent fetches
463
+ $.ajax(newUrl, {
464
+ headers: {
465
+ pjaxpageload: "true",
466
+ localizedstate: "true", //no admin bar
467
+ },
468
+ success: function (res, textStatus, request) {
469
+ const newE = `<div class="d-inline"
470
+ data-sc-embed-viewname="${viewname}"
471
+ data-sc-view-source="${newUrl}"
472
+ data-view-source-current="${newUrl}"
473
+ data-view-source-need-fields="${needFields}"
474
+ data-view-source="${encFml}">${res}</div>`;
475
+
476
+ e.replaceWith(newE);
477
+ initialize_page();
478
+ },
479
+ error: function (res) {
480
+ if (!checkNetworkError(res))
481
+ notifyAlert({ type: "danger", text: res.responseText });
482
+ },
483
+ });
484
+ });
431
485
  $("[data-source-url]").each(function (ix, element) {
432
486
  const e = $(element);
433
487
  const rec0 = get_form_record(e);
@@ -1664,8 +1718,10 @@ function press_store_button(clicked, keepOld, disable) {
1664
1718
  }
1665
1719
 
1666
1720
  function restore_old_button(btnId) {
1721
+ if (window.reset_spinners) reset_spinners();
1667
1722
  const btn = btnId instanceof jQuery ? btnId : $(`#${btnId}`);
1668
1723
  const oldText = $(btn).data("old-text");
1724
+ if (!oldText.length) reuturn;
1669
1725
  btn.html(oldText);
1670
1726
  btn.css({ width: "", height: "" }).prop("disabled", false);
1671
1727
  btn.removeData("old-text");
@@ -1689,6 +1745,9 @@ async function common_done(res, viewnameOrElem0, isWeb = true) {
1689
1745
  for (const current of element) await fn(current);
1690
1746
  else await fn(element);
1691
1747
  };
1748
+ //TODO what if something else is spinning?
1749
+ if (window.reset_spinners) reset_spinners();
1750
+
1692
1751
  const eval_it = async (s) => {
1693
1752
  if (res.row && res.field_names) {
1694
1753
  const f = new Function(`viewname, row, {${res.field_names}}`, s);
@@ -1741,7 +1800,7 @@ async function common_done(res, viewnameOrElem0, isWeb = true) {
1741
1800
  form.append(
1742
1801
  `<input type="hidden" name="id" value="${res.set_fields[k]}">`
1743
1802
  );
1744
- reloadEmbeddedEditOwnViews(form, res.set_fields[k]);
1803
+ apply_showif();
1745
1804
  return;
1746
1805
  }
1747
1806
  if (input.attr("type") === "checkbox")
@@ -1830,29 +1889,6 @@ function editAllowedAuthByRole(id, event) {
1830
1889
  );
1831
1890
  }
1832
1891
 
1833
- function reloadEmbeddedEditOwnViews(form, id) {
1834
- form.find("div[sc-load-on-assign-id]").each(function () {
1835
- const $e = $(this);
1836
- const viewname = $e.attr("sc-load-on-assign-id");
1837
- const newUrl = `/view/${viewname}?id=${id}`;
1838
- $.ajax(newUrl, {
1839
- headers: {
1840
- pjaxpageload: "true",
1841
- localizedstate: "true", //no admin bar
1842
- },
1843
- success: function (res, textStatus, request) {
1844
- const newE = `<div class="d-inline" data-sc-embed-viewname="${viewname}" data-sc-view-source="${newUrl}">${res}</div>`;
1845
- $e.replaceWith(newE);
1846
- initialize_page();
1847
- },
1848
- error: function (res) {
1849
- if (!checkNetworkError(res))
1850
- notifyAlert({ type: "danger", text: res.responseText });
1851
- },
1852
- });
1853
- });
1854
- }
1855
-
1856
1892
  const repeaterCopyValuesToForm = (form, editor, noTriggerChange) => {
1857
1893
  const vs = JSON.parse(editor.getString());
1858
1894
 
@@ -1981,7 +2017,8 @@ function unique_field_from_rows(
1981
2017
  .filter((v) => v !== value)
1982
2018
  .map((s) => s.replace(value_wspace, ""))
1983
2019
  .map((s) => (numtype ? +s : s))
1984
- .sort(numtype ? (a, b) => a - b : undefined);
2020
+ .filter((s) => (numtype ? !isNaN(s) : true))
2021
+ .sort((a, b) => a - b);
1985
2022
  if (stripped.length === 0) newname = `${value_wspace}${gen_char(start)}`;
1986
2023
  else {
1987
2024
  const i = char_to_i(stripped[stripped.length - 1]);
@@ -2039,6 +2076,25 @@ function init_room(viewname, room_id) {
2039
2076
  });
2040
2077
  }
2041
2078
 
2079
+ function init_collab_room(viewname, eventCfgs) {
2080
+ const socket = io({ transports: ["websocket"] });
2081
+ for (const [event, callback] of Object.entries(eventCfgs.events)) {
2082
+ socket.on(event, callback);
2083
+ }
2084
+ socket.on("connect", function () {
2085
+ socket.emit("join_collab_room", viewname, (ack) => {
2086
+ if (ack && ack.status === "ok") {
2087
+ console.log(`Joined collaboration room for view '${viewname}'`);
2088
+ } else {
2089
+ console.error("Failed to join collaboration room:", ack);
2090
+ }
2091
+ });
2092
+ });
2093
+ socket.on("disconnect", function () {
2094
+ console.log("Disconnected from the server");
2095
+ });
2096
+ }
2097
+
2042
2098
  function cancel_form(form) {
2043
2099
  if (!form) return;
2044
2100
  $(form).trigger("reset");
@@ -2281,6 +2337,22 @@ function formInEmbed(event) {
2281
2337
  return form;
2282
2338
  }
2283
2339
 
2340
+ function login_from_edit_view(e) {
2341
+ e.stopPropagation();
2342
+ e.preventDefault();
2343
+ const form = $(e.target).closest("form");
2344
+ form.attr("action", "/auth/login");
2345
+ form.submit();
2346
+ }
2347
+
2348
+ function signup_from_edit_view(e) {
2349
+ e.stopPropagation();
2350
+ e.preventDefault();
2351
+ const form = $(e.target).closest("form");
2352
+ form.attr("action", "/auth/signup");
2353
+ form.submit();
2354
+ }
2355
+
2284
2356
  function handle_identical_fields(event) {
2285
2357
  let form = null;
2286
2358
  if (event.srcElement) {
@@ -824,6 +824,14 @@ tr:hover span.add-tag {
824
824
  );
825
825
  }
826
826
 
827
+ .prevwfroomrun i.fa-trash-alt {
828
+ display: none;
829
+ }
830
+
831
+ .prevwfroomrun:hover i.fa-trash-alt {
832
+ display: inline;
833
+ }
834
+
827
835
  input[type="file"].file-has-existing {
828
836
  font-size: 0;
829
837
  }
@@ -538,7 +538,7 @@ function saveAndContinue(e, k, event) {
538
538
  form.append(
539
539
  `<input type="hidden" class="form-control " name="id" value="${res.id}">`
540
540
  );
541
- reloadEmbeddedEditOwnViews(form, res.id);
541
+ apply_showif();
542
542
  }
543
543
  common_done(res, form.attr("data-viewname"));
544
544
  if (focusedEl) focusedEl.setAttribute("previous-val", focusedEl.value);
@@ -1338,6 +1338,14 @@ function check_delete_unsaved(tablename, script_tag) {
1338
1338
  }
1339
1339
  }
1340
1340
 
1341
+ function delprevwfroomrun(viewname, e, runid) {
1342
+ e.preventDefault();
1343
+ e.stopPropagation();
1344
+ view_post(viewname, "delprevrun", { run_id: runid });
1345
+ $(e.target).closest(".prevwfroomrun").remove();
1346
+ return false;
1347
+ }
1348
+
1341
1349
  function cfu_translate(that) {
1342
1350
  const locale = that.value;
1343
1351
  const translations = window.cfu_translations[locale];
package/routes/admin.js CHANGED
@@ -196,6 +196,8 @@ admin_config_route({
196
196
  { section_header: "Extension store" },
197
197
  "plugins_store_endpoint",
198
198
  "packs_store_endpoint",
199
+ "maintenance_mode_enabled",
200
+ "maintenance_mode_page",
199
201
  ],
200
202
  response(form, req, res) {
201
203
  send_admin_page({
@@ -487,28 +489,22 @@ router.get(
487
489
  backupForm.values.auto_backup_expire_days = getState().getConfig(
488
490
  "auto_backup_expire_days"
489
491
  );
490
- backupForm.values.storage_s3_bucket = getState().getConfig(
491
- "storage_s3_bucket"
492
+ backupForm.values.backup_s3_bucket =
493
+ getState().getConfig("backup_s3_bucket");
494
+ backupForm.values.backup_s3_endpoint =
495
+ getState().getConfig("backup_s3_endpoint");
496
+ backupForm.values.backup_s3_access_key = getState().getConfig(
497
+ "backup_s3_access_key"
492
498
  );
493
- backupForm.values.storage_s3_access_key = getState().getConfig(
494
- "storage_s3_access_key"
495
- );
496
- backupForm.values.storage_s3_access_secret = getState().getConfig(
497
- "storage_s3_access_secret"
498
- );
499
- backupForm.values.storage_s3_region = getState().getConfig(
500
- "storage_s3_region"
499
+ backupForm.values.backup_s3_access_secret = getState().getConfig(
500
+ "backup_s3_access_secret"
501
501
  );
502
+ backupForm.values.backup_s3_region =
503
+ getState().getConfig("backup_s3_region");
502
504
  aBackupFilePrefixForm.values.backup_with_event_log = getState().getConfig(
503
505
  "backup_with_event_log"
504
506
  );
505
- aBackupFilePrefixForm.values.backup_with_system_zip = getState().getConfig(
506
- "backup_with_system_zip"
507
- );
508
- aBackupFilePrefixForm.values.backup_system_zip_level = getState().getConfig(
509
- "backup_system_zip_level"
510
- );
511
- //
507
+ aBackupFilePrefixForm.values.backup_password = getState().getConfig("backup_password");
512
508
  const aSnapshotForm = snapshotForm(req);
513
509
  aSnapshotForm.values.snapshots_enabled =
514
510
  getState().getConfig("snapshots_enabled");
@@ -966,25 +962,13 @@ const backupFilePrefixForm = (req) =>
966
962
  name: "backup_with_event_log",
967
963
  },
968
964
  {
969
- type: "Bool",
970
- label: req.__("Use system zip"),
965
+ type: "String",
966
+ label: "Backup password",
967
+ fieldview: "password",
968
+ name: "backup_password",
971
969
  sublabel: req.__(
972
- "Recommended. Executable <code>zip</code> must be installed"
970
+ "Password to encrypt the backup file. Leave empty for no encryption"
973
971
  ),
974
- name: "backup_with_system_zip",
975
- },
976
- {
977
- type: "Integer",
978
- label: req.__("Zip compression level"),
979
- sublabel: req.__("1=Fast, larger file, 9=Slow, smaller files"),
980
- name: "backup_system_zip_level",
981
- attributes: {
982
- min: 1,
983
- max: 9,
984
- },
985
- showIf: {
986
- backup_with_system_zip: true,
987
- },
988
972
  },
989
973
  ],
990
974
  });
@@ -1089,18 +1073,6 @@ const autoBackupForm = (req) => {
1089
1073
  //auto_backup_destination: "Local directory",
1090
1074
  },
1091
1075
  },
1092
- {
1093
- type: "Integer",
1094
- label: req.__("Expiration in days"),
1095
- sublabel: req.__(
1096
- "Delete old backup files in this directory after the set number of days"
1097
- ),
1098
- name: "auto_backup_expire_days",
1099
- showIf: {
1100
- auto_backup_frequency: ["Daily", "Weekly"],
1101
- auto_backup_destination: "Local directory",
1102
- },
1103
- },
1104
1076
  ...(isRoot
1105
1077
  ? [
1106
1078
  {
@@ -1114,10 +1086,19 @@ const autoBackupForm = (req) => {
1114
1086
  },
1115
1087
  ]
1116
1088
  : []),
1089
+ {
1090
+ type: "String",
1091
+ label: req.__("S3 Endpoint"),
1092
+ name: "backup_s3_endpoint",
1093
+ showIf: {
1094
+ auto_backup_frequency: ["Daily", "Weekly"],
1095
+ auto_backup_destination: "S3",
1096
+ },
1097
+ },
1117
1098
  {
1118
1099
  type: "String",
1119
1100
  label: req.__("S3 Bucket Name"),
1120
- name: "storage_s3_bucket",
1101
+ name: "backup_s3_bucket",
1121
1102
  showIf: {
1122
1103
  auto_backup_frequency: ["Daily", "Weekly"],
1123
1104
  auto_backup_destination: "S3",
@@ -1126,7 +1107,7 @@ const autoBackupForm = (req) => {
1126
1107
  {
1127
1108
  type: "String",
1128
1109
  label: req.__("S3 Access Key"),
1129
- name: "storage_s3_access_key",
1110
+ name: "backup_s3_access_key",
1130
1111
  showIf: {
1131
1112
  auto_backup_frequency: ["Daily", "Weekly"],
1132
1113
  auto_backup_destination: "S3",
@@ -1136,7 +1117,7 @@ const autoBackupForm = (req) => {
1136
1117
  type: "String",
1137
1118
  label: req.__("S3 Secret Key"),
1138
1119
  fieldview: "password",
1139
- name: "storage_s3_access_secret",
1120
+ name: "backup_s3_access_secret",
1140
1121
  showIf: {
1141
1122
  auto_backup_frequency: ["Daily", "Weekly"],
1142
1123
  auto_backup_destination: "S3",
@@ -1145,12 +1126,24 @@ const autoBackupForm = (req) => {
1145
1126
  {
1146
1127
  type: "String",
1147
1128
  label: req.__("S3 Region"),
1148
- name: "storage_s3_region",
1129
+ name: "backup_s3_region",
1149
1130
  showIf: {
1150
1131
  auto_backup_frequency: ["Daily", "Weekly"],
1151
1132
  auto_backup_destination: "S3",
1152
1133
  },
1153
1134
  },
1135
+ {
1136
+ type: "Integer",
1137
+ label: req.__("Expiration in days"),
1138
+ sublabel: req.__(
1139
+ "Delete old backup files in this directory after the set number of days"
1140
+ ),
1141
+ name: "auto_backup_expire_days",
1142
+ showIf: {
1143
+ auto_backup_frequency: ["Daily", "Weekly"],
1144
+ auto_backup_destination: ["Local directory", "S3"],
1145
+ },
1146
+ },
1154
1147
  ],
1155
1148
  });
1156
1149
  };
@@ -3832,6 +3825,22 @@ router.post(
3832
3825
  spawnParams.push("--androidKeyStoreAlias", keystoreAlias);
3833
3826
  if (keystorePassword)
3834
3827
  spawnParams.push("--androidKeystorePassword", keystorePassword);
3828
+
3829
+ // if builDir exists, remove it
3830
+ if (
3831
+ await fs.promises
3832
+ .access(buildDir)
3833
+ .then(() => true)
3834
+ .catch(() => false)
3835
+ ) {
3836
+ try {
3837
+ await fs.promises.rm(buildDir, { recursive: true, force: true });
3838
+ getState().log(5, `Removed existing build directory: ${buildDir}`);
3839
+ } catch (error) {
3840
+ getState().log(4, `Error removing build directory: ${error.message}`);
3841
+ }
3842
+ }
3843
+
3835
3844
  // end http call, return the out directory name, the build directory path and the mode
3836
3845
  // the gui polls for results
3837
3846
  res.json({
package/routes/api.js CHANGED
@@ -135,6 +135,21 @@ const getFlashes = (req) =>
135
135
  })
136
136
  .filter((a) => a.msg && a.msg.length && a.msg.length > 0);
137
137
 
138
+ router.use(
139
+ error_catcher(async (req, res, next) => {
140
+ const state = getState();
141
+ const maintenanceModeEnabled = state.getConfig(
142
+ "maintenance_mode_enabled",
143
+ false
144
+ );
145
+ if (maintenanceModeEnabled && (!req.user || req.user.role_id > 1)) {
146
+ res.status(503).json({ error: "in maintenance mode" });
147
+ return;
148
+ }
149
+ next();
150
+ })
151
+ );
152
+
138
153
  router.post(
139
154
  "/viewQuery/:viewName/:queryName",
140
155
  error_catcher(async (req, res, next) => {
@@ -376,8 +391,8 @@ router.get(
376
391
  aggregations: {
377
392
  _versions: {
378
393
  table: table.name + "__history",
379
- ref: "id",
380
- field: "id",
394
+ ref: table.pk_name,
395
+ field: table.pk_name,
381
396
  aggregate: "count",
382
397
  },
383
398
  },
@@ -446,6 +461,44 @@ router.get(
446
461
  })
447
462
  );
448
463
 
464
+ router.get("/:tableName/count", async (req, res, next) => {
465
+ const { tableName } = req.params;
466
+ const { approximate, ...req_query } = req.query;
467
+
468
+ const table = Table.findOne(
469
+ strictParseInt(tableName)
470
+ ? { id: strictParseInt(tableName) }
471
+ : { name: tableName }
472
+ );
473
+ if (!table) {
474
+ getState().log(3, `API get ${tableName} table not found`);
475
+ res.status(404).json({ error: req.__("Not found") });
476
+ return;
477
+ }
478
+ await passport.authenticate(
479
+ ["api-bearer", "jwt"],
480
+ { session: false },
481
+ async function (err, user, info) {
482
+ if (accessAllowedRead(req, user, table)) {
483
+ const tbl_fields = table.getFields();
484
+ readState(req_query, tbl_fields, req);
485
+ const qstate = stateFieldsToWhere({
486
+ fields: tbl_fields,
487
+ approximate: !!approximate,
488
+ state: req_query,
489
+ table,
490
+ prefix: "a.",
491
+ });
492
+ const count = await table.countRows(qstate);
493
+ res.json({ success: count });
494
+ } else {
495
+ getState().log(3, `API get ${table.name} not authorized`);
496
+ res.status(401).json({ error: req.__("Not authorized") });
497
+ }
498
+ }
499
+ )(req, res, next);
500
+ });
501
+
449
502
  /**
450
503
  * Emit Event using POST
451
504
  * This is used from the mobile app to send an event to the server.
package/routes/files.js CHANGED
@@ -52,6 +52,18 @@ const { extract } = require("@saltcorn/admin-models/models/backup");
52
52
  const router = new Router();
53
53
  module.exports = router;
54
54
 
55
+ router.use(
56
+ error_catcher(async (req, res, next) => {
57
+ const state = getState();
58
+ const maintenanceModeEnabled = state.getConfig("maintenance_mode_enabled", false);
59
+ if (maintenanceModeEnabled && (!req.user || req.user.role_id > 1)) {
60
+ res.status(503).send("Page Unavailable: in maintenance mode");
61
+ return;
62
+ }
63
+ next();
64
+ })
65
+ )
66
+
55
67
  const send_files_picker = async (folder, noSubdirs, inputId, req, res) => {
56
68
  res.set("SaltcornModalWidth", "1200px");
57
69
  res.sendWrap(req.__("Please select a file"), {
@@ -15,7 +15,7 @@ const Page = require("@saltcorn/data/models/page");
15
15
  const PageGroup = require("@saltcorn/data/models/page_group");
16
16
  const Plugin = require("@saltcorn/data/models/plugin");
17
17
  const { link, mkTable } = require("@saltcorn/markup");
18
- const { div, a, p, i, h5, span } = require("@saltcorn/markup/tags");
18
+ const { div, a, p, i, h5, span, title } = require("@saltcorn/markup/tags");
19
19
  const Table = require("@saltcorn/data/models/table");
20
20
  const { get_cached_packs } = require("@saltcorn/admin-models/models/pack");
21
21
  // const { restore_backup } = require("../markup/admin");
@@ -553,6 +553,28 @@ const no_views_logged_in = async (req, res) => {
553
553
  * @returns {Promise<boolean>}
554
554
  */
555
555
  const get_config_response = async (role_id, res, req) => {
556
+ const state = getState();
557
+ const maintenanceModeEnabled = state.getConfig("maintenance_mode_enabled", false);
558
+ const maintenanceModePage = state.getConfig("maintenance_mode_page", "");
559
+
560
+ if(maintenanceModeEnabled && (!req.user || req.user.role_id > 1) && maintenanceModePage) {
561
+ const db_page = await Page.findOne({ name: maintenanceModePage });
562
+ if (db_page) {
563
+ res.sendWrap(
564
+ {
565
+ title: db_page.title,
566
+ description: db_page.description,
567
+ bodyClass: "page_" + db.sqlsanitize(maintenanceModePage),
568
+ },
569
+ await db_page.run(req.query, { res, req })
570
+ );
571
+ return true;
572
+ } else {
573
+ res.status(503).send("Page Unavailable: in maintenance mode");
574
+ return true;
575
+ }
576
+ }
577
+
556
578
  const wrap = async (
557
579
  contents,
558
580
  homeCfg,
package/routes/list.js CHANGED
@@ -65,7 +65,7 @@ router.get(
65
65
 
66
66
  const fields = table.getFields();
67
67
  var tfields = fields.map((f) => ({ label: f.label, key: f.listKey }));
68
-
68
+ const pk_name = table.pk_name;
69
69
  tfields.push({
70
70
  label: req.__("Version"),
71
71
  key: (r) => r._version,
@@ -82,7 +82,7 @@ router.get(
82
82
  label: req.__("Restore"),
83
83
  key: (r) =>
84
84
  post_btn(
85
- `/list/_restore/${table.name}/${r.id}/${r._version}`,
85
+ `/list/_restore/${table.name}/${r[pk_name]}/${r._version}`,
86
86
  req.__("Restore"),
87
87
  req.csrfToken()
88
88
  ),
@@ -281,6 +281,7 @@ router.get(
281
281
  field: "_versions",
282
282
  title: "Versions",
283
283
  formatter: "__versionsFormatter",
284
+ formatterParams: { pk_name: table.pk_name },
284
285
  });
285
286
  }
286
287
  jsfields.push({
@@ -466,7 +467,7 @@ router.get(
466
467
  window.tabulator_table.on("cellEdited", function(cell){
467
468
  const row = cell.getRow().getData()
468
469
  const fieldName = cell.getColumn().getField()
469
- let ident = (row.${pkNm}||"");
470
+ let ident = encodeURIComponent(row.${pkNm}||"");
470
471
  if(fieldName === "${pkNm}")
471
472
  ident = "";
472
473
  ajax_indicator(true);
package/routes/menu.js CHANGED
@@ -624,6 +624,20 @@ router.post(
624
624
  })
625
625
  );
626
626
 
627
+ router.post(
628
+ "/action/:rndid",
629
+ error_catcher(async (req, res, next) => {
630
+ const state = getState();
631
+ const maintenanceModeEnabled = state.getConfig("maintenance_mode_enabled", false);
632
+
633
+ if (maintenanceModeEnabled && (!req.user || req.user.role_id > 1)) {
634
+ res.status(503).json({ error: "in maintenance mode" });
635
+ return;
636
+ }
637
+ next();
638
+ }),
639
+ );
640
+
627
641
  const getIcons = () => {
628
642
  return getState().icons;
629
643
  };
@@ -20,6 +20,18 @@ const db = require("@saltcorn/data/db");
20
20
  const router = new Router();
21
21
  module.exports = router;
22
22
 
23
+ router.use(
24
+ error_catcher(async (req, res, next) => {
25
+ const state = getState();
26
+ const maintenanceModeEnabled = state.getConfig("maintenance_mode_enabled", false);
27
+ if (maintenanceModeEnabled && (!req.user || req.user.role_id > 1)) {
28
+ res.status(503).send("Page Unavailable: in maintenance mode");
29
+ return;
30
+ }
31
+ next();
32
+ })
33
+ );
34
+
23
35
  const notificationSettingsForm = () =>
24
36
  new Form({
25
37
  action: `/notifications/settings`,