@saltcorn/server 1.1.4-beta.1 → 1.1.4-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 (415) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/auth/admin.js +24 -1
  3. package/auth/resetpw.js +1 -1
  4. package/auth/roleadmin.js +1 -4
  5. package/auth/routes.js +57 -1
  6. package/docs/assets/search.js +1 -1
  7. package/docs/classes/_saltcorn_common_code.Relation.html +31 -9
  8. package/docs/classes/_saltcorn_common_code.RelationsFinder.html +5 -5
  9. package/docs/classes/_saltcorn_data.models.Crash-1.html +18 -18
  10. package/docs/classes/_saltcorn_data.models.EventLog-1.html +19 -19
  11. package/docs/classes/_saltcorn_data.models.Field.html +71 -71
  12. package/docs/classes/_saltcorn_data.models.FieldRepeat-1.html +17 -17
  13. package/docs/classes/_saltcorn_data.models.File-1.html +48 -48
  14. package/docs/classes/_saltcorn_data.models.Form-1.html +38 -38
  15. package/docs/classes/_saltcorn_data.models.Library.html +13 -13
  16. package/docs/classes/_saltcorn_data.models.Page.html +24 -24
  17. package/docs/classes/_saltcorn_data.models.PageGroup-1.html +25 -25
  18. package/docs/classes/_saltcorn_data.models.Plugin.html +25 -25
  19. package/docs/classes/_saltcorn_data.models.Role.html +9 -9
  20. package/docs/classes/_saltcorn_data.models.Table-1.html +111 -96
  21. package/docs/classes/_saltcorn_data.models.TableConstraint-1.html +14 -14
  22. package/docs/classes/_saltcorn_data.models.Trigger.html +36 -36
  23. package/docs/classes/_saltcorn_data.models.User-1.html +50 -50
  24. package/docs/classes/_saltcorn_data.models.View-1.html +52 -52
  25. package/docs/classes/_saltcorn_data.models.Workflow-1.html +17 -17
  26. package/docs/classes/_saltcorn_data.models.WorkflowRun.html +35 -35
  27. package/docs/classes/_saltcorn_data.models.WorkflowStep.html +25 -25
  28. package/docs/classes/_saltcorn_data.models.WorkflowTrace.html +18 -18
  29. package/docs/classes/_saltcorn_mobile_builder.MobileBuilder.html +36 -36
  30. package/docs/enums/_saltcorn_common_code.RelationType.html +7 -7
  31. package/docs/enums/_saltcorn_common_code.ViewDisplayType.html +4 -4
  32. package/docs/functions/_saltcorn_admin_models.backup.create_backup.html +1 -1
  33. package/docs/functions/_saltcorn_admin_models.backup.create_csv_from_rows.html +1 -1
  34. package/docs/functions/_saltcorn_admin_models.backup.restore.html +1 -1
  35. package/docs/functions/_saltcorn_admin_models.pack.add_to_menu.html +1 -1
  36. package/docs/functions/_saltcorn_admin_models.pack.can_install_pack.html +1 -1
  37. package/docs/functions/_saltcorn_admin_models.pack.fetch_available_packs.html +1 -1
  38. package/docs/functions/_saltcorn_admin_models.pack.fetch_pack_by_name.html +1 -1
  39. package/docs/functions/_saltcorn_admin_models.pack.install_pack.html +1 -1
  40. package/docs/functions/_saltcorn_admin_models.pack.library_pack.html +1 -1
  41. package/docs/functions/_saltcorn_admin_models.pack.model_instance_pack.html +1 -1
  42. package/docs/functions/_saltcorn_admin_models.pack.model_pack.html +1 -1
  43. package/docs/functions/_saltcorn_admin_models.pack.page_group_pack.html +1 -1
  44. package/docs/functions/_saltcorn_admin_models.pack.page_pack.html +1 -1
  45. package/docs/functions/_saltcorn_admin_models.pack.plugin_pack.html +1 -1
  46. package/docs/functions/_saltcorn_admin_models.pack.role_pack.html +1 -1
  47. package/docs/functions/_saltcorn_admin_models.pack.table_pack.html +1 -1
  48. package/docs/functions/_saltcorn_admin_models.pack.trigger_pack.html +1 -1
  49. package/docs/functions/_saltcorn_admin_models.pack.uninstall_pack.html +1 -1
  50. package/docs/functions/_saltcorn_admin_models.pack.view_pack.html +1 -1
  51. package/docs/functions/_saltcorn_admin_models.tenant.copy_tenant_template.html +1 -1
  52. package/docs/functions/_saltcorn_admin_models.tenant.create_tenant.html +1 -1
  53. package/docs/functions/_saltcorn_admin_models.tenant.deleteTenant.html +1 -1
  54. package/docs/functions/_saltcorn_admin_models.tenant.domain_sanitize.html +1 -1
  55. package/docs/functions/_saltcorn_admin_models.tenant.eachTenant.html +1 -1
  56. package/docs/functions/_saltcorn_admin_models.tenant.getAllTenantRows.html +1 -1
  57. package/docs/functions/_saltcorn_admin_models.tenant.getAllTenants.html +1 -1
  58. package/docs/functions/_saltcorn_admin_models.tenant.insertTenant.html +1 -1
  59. package/docs/functions/_saltcorn_admin_models.tenant.switchToTenant.html +1 -1
  60. package/docs/functions/_saltcorn_common_code.buildTableCaches.html +1 -1
  61. package/docs/functions/_saltcorn_common_code.parseLegacyRelation.html +1 -1
  62. package/docs/functions/_saltcorn_common_code.parseRelationPath.html +1 -1
  63. package/docs/functions/_saltcorn_data.models.config.check_email_mask.html +1 -1
  64. package/docs/functions/_saltcorn_data.models.config.deleteConfig.html +1 -1
  65. package/docs/functions/_saltcorn_data.models.config.getAllConfig.html +1 -1
  66. package/docs/functions/_saltcorn_data.models.config.getConfig.html +1 -1
  67. package/docs/functions/_saltcorn_data.models.config.get_base_url.html +1 -1
  68. package/docs/functions/_saltcorn_data.models.config.get_latest_npm_version.html +1 -1
  69. package/docs/functions/_saltcorn_data.models.config.remove_from_menu.html +1 -1
  70. package/docs/functions/_saltcorn_data.models.config.save_menu_items.html +1 -1
  71. package/docs/functions/_saltcorn_data.models.config.setConfig.html +1 -1
  72. package/docs/functions/_saltcorn_data.models.discovery.discover_tables.html +1 -1
  73. package/docs/functions/_saltcorn_data.models.discovery.discoverable_tables.html +1 -1
  74. package/docs/functions/_saltcorn_data.models.discovery.findType.html +3 -3
  75. package/docs/functions/_saltcorn_data.models.discovery.get_existing_views.html +1 -1
  76. package/docs/functions/_saltcorn_data.models.discovery.implement_discovery.html +1 -1
  77. package/docs/functions/_saltcorn_data.models.email.getMailTransport.html +3 -3
  78. package/docs/functions/_saltcorn_data.models.email.send_verification_email.html +1 -1
  79. package/docs/functions/_saltcorn_data.models.email.viewToEmailHtml.html +1 -1
  80. package/docs/functions/_saltcorn_data.models.expression.apply_calculated_fields.html +1 -1
  81. package/docs/functions/_saltcorn_data.models.expression.apply_calculated_fields_stored.html +1 -1
  82. package/docs/functions/_saltcorn_data.models.expression.eval_expression.html +1 -1
  83. package/docs/functions/_saltcorn_data.models.expression.expressionValidator.html +1 -1
  84. package/docs/functions/_saltcorn_data.models.expression.get_async_expression_function.html +1 -1
  85. package/docs/functions/_saltcorn_data.models.expression.get_expression_function.html +1 -1
  86. package/docs/functions/_saltcorn_data.models.expression.jsexprToWhere.html +1 -1
  87. package/docs/functions/_saltcorn_data.models.expression.recalculate_for_stored.html +1 -1
  88. package/docs/functions/_saltcorn_data.models.expression.transform_for_async.html +1 -1
  89. package/docs/functions/_saltcorn_data.models.layout.eachView.html +1 -1
  90. package/docs/functions/_saltcorn_data.models.layout.getStringsForI18n.html +1 -1
  91. package/docs/functions/_saltcorn_data.models.layout.getViews.html +1 -1
  92. package/docs/functions/_saltcorn_data.models.layout.translateLayout.html +1 -1
  93. package/docs/functions/_saltcorn_data.models.layout.traverse.html +1 -1
  94. package/docs/functions/_saltcorn_data.models.layout.traverseSync.html +1 -1
  95. package/docs/functions/_saltcorn_data.models.random.all_views.html +1 -1
  96. package/docs/functions/_saltcorn_data.models.random.fill_table_row.html +1 -1
  97. package/docs/functions/_saltcorn_data.models.random.initial_view.html +1 -1
  98. package/docs/functions/_saltcorn_data.models.random.random_table.html +1 -1
  99. package/docs/functions/_saltcorn_db_common.buildInsertBulkSql.html +1 -1
  100. package/docs/functions/_saltcorn_db_common.buildInsertSql.html +1 -1
  101. package/docs/functions/_saltcorn_db_common.doCount.html +1 -1
  102. package/docs/functions/_saltcorn_db_common.doDeleteWhere.html +1 -1
  103. package/docs/functions/_saltcorn_db_common.doListScTables.html +1 -1
  104. package/docs/functions/_saltcorn_db_common.doListTables.html +1 -1
  105. package/docs/functions/_saltcorn_db_common.doListUserDefinedTables.html +1 -1
  106. package/docs/functions/_saltcorn_db_common.do_add_index.html +1 -1
  107. package/docs/functions/_saltcorn_db_common.do_drop_index.html +1 -1
  108. package/docs/functions/_saltcorn_db_common.ftsFieldsSqlExpr.html +1 -1
  109. package/docs/functions/_saltcorn_db_common.mkSelectOptions.html +1 -1
  110. package/docs/functions/_saltcorn_db_common.mkVal.html +1 -1
  111. package/docs/functions/_saltcorn_db_common.mkWhere.html +1 -1
  112. package/docs/functions/_saltcorn_db_common.multi_tenant.enable_multi_tenant.html +1 -1
  113. package/docs/functions/_saltcorn_db_common.multi_tenant.getRequestContext.html +1 -1
  114. package/docs/functions/_saltcorn_db_common.multi_tenant.getTenantSchema.html +1 -1
  115. package/docs/functions/_saltcorn_db_common.multi_tenant.init.html +1 -1
  116. package/docs/functions/_saltcorn_db_common.multi_tenant.is_it_multi_tenant.html +1 -1
  117. package/docs/functions/_saltcorn_db_common.multi_tenant.runWithTenant.html +1 -1
  118. package/docs/functions/_saltcorn_db_common.orderByIsObject.html +1 -1
  119. package/docs/functions/_saltcorn_db_common.orderByIsOperator.html +1 -1
  120. package/docs/functions/_saltcorn_db_common.prefixFieldsInWhere.html +1 -1
  121. package/docs/functions/_saltcorn_db_common.reprAsJson.html +1 -1
  122. package/docs/functions/_saltcorn_db_common.sqlBinOp.html +1 -1
  123. package/docs/functions/_saltcorn_db_common.sqlFun.html +1 -1
  124. package/docs/functions/_saltcorn_db_common.sqlsanitize.html +1 -1
  125. package/docs/functions/_saltcorn_db_common.sqlsanitizeAllowDots.html +1 -1
  126. package/docs/functions/_saltcorn_db_common.subSelectWhere.html +1 -1
  127. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.androidFeatures.html +1 -1
  128. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.androidPermissions.html +1 -1
  129. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.buildTablesFile.html +1 -1
  130. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.copyPrepopulatedDb.html +1 -1
  131. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.copyServerFiles.html +1 -1
  132. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.copyShareExtFiles.html +1 -1
  133. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.copySiteLogo.html +1 -1
  134. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.copyTranslationFiles.html +1 -1
  135. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.createSqliteDb.html +1 -1
  136. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.decodeProvisioningProfile.html +1 -1
  137. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.extractDomain.html +1 -1
  138. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.generateAndroidVersionCode.html +1 -1
  139. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.modifyAndroidManifest.html +1 -1
  140. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.modifyConfigXml.html +1 -1
  141. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.modifyGradleConfig.html +1 -1
  142. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.modifyInfoPlist.html +1 -1
  143. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.modifyXcodeProjectFile.html +1 -1
  144. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.prepAppIcon.html +1 -1
  145. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.prepareAppIcon.html +1 -1
  146. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.prepareBuildDir.html +1 -1
  147. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.prepareExportOptionsPlist.html +1 -1
  148. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.prepareSplashIcon.html +1 -1
  149. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.prepareSplashPage.html +1 -1
  150. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.writeCapacitorConfig.html +1 -1
  151. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.writeCfgFile.html +1 -1
  152. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.writeDataExtractionRules.html +1 -1
  153. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.writeNetworkSecurityConfig.html +1 -1
  154. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.writePodfile.html +1 -1
  155. package/docs/functions/_saltcorn_mobile_builder.common_build_utils.writePrivacyInfo.html +1 -1
  156. package/docs/functions/_saltcorn_mobile_builder.package_bundle_utils.bundleMobileAppCode.html +1 -1
  157. package/docs/functions/_saltcorn_mobile_builder.package_bundle_utils.bundlePackagesAndPlugins.html +1 -1
  158. package/docs/functions/_saltcorn_mobile_builder.package_bundle_utils.copyMobileAppDirs.html +1 -1
  159. package/docs/functions/_saltcorn_mobile_builder.package_bundle_utils.copyPublicDirs.html +1 -1
  160. package/docs/functions/_saltcorn_sqlite.add_index.html +2 -1
  161. package/docs/functions/_saltcorn_sqlite.add_unique_constraint.html +2 -1
  162. package/docs/functions/_saltcorn_sqlite.begin.html +2 -1
  163. package/docs/functions/_saltcorn_sqlite.changeConnection.html +2 -1
  164. package/docs/functions/_saltcorn_sqlite.close.html +2 -1
  165. package/docs/functions/_saltcorn_sqlite.commit.html +2 -1
  166. package/docs/functions/_saltcorn_sqlite.count.html +2 -1
  167. package/docs/functions/_saltcorn_sqlite.deleteWhere.html +2 -1
  168. package/docs/functions/_saltcorn_sqlite.dropTable.html +2 -1
  169. package/docs/functions/_saltcorn_sqlite.dropTables.html +2 -1
  170. package/docs/functions/_saltcorn_sqlite.drop_index.html +2 -1
  171. package/docs/functions/_saltcorn_sqlite.drop_reset_schema.html +2 -1
  172. package/docs/functions/_saltcorn_sqlite.drop_unique_constraint.html +2 -1
  173. package/docs/functions/_saltcorn_sqlite.getVersion.html +2 -1
  174. package/docs/functions/_saltcorn_sqlite.get_db_filepath.html +2 -1
  175. package/docs/functions/_saltcorn_sqlite.get_sql_logging.html +2 -1
  176. package/docs/functions/_saltcorn_sqlite.init.html +2 -1
  177. package/docs/functions/_saltcorn_sqlite.insert.html +2 -1
  178. package/docs/functions/_saltcorn_sqlite.listScTables.html +2 -1
  179. package/docs/functions/_saltcorn_sqlite.listTables.html +2 -1
  180. package/docs/functions/_saltcorn_sqlite.listUserDefinedTables.html +2 -1
  181. package/docs/functions/_saltcorn_sqlite.query.html +2 -1
  182. package/docs/functions/_saltcorn_sqlite.rollback.html +2 -1
  183. package/docs/functions/_saltcorn_sqlite.select.html +2 -1
  184. package/docs/functions/_saltcorn_sqlite.selectMaybeOne.html +2 -1
  185. package/docs/functions/_saltcorn_sqlite.selectOne.html +2 -1
  186. package/docs/functions/_saltcorn_sqlite.set_sql_logging.html +2 -1
  187. package/docs/functions/_saltcorn_sqlite.slugify.html +2 -1
  188. package/docs/functions/_saltcorn_sqlite.sql_log.html +2 -1
  189. package/docs/functions/_saltcorn_sqlite.tryCatchInTransaction.html +97 -0
  190. package/docs/functions/_saltcorn_sqlite.update.html +2 -1
  191. package/docs/functions/_saltcorn_sqlite.updateWhere.html +2 -1
  192. package/docs/functions/_saltcorn_sqlite.withTransaction.html +2 -1
  193. package/docs/functions/_saltcorn_sqlite_mobile.add_index.html +1 -1
  194. package/docs/functions/_saltcorn_sqlite_mobile.add_unique_constraint.html +1 -1
  195. package/docs/functions/_saltcorn_sqlite_mobile.count.html +1 -1
  196. package/docs/functions/_saltcorn_sqlite_mobile.deleteWhere.html +1 -1
  197. package/docs/functions/_saltcorn_sqlite_mobile.drop_index.html +1 -1
  198. package/docs/functions/_saltcorn_sqlite_mobile.drop_reset_schema.html +1 -1
  199. package/docs/functions/_saltcorn_sqlite_mobile.drop_unique_constraint.html +1 -1
  200. package/docs/functions/_saltcorn_sqlite_mobile.init.html +1 -1
  201. package/docs/functions/_saltcorn_sqlite_mobile.insert.html +1 -1
  202. package/docs/functions/_saltcorn_sqlite_mobile.insertRows.html +1 -1
  203. package/docs/functions/_saltcorn_sqlite_mobile.listScTables.html +1 -1
  204. package/docs/functions/_saltcorn_sqlite_mobile.listTables.html +1 -1
  205. package/docs/functions/_saltcorn_sqlite_mobile.listUserDefinedTables.html +1 -1
  206. package/docs/functions/_saltcorn_sqlite_mobile.query.html +1 -1
  207. package/docs/functions/_saltcorn_sqlite_mobile.select.html +1 -1
  208. package/docs/functions/_saltcorn_sqlite_mobile.selectMaybeOne.html +1 -1
  209. package/docs/functions/_saltcorn_sqlite_mobile.selectOne.html +1 -1
  210. package/docs/functions/_saltcorn_sqlite_mobile.setConnectionObject.html +1 -1
  211. package/docs/functions/_saltcorn_sqlite_mobile.tableExists.html +1 -1
  212. package/docs/functions/_saltcorn_sqlite_mobile.time.html +1 -1
  213. package/docs/functions/_saltcorn_sqlite_mobile.update.html +1 -1
  214. package/docs/functions/_saltcorn_types.ModelAbstracts.abstract_field.instanceOfField.html +1 -1
  215. package/docs/functions/_saltcorn_types.ModelAbstracts.abstract_page.instanceOfPage.html +1 -1
  216. package/docs/functions/_saltcorn_types.ModelAbstracts.abstract_view.instanceOfView.html +1 -1
  217. package/docs/functions/_saltcorn_types.Types.base_types.instanceOWithHtmlFile.html +1 -1
  218. package/docs/functions/_saltcorn_types.Types.common_types.instanceOfErrorMsg.html +1 -1
  219. package/docs/functions/_saltcorn_types.Types.common_types.instanceOfSuccessMsg.html +1 -1
  220. package/docs/functions/_saltcorn_types.Types.common_types.instanceOfType.html +1 -1
  221. package/docs/functions/_saltcorn_types.generators.generateBool.html +1 -1
  222. package/docs/functions/_saltcorn_types.generators.generateString.html +1 -1
  223. package/docs/functions/_saltcorn_types.generators.num_between.html +1 -1
  224. package/docs/functions/_saltcorn_types.generators.oneOf.html +1 -1
  225. package/docs/interfaces/_saltcorn_mobile_builder.common_build_utils.ScCapacitorConfig.html +10 -10
  226. package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_field.AbstractField.html +14 -14
  227. package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_field.AbstractFieldRepeat.html +3 -3
  228. package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_form.AbstractForm.html +26 -26
  229. package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_page.AbstractPage.html +7 -7
  230. package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_role.AbstractRole.html +3 -3
  231. package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_table.AbstractTable.html +7 -7
  232. package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_trigger.AbstractTrigger.html +16 -16
  233. package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_view.AbstractView.html +10 -10
  234. package/docs/interfaces/_saltcorn_types.ModelAbstracts.abstract_workflow.AbstractWorkflow.html +13 -13
  235. package/docs/modules/_saltcorn_admin_models.backup.html +1 -1
  236. package/docs/modules/_saltcorn_admin_models.html +1 -1
  237. package/docs/modules/_saltcorn_admin_models.pack.html +1 -1
  238. package/docs/modules/_saltcorn_admin_models.tenant.html +1 -1
  239. package/docs/modules/_saltcorn_common_code.html +1 -1
  240. package/docs/modules/_saltcorn_data.html +56 -18
  241. package/docs/modules/_saltcorn_data.models.Crash.html +2 -2
  242. package/docs/modules/_saltcorn_data.models.EventLog.html +2 -2
  243. package/docs/modules/_saltcorn_data.models.FieldRepeat.html +2 -2
  244. package/docs/modules/_saltcorn_data.models.File.html +2 -2
  245. package/docs/modules/_saltcorn_data.models.Form.html +2 -2
  246. package/docs/modules/_saltcorn_data.models.PageGroup.html +2 -2
  247. package/docs/modules/_saltcorn_data.models.Table.html +2 -2
  248. package/docs/modules/_saltcorn_data.models.TableConstraint.html +2 -2
  249. package/docs/modules/_saltcorn_data.models.User.html +2 -2
  250. package/docs/modules/_saltcorn_data.models.View.html +2 -2
  251. package/docs/modules/_saltcorn_data.models.Workflow.html +2 -2
  252. package/docs/modules/_saltcorn_data.models.config.html +1 -1
  253. package/docs/modules/_saltcorn_data.models.discovery.html +1 -1
  254. package/docs/modules/_saltcorn_data.models.email.html +1 -1
  255. package/docs/modules/_saltcorn_data.models.expression.html +1 -1
  256. package/docs/modules/_saltcorn_data.models.html +1 -1
  257. package/docs/modules/_saltcorn_data.models.layout.html +1 -1
  258. package/docs/modules/_saltcorn_data.models.random.html +1 -1
  259. package/docs/modules/_saltcorn_data.models.scheduler.html +1 -1
  260. package/docs/modules/_saltcorn_data.plugin_helper.html +1 -1
  261. package/docs/modules/_saltcorn_data.utils.html +1 -1
  262. package/docs/modules/_saltcorn_db_common.html +2 -2
  263. package/docs/modules/_saltcorn_db_common.multi_tenant.html +1 -1
  264. package/docs/modules/_saltcorn_markup.html +13 -13
  265. package/docs/modules/_saltcorn_mobile_builder.common_build_utils.html +1 -1
  266. package/docs/modules/_saltcorn_mobile_builder.html +1 -1
  267. package/docs/modules/_saltcorn_mobile_builder.package_bundle_utils.html +1 -1
  268. package/docs/modules/_saltcorn_sqlite.html +3 -1
  269. package/docs/modules/_saltcorn_sqlite_mobile.html +1 -1
  270. package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_field.html +1 -1
  271. package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_form.html +1 -1
  272. package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_library.html +1 -1
  273. package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_page.html +1 -1
  274. package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_plugin.html +1 -1
  275. package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_role.html +1 -1
  276. package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_table.html +1 -1
  277. package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_trigger.html +1 -1
  278. package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_view.html +1 -1
  279. package/docs/modules/_saltcorn_types.ModelAbstracts.abstract_workflow.html +1 -1
  280. package/docs/modules/_saltcorn_types.ModelAbstracts.html +1 -1
  281. package/docs/modules/_saltcorn_types.Types.base_types.html +1 -1
  282. package/docs/modules/_saltcorn_types.Types.common_types.html +1 -1
  283. package/docs/modules/_saltcorn_types.Types.html +1 -1
  284. package/docs/modules/_saltcorn_types.generators.html +1 -1
  285. package/docs/modules/_saltcorn_types.html +1 -1
  286. package/docs/types/_saltcorn_data.models.Crash.CrashCfg.html +1 -1
  287. package/docs/types/_saltcorn_data.models.EventLog.EventLogCfg.html +1 -1
  288. package/docs/types/_saltcorn_data.models.FieldRepeat.FieldRepeatCfg.html +1 -1
  289. package/docs/types/_saltcorn_data.models.File.FileCfg.html +1 -1
  290. package/docs/types/_saltcorn_data.models.Form.AdditionalButton.html +1 -1
  291. package/docs/types/_saltcorn_data.models.Form.FormCfg.html +1 -1
  292. package/docs/types/_saltcorn_data.models.PageGroup.ScreenInfoParams.html +1 -1
  293. package/docs/types/_saltcorn_data.models.Table.ChildRelations.html +1 -1
  294. package/docs/types/_saltcorn_data.models.Table.ParentRelations.html +1 -1
  295. package/docs/types/_saltcorn_data.models.Table.RelationData.html +1 -1
  296. package/docs/types/_saltcorn_data.models.TableConstraint.TableConstraintCfg.html +1 -1
  297. package/docs/types/_saltcorn_data.models.User.UserCfg.html +1 -1
  298. package/docs/types/_saltcorn_data.models.View.FindViewsPred.html +1 -1
  299. package/docs/types/_saltcorn_data.models.Workflow.WorkflowCfg.html +1 -1
  300. package/docs/types/_saltcorn_db_common.AggregationOptions.html +1 -1
  301. package/docs/types/_saltcorn_db_common.CoordOpts.html +1 -1
  302. package/docs/types/_saltcorn_db_common.DatabaseClient.html +1 -1
  303. package/docs/types/_saltcorn_db_common.JoinField.html +1 -1
  304. package/docs/types/_saltcorn_db_common.JoinFields.html +1 -1
  305. package/docs/types/_saltcorn_db_common.JoinOptions.html +1 -1
  306. package/docs/types/_saltcorn_db_common.JsonPath.html +1 -1
  307. package/docs/types/_saltcorn_db_common.JsonPathElem.html +1 -1
  308. package/docs/types/_saltcorn_db_common.Operator.html +1 -1
  309. package/docs/types/_saltcorn_db_common.PrimaryKeyValue.html +1 -1
  310. package/docs/types/_saltcorn_db_common.Row.html +1 -1
  311. package/docs/types/_saltcorn_db_common.SelectOptions.html +1 -1
  312. package/docs/types/_saltcorn_db_common.SqlAndValues.html +1 -1
  313. package/docs/types/_saltcorn_db_common.SubselectOptions.html +1 -1
  314. package/docs/types/_saltcorn_db_common.Value.html +1 -1
  315. package/docs/types/_saltcorn_db_common.Where.html +1 -1
  316. package/docs/types/_saltcorn_mobile_builder.IosCfg.html +1 -1
  317. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_field.FieldCfg.html +1 -1
  318. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_field.InputType.html +1 -1
  319. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_form.AdditionalButton.html +1 -1
  320. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_library.LibraryCfg.html +1 -1
  321. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_library.LibraryPack.html +1 -1
  322. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_page.PageCfg.html +1 -1
  323. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_page.PagePack.html +1 -1
  324. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_plugin.PluginCfg.html +1 -1
  325. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_plugin.PluginPack.html +1 -1
  326. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_role.RoleCfg.html +1 -1
  327. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_role.RolePack.html +1 -1
  328. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_table.TableCfg.html +1 -1
  329. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_table.TablePack.html +1 -1
  330. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_trigger.TriggerCfg.html +1 -1
  331. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_trigger.TriggerPack.html +1 -1
  332. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_view.ViewCfg.html +1 -1
  333. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_view.ViewPack.html +1 -1
  334. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_workflow.ConfigWorkflowStep.html +1 -1
  335. package/docs/types/_saltcorn_types.ModelAbstracts.abstract_workflow.RunResult.html +1 -1
  336. package/docs/types/_saltcorn_types.Types.base_types.Action.html +1 -1
  337. package/docs/types/_saltcorn_types.Types.base_types.AuthenticationMethod.html +1 -1
  338. package/docs/types/_saltcorn_types.Types.base_types.CapacitorPlugin.html +1 -1
  339. package/docs/types/_saltcorn_types.Types.base_types.CodePagePack.html +1 -1
  340. package/docs/types/_saltcorn_types.Types.base_types.Column.html +1 -1
  341. package/docs/types/_saltcorn_types.Types.base_types.ConnectedObjects.html +1 -1
  342. package/docs/types/_saltcorn_types.Types.base_types.CopilotSkill.html +1 -1
  343. package/docs/types/_saltcorn_types.Types.base_types.FieldLike.html +1 -1
  344. package/docs/types/_saltcorn_types.Types.base_types.FieldView.html +1 -1
  345. package/docs/types/_saltcorn_types.Types.base_types.Header.html +1 -1
  346. package/docs/types/_saltcorn_types.Types.base_types.JoinFieldOption.html +1 -1
  347. package/docs/types/_saltcorn_types.Types.base_types.Layout.html +1 -1
  348. package/docs/types/_saltcorn_types.Types.base_types.MobileConfig.html +1 -1
  349. package/docs/types/_saltcorn_types.Types.base_types.ModelPattern.html +1 -1
  350. package/docs/types/_saltcorn_types.Types.base_types.Pack.html +1 -1
  351. package/docs/types/_saltcorn_types.Types.base_types.Plugin.html +1 -1
  352. package/docs/types/_saltcorn_types.Types.base_types.PluginFunction.html +5 -5
  353. package/docs/types/_saltcorn_types.Types.base_types.PluginLayout.html +1 -1
  354. package/docs/types/_saltcorn_types.Types.base_types.PluginRoute.html +1 -1
  355. package/docs/types/_saltcorn_types.Types.base_types.PluginSourceType.html +1 -1
  356. package/docs/types/_saltcorn_types.Types.base_types.PluginType.html +1 -1
  357. package/docs/types/_saltcorn_types.Types.base_types.PluginWrap.html +1 -1
  358. package/docs/types/_saltcorn_types.Types.base_types.PluginWrapArg.html +1 -1
  359. package/docs/types/_saltcorn_types.Types.base_types.RelationOption.html +1 -1
  360. package/docs/types/_saltcorn_types.Types.base_types.Req.html +1 -1
  361. package/docs/types/_saltcorn_types.Types.base_types.Res.html +1 -1
  362. package/docs/types/_saltcorn_types.Types.base_types.RouteAction.html +1 -1
  363. package/docs/types/_saltcorn_types.Types.base_types.RunExtra.html +1 -1
  364. package/docs/types/_saltcorn_types.Types.base_types.TableProvider.html +5 -5
  365. package/docs/types/_saltcorn_types.Types.base_types.TableQuery.html +1 -1
  366. package/docs/types/_saltcorn_types.Types.base_types.Tablely.html +1 -1
  367. package/docs/types/_saltcorn_types.Types.base_types.ViewTemplate.html +1 -1
  368. package/docs/types/_saltcorn_types.Types.common_types.ErrorMessage.html +1 -1
  369. package/docs/types/_saltcorn_types.Types.common_types.GenObj.html +1 -1
  370. package/docs/types/_saltcorn_types.Types.common_types.ReqRes.html +1 -1
  371. package/docs/types/_saltcorn_types.Types.common_types.ResultMessage.html +1 -1
  372. package/docs/types/_saltcorn_types.Types.common_types.SuccessMessage.html +1 -1
  373. package/docs/types/_saltcorn_types.Types.common_types.Type.html +17 -4
  374. package/docs/variables/_saltcorn_data.db.html +1 -1
  375. package/docs/variables/_saltcorn_data.migrations.html +1 -1
  376. package/docs/variables/_saltcorn_data.models.config.available_languages.html +1 -1
  377. package/docs/variables/_saltcorn_data.models.config.configTypes.html +1 -1
  378. package/docs/variables/_saltcorn_data.models.scheduler.runScheduler.html +1 -1
  379. package/docs/variables/_saltcorn_data.plugin_helper.run_action_column.html +1 -1
  380. package/docs/variables/_saltcorn_data.utils.NotAuthorized.html +1 -1
  381. package/docs/variables/_saltcorn_data.utils.sleep.html +1 -1
  382. package/docs/variables/_saltcorn_db_common.multi_tenant.tenantNamespace.html +1 -1
  383. package/load_plugins.js +1 -1
  384. package/locales/da.json +874 -860
  385. package/locales/de.json +20 -2
  386. package/locales/en.json +12 -1
  387. package/locales/es.json +20 -2
  388. package/locales/fr.json +21 -3
  389. package/locales/pl.json +19 -9
  390. package/locales/pt.json +20 -2
  391. package/markup/admin.js +28 -0
  392. package/markup/expression_blurb.js +4 -2
  393. package/package.json +10 -9
  394. package/public/saltcorn-common.js +54 -18
  395. package/public/saltcorn.css +11 -1
  396. package/public/saltcorn.js +10 -3
  397. package/public/tabulator.min.js +2 -2
  398. package/public/tabulator_bootstrap4.min.css +1 -1
  399. package/public/tabulator_bootstrap5.min.css +2 -1
  400. package/routes/actions.js +28 -5
  401. package/routes/admin.js +106 -14
  402. package/routes/api.js +27 -15
  403. package/routes/common_lists.js +18 -7
  404. package/routes/fields.js +1 -6
  405. package/routes/infoarch.js +216 -21
  406. package/routes/list.js +47 -11
  407. package/routes/menu.js +1 -1
  408. package/routes/plugins.js +1 -1
  409. package/routes/registry.js +17 -0
  410. package/routes/tables.js +15 -2
  411. package/routes/tag_entries.js +6 -1
  412. package/routes/view.js +10 -3
  413. package/serve.js +5 -1
  414. package/tests/menu.test.js +122 -0
  415. package/wrapper.js +8 -5
package/routes/api.js CHANGED
@@ -407,23 +407,35 @@ router.get(
407
407
  target: field?.attributes?.summary_field,
408
408
  };
409
409
  });
410
- rows = await table.getJoinedRows({
411
- where: qstate,
412
- joinFields,
413
- limit: use_limit,
414
- offset: use_offset,
415
- orderDesc:
416
- (sortDesc && sortDesc !== "false") || tabulator_dir == "desc",
417
- orderBy: orderByField?.name || undefined,
418
- forPublic: !(req.user || user),
419
- forUser: req.user || user,
420
- });
410
+ try {
411
+ rows = await table.getJoinedRows({
412
+ where: qstate,
413
+ joinFields,
414
+ limit: use_limit,
415
+ offset: use_offset,
416
+ orderDesc:
417
+ (sortDesc && sortDesc !== "false") || tabulator_dir == "desc",
418
+ orderBy: orderByField?.name || undefined,
419
+ forPublic: !(req.user || user),
420
+ forUser: req.user || user,
421
+ });
422
+ } catch (e) {
423
+ console.error(e);
424
+ res.json({ error: "API error" });
425
+ return;
426
+ }
421
427
  }
422
428
  if (tabulator_pagination_format) {
423
- res.json({
424
- last_page: Math.ceil((await table.countRows()) / +tabulator_size),
425
- data: rows.map(limitFields(fields)),
426
- });
429
+ const count = await table.countRows();
430
+ if (count === null)
431
+ res.json({
432
+ data: rows.map(limitFields(fields)),
433
+ });
434
+ else
435
+ res.json({
436
+ last_page: Math.ceil(count / +tabulator_size),
437
+ data: rows.map(limitFields(fields)),
438
+ });
427
439
  } else res.json({ success: rows.map(limitFields(fields)) });
428
440
  } else {
429
441
  getState().log(3, `API get ${table.name} not authorized`);
@@ -205,7 +205,7 @@ const view_dropdown = (view, req, on_done_redirect_str = "") =>
205
205
  a(
206
206
  {
207
207
  class: "dropdown-item",
208
- href: `javascript:ajax_modal('/admin/snapshot-restore/view/${view.name}')`,
208
+ href: `javascript:ajax_modal('/admin/snapshot-restore/view/${view.name}${on_done_redirect_str}')`,
209
209
  },
210
210
  '<i class="fas fa-undo-alt"></i>&nbsp;' + req.__("Restore")
211
211
  ),
@@ -284,7 +284,7 @@ const tagsDropdown = (tags, altHeader, req) =>
284
284
  {
285
285
  class: "dropdown-item",
286
286
  // TODO check url why view for page, what do we need for page group
287
- href: `tag`,
287
+ href: `/tag`,
288
288
  },
289
289
  req.__("Manage tags...")
290
290
  )
@@ -391,7 +391,7 @@ const viewsList = async (
391
391
  filterOnTag ? `Tag:${filterOnTag.name}` : undefined,
392
392
  req
393
393
  ),
394
- key: (r) => tagBadges(r),
394
+ key: (r) => (r.id ? tagBadges(r) : ""),
395
395
  },
396
396
  ]),
397
397
  {
@@ -674,12 +674,12 @@ const trigger_dropdown = (trigger, req, on_done_redirect_str = "") =>
674
674
  a(
675
675
  {
676
676
  class: "dropdown-item",
677
- href: `javascript:ajax_modal('/admin/snapshot-restore/trigger/${trigger.name}')`,
677
+ href: `javascript:ajax_modal('/admin/snapshot-restore/trigger/${trigger.name}${on_done_redirect_str}')`,
678
678
  },
679
679
  '<i class="fas fa-undo-alt"></i>&nbsp;' + req.__("Restore")
680
680
  ),
681
681
  post_dropdown_item(
682
- `/actions/clone/${trigger.id}`,
682
+ `/actions/clone/${trigger.id}${on_done_redirect_str}`,
683
683
  '<i class="far fa-copy"></i>&nbsp;' + req.__("Duplicate"),
684
684
  req
685
685
  ),
@@ -734,11 +734,22 @@ const getTriggerList = async (
734
734
  { label: req.__("Name"), key: "name" },
735
735
  {
736
736
  label: req.__("Test run"),
737
- key: (r) => link(`/actions/testrun/${r.id}`, req.__("Test run")),
737
+ key: (r) =>
738
+ link(
739
+ `/actions/testrun/${r.id}${on_done_redirect_str}`,
740
+ req.__("Test run"),
741
+ {
742
+ onclick: `press_store_button(this)`,
743
+ }
744
+ ),
738
745
  },
739
746
  {
740
747
  label: req.__("Configure"),
741
- key: (r) => link(`/actions/configure/${r.id}`, req.__("Configure")),
748
+ key: (r) =>
749
+ link(
750
+ `/actions/configure/${r.id}${on_done_redirect_str}`,
751
+ req.__("Configure")
752
+ ),
742
753
  },
743
754
  ...(tagId
744
755
  ? []
package/routes/fields.js CHANGED
@@ -307,12 +307,7 @@ const fieldFlow = (req) =>
307
307
  try {
308
308
  await db.withTransaction(async () => {
309
309
  if (context.id) {
310
- const field = await Field.findOne({ id: context.id });
311
-
312
- if (fldRow.label && field.label != fldRow.label) {
313
- fldRow.name = Field.labelToName(fldRow.label);
314
- }
315
-
310
+ const field = await Field.findOne({ id: context.id });
316
311
  await field.update(fldRow);
317
312
  Trigger.emitEvent(
318
313
  "AppChange",
@@ -16,12 +16,22 @@ const {
16
16
  send_admin_page,
17
17
  config_fields_form,
18
18
  save_config_from_form,
19
+ upload_language_pack,
19
20
  } = require("../markup/admin.js");
20
21
  const { getState } = require("@saltcorn/data/db/state");
21
- const { div, a, i, text, button } = require("@saltcorn/markup/tags");
22
- const { mkTable, renderForm, post_delete_btn } = require("@saltcorn/markup");
22
+ const { span, div, a, i, text, button } = require("@saltcorn/markup/tags");
23
+ const {
24
+ mkTable,
25
+ renderForm,
26
+ post_delete_btn,
27
+ post_btn,
28
+ } = require("@saltcorn/markup");
23
29
  const Form = require("@saltcorn/data/models/form");
24
30
  const Snapshot = require("@saltcorn/admin-models/models/snapshot");
31
+ const { stringify } = require("csv-stringify");
32
+ const csvtojson = require("csvtojson");
33
+ const { hasLLM, translate } = require("@saltcorn/data/translate");
34
+ const { escapeHtml } = require("@saltcorn/data/utils");
25
35
 
26
36
  /**
27
37
  * @type {object}
@@ -175,6 +185,17 @@ router.get(
175
185
  })
176
186
  : "",
177
187
  },
188
+ {
189
+ label: req.__("Language CSV"),
190
+ key: (r) =>
191
+ a(
192
+ {
193
+ href: `/site-structure/localizer/download-pack/${r.locale}`,
194
+ },
195
+ i({ class: "fas fa-download me-2" }),
196
+ req.__("Download")
197
+ ),
198
+ },
178
199
  {
179
200
  label: req.__("Delete"),
180
201
  key: (r) =>
@@ -187,13 +208,17 @@ router.get(
187
208
  ],
188
209
  Object.values(cfgLangs)
189
210
  ),
190
- a(
191
- {
192
- href: "/site-structure/localizer/add-lang",
193
- class: "btn btn-primary mt-1",
194
- },
195
- i({ class: "fas fa-plus-square me-1" }),
196
- req.__("Add language")
211
+ div(
212
+ { class: "d-flex mt-1" },
213
+ a(
214
+ {
215
+ href: "/site-structure/localizer/add-lang",
216
+ class: "btn btn-primary me-2",
217
+ },
218
+ i({ class: "fas fa-plus-square me-1" }),
219
+ req.__("Add language")
220
+ ),
221
+ upload_language_pack(req)
197
222
  )
198
223
  ),
199
224
  },
@@ -201,6 +226,75 @@ router.get(
201
226
  })
202
227
  );
203
228
 
229
+ router.get(
230
+ "/localizer/download-pack/:lang",
231
+ isAdmin,
232
+ error_catcher(async (req, res) => {
233
+ const { lang } = req.params;
234
+ if (lang === "__proto__" || lang === "constructor") {
235
+ res.redirect(`/`);
236
+ return;
237
+ }
238
+ const cfgLangs = getState().getConfig("localizer_languages");
239
+
240
+ if (!cfgLangs[lang]) {
241
+ req.flash("error", req.__("Language not found"));
242
+ return res.redirect(`/site-structure/localizer`);
243
+ }
244
+ const default_lang =
245
+ Object.values(cfgLangs).find((lobj) => lobj.is_default)?.locale ||
246
+ getState().getConfig("default_locale", "en");
247
+
248
+ const cfgStrings = getState().getConfig("localizer_strings", {});
249
+ const translation = cfgStrings[lang] || {};
250
+ const strings = getState()
251
+ .getStringsForI18n()
252
+ .map((s) => ({ [default_lang]: s, [lang]: translation[s] || s }));
253
+ res.type("text/csv");
254
+ res.setHeader("Content-Disposition", `attachment; filename="${lang}.csv"`);
255
+ res.setHeader("Cache-Control", "no-cache");
256
+ res.setHeader("Pragma", "no-cache");
257
+ stringify(strings, {
258
+ header: true,
259
+ columns: [default_lang, lang],
260
+ quoted: true,
261
+ }).pipe(res);
262
+ })
263
+ );
264
+
265
+ router.post(
266
+ "/localizer/upload-language-pack",
267
+ isAdmin,
268
+ setTenant, // TODO why is this needed?????
269
+ error_catcher(async (req, res) => {
270
+ if (req.files?.file?.tempFilePath) {
271
+ const cfgLangs = getState().getConfig("localizer_languages");
272
+ const default_lang =
273
+ Object.values(cfgLangs).find((lobj) => lobj.is_default)?.locale ||
274
+ getState().getConfig("default_locale", "en");
275
+ const cfgStrings = getState().getConfigCopy("localizer_strings");
276
+
277
+ try {
278
+ const rows = await csvtojson().fromFile(req.files?.file?.tempFilePath);
279
+ const langs = Object.keys(rows[0]).filter((k) => k !== default_lang);
280
+ for (const lang of langs)
281
+ for (const row of rows) {
282
+ const defstring = row[default_lang];
283
+ if (cfgStrings[lang]) cfgStrings[lang][defstring] = row[lang];
284
+ else cfgStrings[lang] = { [defstring]: row[lang] };
285
+ }
286
+ await getState().setConfig("localizer_strings", cfgStrings);
287
+
288
+ req.flash("success", `Updated languages: ${langs.join(", ")}`);
289
+ } catch (e) {
290
+ console.error(e);
291
+ req.flash("error", e.message);
292
+ }
293
+ }
294
+ res.redirect(`/site-structure/localizer`);
295
+ })
296
+ );
297
+
204
298
  /**
205
299
  * @name get/localizer/add-lang
206
300
  * @function
@@ -253,7 +347,21 @@ router.get(
253
347
  above: [
254
348
  {
255
349
  type: "card",
256
- contents: [renderForm(form, req.csrfToken())],
350
+ contents: [
351
+ renderForm(form, req.csrfToken()),
352
+ hasLLM() &&
353
+ renderForm(
354
+ new Form({
355
+ fields: [],
356
+ action: `/site-structure/localizer/translate-llm/${lang}`,
357
+ submitLabel: req.__("Translate with LLM"),
358
+ onSubmit: "press_store_button(this)",
359
+
360
+ submitButtonClass: "btn-secondary",
361
+ }),
362
+ req.csrfToken()
363
+ ),
364
+ ],
257
365
  },
258
366
  !is_default && {
259
367
  type: "card",
@@ -263,18 +371,35 @@ router.get(
263
371
  [
264
372
  {
265
373
  label: req.__("In default language"),
266
- key: "in_default",
374
+ key: (r) => escapeHtml(r.in_default),
267
375
  },
268
376
  {
269
377
  label: req.__("In %s", form.values.name),
270
378
  key: (r) =>
271
- div(
272
- {
273
- "data-inline-edit-dest-url": `/site-structure/localizer/save-string/${lang}/${encodeURIComponent(
274
- r.in_default
275
- )}`,
276
- },
277
- r.translated
379
+ span(
380
+ div(
381
+ {
382
+ "data-inline-edit-dest-url": `/site-structure/localizer/save-string/${lang}/${encodeURIComponent(
383
+ r.in_default
384
+ )}`,
385
+ "data-inline-edit-unescape": "true",
386
+ class: "d-inline",
387
+ },
388
+ escapeHtml(r.translated)
389
+ ),
390
+ r.in_default !== r.translated &&
391
+ post_btn(
392
+ `/site-structure/localizer/delete-string/${lang}/${encodeURIComponent(
393
+ r.in_default
394
+ )}`,
395
+ "",
396
+ req.csrfToken(),
397
+ {
398
+ icon: "fas fa-trash-alt",
399
+ btnClass: "btn-sm btn-xs btn-link link-danger",
400
+ formClass: "d-inline",
401
+ }
402
+ )
278
403
  ),
279
404
  },
280
405
  ],
@@ -288,6 +413,57 @@ router.get(
288
413
  })
289
414
  );
290
415
 
416
+ router.post(
417
+ "/localizer/translate-llm/:lang/",
418
+ isAdmin,
419
+ error_catcher(async (req, res) => {
420
+ const { lang, defstring } = req.params;
421
+ if (
422
+ lang === "__proto__" ||
423
+ defstring === "__proto__" ||
424
+ lang === "constructor"
425
+ ) {
426
+ res.redirect(`/`);
427
+ return;
428
+ }
429
+ const cfgLangs = getState().getConfig("localizer_languages");
430
+
431
+ if (!cfgLangs[lang]) {
432
+ req.flash("error", req.__("Language not found"));
433
+ return res.redirect(`/site-structure/localizer`);
434
+ }
435
+ const default_lang =
436
+ Object.values(cfgLangs).find((lobj) => lobj.is_default)?.locale ||
437
+ getState().getConfig("default_locale", "en");
438
+ let count = 0;
439
+ for (const defstring of getState().getStringsForI18n()) {
440
+ const cfgStrings = getState().getConfigCopy("localizer_strings", {});
441
+ if (
442
+ cfgStrings[lang][defstring] &&
443
+ cfgStrings[lang][defstring] !== defstring
444
+ )
445
+ continue;
446
+ if (count >= 20) break;
447
+ count += 1;
448
+ const translated = await translate(defstring, lang, default_lang);
449
+ if (cfgStrings[lang]) cfgStrings[lang][defstring] = translated;
450
+ else cfgStrings[lang] = { [defstring]: translated };
451
+ await getState().setConfig("localizer_strings", cfgStrings);
452
+ }
453
+ if (count == 20)
454
+ req.flash(
455
+ "success",
456
+ req.__(
457
+ `Translated %s strings. Click 'Translate with LLM' again to continue`,
458
+ count
459
+ )
460
+ );
461
+ else
462
+ req.flash("success", req.__(`Finished translating %s strings.`, count));
463
+ res.redirect(`/site-structure/localizer/edit/${lang}`);
464
+ })
465
+ );
466
+
291
467
  /**
292
468
  * @name post/localizer/save-string/:lang/:defstring
293
469
  * @function
@@ -308,9 +484,28 @@ router.post(
308
484
  return;
309
485
  }
310
486
  const cfgStrings = getState().getConfigCopy("localizer_strings");
311
- if (cfgStrings[lang])
312
- cfgStrings[lang][defstring] = text((req.body || {}).value);
313
- else cfgStrings[lang] = { [defstring]: text((req.body || {}).value) };
487
+ if (cfgStrings[lang]) cfgStrings[lang][defstring] = (req.body || {}).value;
488
+ else cfgStrings[lang] = { [defstring]: (req.body || {}).value };
489
+ await getState().setConfig("localizer_strings", cfgStrings);
490
+ res.redirect(`/site-structure/localizer/edit/${lang}`);
491
+ })
492
+ );
493
+
494
+ router.post(
495
+ "/localizer/delete-string/:lang/:defstring",
496
+ isAdmin,
497
+ error_catcher(async (req, res) => {
498
+ const { lang, defstring } = req.params;
499
+ if (
500
+ lang === "__proto__" ||
501
+ defstring === "__proto__" ||
502
+ lang === "constructor"
503
+ ) {
504
+ res.redirect(`/`);
505
+ return;
506
+ }
507
+ const cfgStrings = getState().getConfigCopy("localizer_strings");
508
+ if (cfgStrings[lang]) delete cfgStrings[lang][defstring];
314
509
  await getState().setConfig("localizer_strings", cfgStrings);
315
510
  res.redirect(`/site-structure/localizer/edit/${lang}`);
316
511
  })
package/routes/list.js CHANGED
@@ -19,6 +19,7 @@ const {
19
19
  i,
20
20
  text,
21
21
  button,
22
+ a,
22
23
  input,
23
24
  label,
24
25
  form,
@@ -31,6 +32,7 @@ const {
31
32
  } = require("./utils");
32
33
  const moment = require("moment");
33
34
  const { getState } = require("@saltcorn/data/db/state");
35
+ const { comparingCaseInsensitive } = require("@saltcorn/data/utils");
34
36
 
35
37
  /**
36
38
  * @type {object}
@@ -127,19 +129,26 @@ router.post(
127
129
  const typeToGridType = (t, field) => {
128
130
  const jsgField = { field: field.name, title: field.label, editor: true };
129
131
  if (t.name === "String" && field.attributes && field.attributes.options) {
130
- jsgField.editor = "select";
132
+ jsgField.editor = "list";
131
133
 
132
134
  const values = field.attributes.options.split(",").map((o) => o.trim());
133
135
  if (!field.required) values.unshift("");
134
136
 
135
137
  jsgField.editorParams = { values };
136
138
  } else if (t === "Key" || t === "File") {
137
- jsgField.editor = "select";
138
- const values = {};
139
-
140
- field.options.forEach(({ label, value }) => (values[value] = label));
139
+ jsgField.editor = "list";
140
+ const values = [];
141
+ const valuesObj = {};
142
+ field.options
143
+ .sort(comparingCaseInsensitive("label"))
144
+ .forEach(({ label, value }) => {
145
+ //en space. tabulator workaround
146
+ const l = label === "" ? "\u2002" : label;
147
+ values.push({ label: l, value });
148
+ valuesObj[value] = l;
149
+ });
141
150
  jsgField.editorParams = { values };
142
- jsgField.formatterParams = { values };
151
+ jsgField.formatterParams = { values: valuesObj };
143
152
  jsgField.formatter = "__lookupIntToString";
144
153
  } else if (t.name === "Float" || t.name === "Integer") {
145
154
  jsgField.editor = "number";
@@ -373,6 +382,21 @@ router.get(
373
382
  },
374
383
  form(
375
384
  { class: "px-2" },
385
+ a(
386
+ {
387
+ onclick: `event.stopPropagation();allnonecols(true,this)`,
388
+ href: "javascript:;",
389
+ },
390
+ "All"
391
+ ),
392
+ " | ",
393
+ a(
394
+ {
395
+ onclick: `event.stopPropagation();allnonecols(false,this)`,
396
+ href: "javascript:;",
397
+ },
398
+ "None"
399
+ ),
376
400
  fields.map((f) =>
377
401
  div(
378
402
  { class: "form-check" },
@@ -403,7 +427,7 @@ router.get(
403
427
  if(typeof v === "string" && v.startsWith("__"))
404
428
  col[k] = window[v.substring(2)];
405
429
  })
406
- })
430
+ })
407
431
  window.tabulator_table_primary_key = "${table.pk_name}";
408
432
  window.tabulator_table = new Tabulator("#jsGrid", {
409
433
  ajaxURL:"/api/${encodeURIComponent(
@@ -411,22 +435,34 @@ router.get(
411
435
  )}?tabulator_pagination_format=true${
412
436
  table.versioned ? "&versioncount=on" : ""
413
437
  }",
414
- layout:"fitColumns",
438
+ layout:"fitData",
415
439
  columns,
416
440
  height:"100%",
417
441
  pagination:true,
418
442
  paginationMode:"remote",
419
443
  paginationSize:20,
420
- clipboard:true,
421
- persistence:true,
422
- persistenceID:"table_tab_${table.name}",
444
+ clipboard:true,
423
445
  movableColumns: true,
424
446
  ajaxContentType:"json",
425
447
  sortMode:"remote",
448
+ resizableColumnGuide:true,
449
+ columnDefaults:{
450
+ resizable:true,
451
+ maxWidth:500
452
+ },
426
453
  initialSort:[
427
454
  {column:"${table.pk_name}", dir:"asc"},
428
455
  ],
429
456
  });
457
+ window.allnonecols= (do_show, e) =>{
458
+ columns.forEach(col=>{
459
+ if(col.frozen && !do_show) return;
460
+ if (do_show) window.tabulator_table.showColumn(col.field);
461
+ else window.tabulator_table.hideColumn(col.field);
462
+ $(e).closest("form").find("input").prop("checked", do_show)
463
+ })
464
+ }
465
+
430
466
  window.tabulator_table.on("cellEdited", function(cell){
431
467
  const row = cell.getRow().getData()
432
468
  const fieldName = cell.getColumn().getField()
package/routes/menu.js CHANGED
@@ -413,7 +413,7 @@ const menuForm = async (req) => {
413
413
  //default: "Standard",
414
414
  attributes: {
415
415
  inline: true,
416
- options: "Standard, Mobile Bottom, Secondary Menu",
416
+ options: ["Standard", "Mobile Bottom", "Secondary Menu"],
417
417
  },
418
418
  },
419
419
  ],
package/routes/plugins.js CHANGED
@@ -102,7 +102,7 @@ const pluginForm = (req, plugin) => {
102
102
  name: "source",
103
103
  type: getState().types.String,
104
104
  required: true,
105
- attributes: { options: "npm,local,github,git" },
105
+ attributes: { options: ["npm", "local", "github", "git"] },
106
106
  sublabel: req.__(
107
107
  "Source of module for install. Few options:" +
108
108
  "npm - download from npm repository," +
@@ -374,6 +374,23 @@ router.post(
374
374
  await db.withTransaction(async () => {
375
375
  await install_pack(pack);
376
376
  });
377
+ switch (etype) {
378
+ case "table":
379
+ await getState().refresh_tables();
380
+ break;
381
+ case "view":
382
+ await getState().refresh_views();
383
+ break;
384
+ case "page":
385
+ await getState().refresh_pages();
386
+ break;
387
+ case "trigger":
388
+ await getState().refresh_triggers();
389
+ break;
390
+ case "config":
391
+ await getState().refresh_config();
392
+ break;
393
+ }
377
394
  res.redirect(
378
395
  `/registry-editor?etype=${etype}&ename=${encodeURIComponent(
379
396
  ename
package/routes/tables.js CHANGED
@@ -1018,7 +1018,8 @@ router.get(
1018
1018
  // Table Data card
1019
1019
  const dataCard = div(
1020
1020
  { class: "d-flex text-center" },
1021
- div({ class: "mx-auto" }, h4(`${nrows}`), req.__("Rows")),
1021
+ nrows !== null &&
1022
+ div({ class: "mx-auto" }, h4(`${nrows}`), req.__("Rows")),
1022
1023
  div(
1023
1024
  { class: "mx-auto" },
1024
1025
  a(
@@ -1246,6 +1247,7 @@ router.post(
1246
1247
  res.redirect(`/table/new`);
1247
1248
  } else if (rest.provider_name && rest.provider_name !== "-") {
1248
1249
  const table = await Table.create(name, rest);
1250
+ await getState().refresh_tables();
1249
1251
  res.redirect(`/table/provider-cfg/${table.id}`);
1250
1252
  } else {
1251
1253
  delete rest.provider_name;
@@ -1902,7 +1904,9 @@ router.post(
1902
1904
  const renameForm = (table_id, req) =>
1903
1905
  new Form({
1904
1906
  action: `/table/rename/${table_id}`,
1905
- labelCols: 3,
1907
+ blurb: req.__(
1908
+ "You may need to adjust view relations associated with this table after renaming it"
1909
+ ),
1906
1910
  fields: [
1907
1911
  {
1908
1912
  name: "name",
@@ -1910,6 +1914,14 @@ const renameForm = (table_id, req) =>
1910
1914
  type: "String",
1911
1915
  },
1912
1916
  ],
1917
+ additionalButtons: [
1918
+ {
1919
+ label: req.__("Cancel"),
1920
+ class: "btn btn-danger",
1921
+ onclick: "history.back()",
1922
+ },
1923
+ ],
1924
+ values: { name: Table.findOne({ id: table_id })?.name },
1913
1925
  });
1914
1926
 
1915
1927
  /**
@@ -2352,6 +2364,7 @@ const get_provider_workflow = (table, req) => {
2352
2364
  workflow.onDone = async (ctx) => {
2353
2365
  const { table_id, ...configuration } = await oldOnDone(ctx);
2354
2366
  await table.update({ provider_cfg: configuration });
2367
+ await getState().refresh_tables();
2355
2368
 
2356
2369
  return {
2357
2370
  redirect: `/table/${table.id}`,
@@ -7,6 +7,7 @@ const {
7
7
  label,
8
8
  text,
9
9
  } = require("@saltcorn/markup/tags");
10
+ const db = require("@saltcorn/data/db");
10
11
 
11
12
  const Tag = require("@saltcorn/data/models/tag");
12
13
  const TagEntry = require("@saltcorn/data/models/tag_entry");
@@ -192,7 +193,11 @@ router.post(
192
193
  const fieldName = idField(entitytype);
193
194
  const auth = checkEditPermission(entitytype, req.user);
194
195
  if (!auth) req.flash("error", "Not authorized");
195
- else await tag.addEntry({ [fieldName]: +entityid });
196
+ else
197
+ await db.withTransaction(async () => {
198
+ await tag.addEntry({ [fieldName]: +entityid });
199
+ });
200
+
196
201
  let redirectTarget =
197
202
  req.query.on_done_redirect &&
198
203
  is_relative_url("/" + req.query.on_done_redirect)