@kaspernj/api-maker 1.0.2011 → 1.0.2012

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 (410) hide show
  1. package/{.eslintrc.cjs → .eslintrc.js} +10 -1
  2. package/README.md +35 -0
  3. package/android/build.gradle +43 -0
  4. package/android/src/main/AndroidManifest.xml +2 -0
  5. package/android/src/main/java/expo/modules/api_maker/ApiMakerModule.kt +50 -0
  6. package/android/src/main/java/expo/modules/api_maker/ApiMakerView.kt +30 -0
  7. package/build/api.js +120 -0
  8. package/build/attribute-not-loaded-error.js +2 -0
  9. package/build/base-component.js +5 -0
  10. package/build/base-error.js +33 -0
  11. package/build/base-model/attribute.js +25 -0
  12. package/build/base-model/column.js +11 -0
  13. package/build/base-model/reflection.js +14 -0
  14. package/build/base-model/scope.js +11 -0
  15. package/build/base-model.js +828 -0
  16. package/build/bootstrap/attribute-row.js +135 -0
  17. package/build/bootstrap/attribute-rows.js +31 -0
  18. package/build/bootstrap/card.js +138 -0
  19. package/build/bootstrap/checkbox.js +97 -0
  20. package/build/bootstrap/checkboxes.js +183 -0
  21. package/build/bootstrap/index.js +2 -0
  22. package/build/bootstrap/input.js +129 -0
  23. package/build/bootstrap/invalid-feedback.js +27 -0
  24. package/build/bootstrap/paginate.js +150 -0
  25. package/build/bootstrap/radio-buttons.js +72 -0
  26. package/build/bootstrap/select.js +88 -0
  27. package/build/bootstrap/sort-link.js +131 -0
  28. package/build/cable-connection-pool.js +128 -0
  29. package/build/cable-subscription-pool.js +207 -0
  30. package/build/cable-subscription.js +21 -0
  31. package/build/cache-key-generator.js +81 -0
  32. package/build/can-can.js +134 -0
  33. package/build/channels-consumer.js +9 -0
  34. package/build/collection-loader.js +48 -0
  35. package/build/collection.js +280 -0
  36. package/build/command-submit-data.js +81 -0
  37. package/build/commands-pool.js +195 -0
  38. package/build/compose.js +9 -0
  39. package/build/config.js +62 -0
  40. package/build/custom-error.js +5 -0
  41. package/build/data-set-to-attributes.js +10 -0
  42. package/build/deserializer.js +56 -0
  43. package/build/destroy-error.js +5 -0
  44. package/build/devise.js +112 -0
  45. package/build/draggable-sort/controller.js +136 -0
  46. package/build/draggable-sort/index.js +114 -0
  47. package/build/draggable-sort/item.js +188 -0
  48. package/build/error-logger.js +101 -0
  49. package/build/error-messages.js +13 -0
  50. package/build/event-connection.js +32 -0
  51. package/build/event-emitter-listener.js +15 -0
  52. package/build/event-model-class.js +24 -0
  53. package/build/events.js +5 -0
  54. package/build/flash-message.js +79 -0
  55. package/build/form.js +83 -0
  56. package/build/history-expo.js +20 -0
  57. package/build/history-react-native.js +20 -0
  58. package/build/history.js +3 -0
  59. package/build/index.js +3 -0
  60. package/build/inputs/attachment.js +133 -0
  61. package/build/inputs/auto-submit.js +36 -0
  62. package/build/inputs/checkbox.js +138 -0
  63. package/build/inputs/checkboxes.js +112 -0
  64. package/build/inputs/id-for-component.js +15 -0
  65. package/build/inputs/input-wrapper.js +19 -0
  66. package/build/inputs/input.js +243 -0
  67. package/build/inputs/money.js +179 -0
  68. package/build/inputs/name-for-component.js +13 -0
  69. package/build/inputs/select.js +93 -0
  70. package/build/instance-of-class-name.js +23 -0
  71. package/build/key-value-store.js +53 -0
  72. package/build/link.js +73 -0
  73. package/build/logger.js +30 -0
  74. package/build/modal.js +38 -0
  75. package/build/model-class-require.js +13 -0
  76. package/build/model-events.js +30 -0
  77. package/build/model-name.js +28 -0
  78. package/build/model-prop-type.js +101 -0
  79. package/build/model-recipes-loader.js +32 -0
  80. package/build/model-recipes-model-loader.js +357 -0
  81. package/build/models-response-reader.js +40 -0
  82. package/build/models.js +8 -0
  83. package/build/money-formatter.js +78 -0
  84. package/build/not-loaded-error.js +2 -0
  85. package/build/params.js +61 -0
  86. package/build/preloaded.js +38 -0
  87. package/build/resize-observer.js +11 -0
  88. package/build/result.js +13 -0
  89. package/build/router/route.js +270 -0
  90. package/build/router/switch.js +72 -0
  91. package/build/router.js +59 -0
  92. package/build/routes-native.js +202 -0
  93. package/build/routes.js +50 -0
  94. package/build/run-last.js +35 -0
  95. package/build/serializer.js +63 -0
  96. package/build/services.js +20 -0
  97. package/build/session-status-updater.js +134 -0
  98. package/build/source-maps-loader.js +184 -0
  99. package/build/super-admin/config-reader.js +85 -0
  100. package/build/super-admin/edit-page/edit-attribute-checkbox.js +85 -0
  101. package/build/super-admin/edit-page/edit-attribute-content.js +55 -0
  102. package/build/super-admin/edit-page/edit-attribute-input.js +79 -0
  103. package/build/super-admin/edit-page/edit-attribute.js +77 -0
  104. package/build/super-admin/edit-page.js +123 -0
  105. package/build/super-admin/has-edit-config.js +12 -0
  106. package/build/super-admin/index-page.js +25 -0
  107. package/build/super-admin/index.js +181 -0
  108. package/build/super-admin/layout/header/index.js +161 -0
  109. package/build/super-admin/layout/index.js +164 -0
  110. package/build/super-admin/layout/menu/index.js +206 -0
  111. package/build/super-admin/layout/menu/menu-content.js +46 -0
  112. package/build/super-admin/layout/menu/menu-item.js +84 -0
  113. package/build/super-admin/layout/no-access.js +27 -0
  114. package/build/super-admin/model-class-table.js +61 -0
  115. package/build/super-admin/models.js +8 -0
  116. package/build/super-admin/show-nav.js +51 -0
  117. package/build/super-admin/show-page/belongs-to-attribute-row.js +29 -0
  118. package/build/super-admin/show-page/index.js +141 -0
  119. package/build/super-admin/show-reflection-actions.js +47 -0
  120. package/build/super-admin/show-reflection-link.js +48 -0
  121. package/build/super-admin/show-reflection-page.js +48 -0
  122. package/build/table/column-content.js +117 -0
  123. package/build/table/column-identifier.js +18 -0
  124. package/build/table/column-visible.js +7 -0
  125. package/build/table/components/column.js +21 -0
  126. package/build/table/components/flat-list.js +21 -0
  127. package/build/table/components/header.js +26 -0
  128. package/build/table/components/row.js +26 -0
  129. package/build/table/filters/attribute-element.js +44 -0
  130. package/build/table/filters/filter-form.js +402 -0
  131. package/build/table/filters/filter.js +90 -0
  132. package/build/table/filters/index.js +184 -0
  133. package/build/table/filters/load-search-modal.js +175 -0
  134. package/build/table/filters/reflection-element.js +37 -0
  135. package/build/table/filters/save-search-modal.js +88 -0
  136. package/build/table/filters/scope-element.js +42 -0
  137. package/build/table/header-column-content.js +68 -0
  138. package/build/table/header-column.js +144 -0
  139. package/build/table/header-select.js +105 -0
  140. package/build/table/model-callback-args.js +10 -0
  141. package/build/table/model-column.js +97 -0
  142. package/build/table/model-row.js +193 -0
  143. package/build/table/select-calculator.js +63 -0
  144. package/build/table/settings/column-row.js +97 -0
  145. package/build/table/settings/download-action.js +79 -0
  146. package/build/table/settings/index.js +92 -0
  147. package/build/table/table-settings.js +219 -0
  148. package/build/table/table.js +972 -0
  149. package/build/table/use-sorting.js +34 -0
  150. package/build/table/widths.js +75 -0
  151. package/build/table/worker-plugins-check-all-checkbox.js +125 -0
  152. package/build/table/worker-plugins-checkbox.js +115 -0
  153. package/build/translated-attributes.js +10 -0
  154. package/build/translated-collections.js +12 -0
  155. package/build/updated-attribute.js +76 -0
  156. package/build/url-encode.js +15 -0
  157. package/build/use-breakpoint.js +62 -0
  158. package/build/use-can-can.js +55 -0
  159. package/build/use-collection.js +225 -0
  160. package/build/use-created-event.js +52 -0
  161. package/build/use-current-user.js +76 -0
  162. package/build/use-destroyed-event.js +60 -0
  163. package/build/use-event-emitter.js +13 -0
  164. package/build/use-event-listener.js +16 -0
  165. package/build/use-input.js +137 -0
  166. package/build/use-model-event.js +60 -0
  167. package/build/use-model.js +169 -0
  168. package/build/use-resize-observer.js +23 -0
  169. package/build/use-router.js +104 -0
  170. package/build/use-screen-layout.js +39 -0
  171. package/build/use-updated-event.js +60 -0
  172. package/build/use-validation-errors.js +30 -0
  173. package/build/utils/card.js +51 -0
  174. package/build/utils/checkbox.js +78 -0
  175. package/build/utils/checkboxes.js +163 -0
  176. package/build/utils/default-style.js +18 -0
  177. package/build/utils/icon.js +23 -0
  178. package/build/utils/invalid-feedback.js +19 -0
  179. package/build/utils/modal.js +62 -0
  180. package/build/utils/text.js +19 -0
  181. package/build/validation-error.js +28 -0
  182. package/build/validation-errors.js +98 -0
  183. package/build/with-api-maker.js +29 -0
  184. package/build/with-collection.js +14 -0
  185. package/build/with-current-user.js +10 -0
  186. package/build/with-model.js +15 -0
  187. package/build/with-router.js +22 -0
  188. package/expo-module.config.json +17 -0
  189. package/ios/ApiMaker.podspec +29 -0
  190. package/ios/ApiMakerModule.swift +48 -0
  191. package/ios/ApiMakerView.swift +38 -0
  192. package/link.sh +8 -0
  193. package/package.json +49 -46
  194. package/src/{api.mjs → api.js} +38 -37
  195. package/src/base-component.jsx +5 -0
  196. package/src/{base-error.mjs → base-error.js} +4 -6
  197. package/src/base-model/attribute.js +33 -0
  198. package/src/base-model/column.js +13 -0
  199. package/src/base-model/reflection.js +15 -0
  200. package/src/base-model/scope.js +12 -0
  201. package/src/{base-model.mjs → base-model.js} +302 -144
  202. package/src/bootstrap/attribute-row.jsx +135 -0
  203. package/src/bootstrap/attribute-rows.jsx +27 -0
  204. package/src/bootstrap/card.jsx +149 -0
  205. package/src/bootstrap/checkbox.jsx +86 -0
  206. package/src/bootstrap/checkboxes.jsx +185 -0
  207. package/src/bootstrap/index.js +0 -0
  208. package/src/bootstrap/input.jsx +173 -0
  209. package/src/bootstrap/invalid-feedback.jsx +31 -0
  210. package/src/bootstrap/paginate.jsx +187 -0
  211. package/src/bootstrap/radio-buttons.jsx +87 -0
  212. package/src/bootstrap/select.jsx +110 -0
  213. package/src/bootstrap/sort-link.jsx +106 -0
  214. package/src/{cable-connection-pool.mjs → cable-connection-pool.js} +16 -36
  215. package/src/{cable-subscription-pool.mjs → cable-subscription-pool.js} +26 -21
  216. package/src/{cable-subscription.mjs → cable-subscription.js} +6 -4
  217. package/src/cache-key-generator.js +100 -0
  218. package/src/{can-can.mjs → can-can.js} +13 -12
  219. package/src/channels-consumer.js +10 -0
  220. package/src/collection-loader.jsx +58 -224
  221. package/src/{collection.mjs → collection.js} +98 -44
  222. package/src/{command-submit-data.mjs → command-submit-data.js} +2 -7
  223. package/src/{commands-pool.mjs → commands-pool.js} +57 -41
  224. package/src/compose.js +11 -0
  225. package/src/{config.mjs → config.js} +6 -2
  226. package/src/{custom-error.mjs → custom-error.js} +1 -1
  227. package/src/data-set-to-attributes.js +13 -0
  228. package/src/{deserializer.mjs → deserializer.js} +3 -3
  229. package/src/destroy-error.js +7 -0
  230. package/src/devise.js +129 -0
  231. package/src/draggable-sort/controller.js +137 -0
  232. package/src/draggable-sort/index.jsx +108 -0
  233. package/src/draggable-sort/item.jsx +174 -0
  234. package/src/{error-logger.mjs → error-logger.js} +12 -7
  235. package/src/{error-messages.mjs → error-messages.js} +1 -0
  236. package/src/event-connection.jsx +1 -1
  237. package/src/event-emitter-listener.jsx +8 -27
  238. package/src/event-model-class.jsx +2 -4
  239. package/src/events.js +7 -0
  240. package/src/flash-message.js +70 -0
  241. package/src/form.jsx +91 -0
  242. package/src/history-expo.js +23 -0
  243. package/src/history-react-native.js +25 -0
  244. package/src/history.js +3 -0
  245. package/src/index.js +3 -0
  246. package/src/inputs/attachment.jsx +108 -0
  247. package/src/inputs/auto-submit.js +37 -0
  248. package/src/inputs/checkbox.jsx +125 -0
  249. package/src/inputs/checkboxes.jsx +116 -0
  250. package/src/inputs/id-for-component.js +15 -0
  251. package/src/inputs/input-wrapper.jsx +16 -0
  252. package/src/inputs/input.jsx +260 -0
  253. package/src/inputs/money.jsx +187 -0
  254. package/src/inputs/name-for-component.js +15 -0
  255. package/src/inputs/select.jsx +104 -0
  256. package/src/{key-value-store.mjs → key-value-store.js} +1 -1
  257. package/src/link.jsx +54 -9
  258. package/src/logger.js +38 -0
  259. package/src/modal.jsx +37 -0
  260. package/src/model-class-require.js +17 -0
  261. package/src/{model-events.mjs → model-events.js} +1 -1
  262. package/src/{model-name.mjs → model-name.js} +8 -8
  263. package/src/{model-recipes-loader.mjs → model-recipes-loader.js} +1 -1
  264. package/src/{model-recipes-model-loader.mjs → model-recipes-model-loader.js} +5 -5
  265. package/src/{models-response-reader.mjs → models-response-reader.js} +3 -4
  266. package/src/models.js +7 -0
  267. package/src/{models.mjs.erb → models.js.erb} +6 -3
  268. package/src/{money-formatter.mjs → money-formatter.js} +5 -4
  269. package/src/{params.mjs → params.js} +17 -7
  270. package/src/{preloaded.mjs → preloaded.js} +2 -2
  271. package/src/resize-observer.jsx +10 -0
  272. package/src/result.js +13 -0
  273. package/src/router/route.jsx +246 -0
  274. package/src/router/switch.jsx +76 -0
  275. package/src/router.jsx +23 -21
  276. package/src/{routes-native.mjs → routes-native.js} +12 -6
  277. package/src/{routes.mjs → routes.js} +1 -1
  278. package/src/run-last.js +39 -0
  279. package/src/{serializer.mjs → serializer.js} +2 -2
  280. package/src/{services.mjs → services.js} +1 -1
  281. package/src/session-status-updater.js +172 -0
  282. package/src/{source-maps-loader.mjs → source-maps-loader.js} +54 -28
  283. package/src/super-admin/config-reader.jsx +93 -0
  284. package/src/super-admin/edit-page/edit-attribute-checkbox.jsx +81 -0
  285. package/src/super-admin/edit-page/edit-attribute-content.jsx +57 -0
  286. package/src/super-admin/edit-page/edit-attribute-input.jsx +71 -0
  287. package/src/super-admin/edit-page/edit-attribute.jsx +81 -0
  288. package/src/super-admin/edit-page.jsx +117 -0
  289. package/src/super-admin/has-edit-config.js +15 -0
  290. package/src/super-admin/index-page.jsx +23 -0
  291. package/src/super-admin/index.jsx +197 -0
  292. package/src/super-admin/layout/header/index.jsx +144 -0
  293. package/src/super-admin/layout/header/style.scss +45 -0
  294. package/src/super-admin/layout/index.jsx +154 -0
  295. package/src/super-admin/layout/menu/index.jsx +171 -0
  296. package/src/super-admin/layout/menu/menu-content.jsx +43 -0
  297. package/src/super-admin/layout/menu/menu-item.jsx +70 -0
  298. package/src/super-admin/layout/menu/style.scss +11 -0
  299. package/src/super-admin/layout/no-access.jsx +26 -0
  300. package/src/super-admin/model-class-table.jsx +66 -0
  301. package/src/super-admin/models.js +11 -0
  302. package/src/super-admin/show-nav.jsx +44 -0
  303. package/src/super-admin/show-page/belongs-to-attribute-row.jsx +30 -0
  304. package/src/super-admin/show-page/index.jsx +141 -0
  305. package/src/super-admin/show-reflection-actions.jsx +49 -0
  306. package/src/super-admin/show-reflection-link.jsx +40 -0
  307. package/src/super-admin/show-reflection-page.jsx +47 -0
  308. package/src/super-admin/stylesheets/variables.scss +11 -0
  309. package/src/table/column-content.jsx +122 -0
  310. package/src/table/column-identifier.js +23 -0
  311. package/src/table/column-visible.js +7 -0
  312. package/src/table/components/column.jsx +19 -0
  313. package/src/table/components/flat-list.jsx +19 -0
  314. package/src/table/components/header.jsx +21 -0
  315. package/src/table/components/row.jsx +23 -0
  316. package/src/table/filters/attribute-element.jsx +47 -0
  317. package/src/table/filters/filter-form.jsx +407 -0
  318. package/src/table/filters/filter.jsx +70 -0
  319. package/src/table/filters/index.jsx +170 -0
  320. package/src/table/filters/load-search-modal.jsx +146 -0
  321. package/src/table/filters/reflection-element.jsx +38 -0
  322. package/src/table/filters/save-search-modal.jsx +74 -0
  323. package/src/table/filters/scope-element.jsx +44 -0
  324. package/src/table/header-column-content.jsx +55 -0
  325. package/src/table/header-column.jsx +129 -0
  326. package/src/table/header-select.jsx +73 -0
  327. package/src/table/model-callback-args.js +10 -0
  328. package/src/table/model-column.jsx +82 -0
  329. package/src/table/model-row.jsx +136 -0
  330. package/src/table/select-calculator.js +65 -0
  331. package/src/table/settings/column-row.jsx +93 -0
  332. package/src/table/settings/download-action.jsx +68 -0
  333. package/src/table/settings/index.jsx +65 -0
  334. package/src/table/table-settings.js +263 -0
  335. package/src/table/table.jsx +950 -0
  336. package/src/table/use-sorting.js +35 -0
  337. package/src/table/variables.scss +11 -0
  338. package/src/table/widths.jsx +87 -0
  339. package/src/table/worker-plugins-check-all-checkbox.jsx +112 -0
  340. package/src/table/worker-plugins-checkbox.jsx +104 -0
  341. package/src/translated-attributes.js +11 -0
  342. package/src/{translated-collections.mjs → translated-collections.js} +3 -2
  343. package/src/updated-attribute.jsx +1 -1
  344. package/src/url-encode.js +18 -0
  345. package/src/use-breakpoint.js +76 -0
  346. package/src/use-can-can.js +55 -0
  347. package/src/use-collection.js +280 -0
  348. package/src/use-created-event.js +55 -0
  349. package/src/use-current-user.js +88 -0
  350. package/src/use-destroyed-event.js +60 -0
  351. package/src/use-event-emitter.js +15 -0
  352. package/src/use-event-listener.js +19 -0
  353. package/src/use-input.js +157 -0
  354. package/src/use-model-event.js +60 -0
  355. package/src/use-model.js +189 -0
  356. package/src/use-resize-observer.js +24 -0
  357. package/src/use-router.jsx +128 -0
  358. package/src/use-screen-layout.js +49 -0
  359. package/src/use-updated-event.js +60 -0
  360. package/src/use-validation-errors.js +33 -0
  361. package/src/utils/card.jsx +49 -0
  362. package/src/utils/checkbox.jsx +80 -0
  363. package/src/utils/checkboxes.jsx +158 -0
  364. package/src/utils/default-style.jsx +25 -0
  365. package/src/utils/icon.jsx +21 -0
  366. package/src/utils/invalid-feedback.jsx +20 -0
  367. package/src/utils/modal.jsx +60 -0
  368. package/src/utils/text.jsx +16 -0
  369. package/src/{validation-error.mjs → validation-error.js} +9 -5
  370. package/src/{validation-errors.mjs → validation-errors.js} +15 -27
  371. package/src/with-api-maker.jsx +31 -0
  372. package/src/with-collection.jsx +17 -0
  373. package/src/with-current-user.jsx +7 -25
  374. package/src/with-model.jsx +16 -0
  375. package/src/with-router.jsx +7 -129
  376. package/__tests__/base-model.test.js +0 -71
  377. package/__tests__/cable-connection-pool.test.js +0 -227
  378. package/__tests__/cable-subscription-pool.test.js +0 -26
  379. package/__tests__/can-can.test.js +0 -34
  380. package/__tests__/collection.test.js +0 -51
  381. package/__tests__/custom-error.test.js +0 -13
  382. package/__tests__/model-name.test.js +0 -34
  383. package/__tests__/model-prop-type.test.js +0 -113
  384. package/__tests__/params.test.js +0 -40
  385. package/__tests__/routes-native.test.js +0 -103
  386. package/__tests__/routes.test.js +0 -46
  387. package/__tests__/serializer.test.js +0 -30
  388. package/__tests__/support/task.js +0 -27
  389. package/__tests__/support/user.js +0 -32
  390. package/index.js +0 -1
  391. package/jest.config.js +0 -4
  392. package/src/can-can-loader.jsx +0 -54
  393. package/src/channels-consumer.mjs +0 -3
  394. package/src/destroy-error.mjs +0 -7
  395. package/src/devise.mjs +0 -122
  396. package/src/event-created.jsx +0 -65
  397. package/src/event-destroyed.jsx +0 -29
  398. package/src/event-listener.jsx +0 -38
  399. package/src/event-updated.jsx +0 -74
  400. package/src/logger.mjs +0 -25
  401. package/src/model-class-require.mjs +0 -10
  402. package/src/model-load-wrapper.jsx +0 -116
  403. package/src/result.mjs +0 -29
  404. package/src/session-status-updater.mjs +0 -116
  405. package/webpack.config.js +0 -15
  406. /package/src/{attribute-not-loaded-error.mjs → attribute-not-loaded-error.js} +0 -0
  407. /package/src/{instance-of-class-name.mjs → instance-of-class-name.js} +0 -0
  408. /package/src/{model-prop-type.mjs → model-prop-type.js} +0 -0
  409. /package/src/{not-loaded-error.mjs → not-loaded-error.js} +0 -0
  410. /package/src/{translated-collections-data.mjs.erb → translated-collections-data.js.erb} +0 -0
@@ -0,0 +1,70 @@
1
+ import CustomError from "@kaspernj/api-maker/build/custom-error"
2
+ import I18nOnSteroids from "i18n-on-steroids"
3
+ import ValidationError from "@kaspernj/api-maker/build/validation-error"
4
+ import {digg} from "diggerize"
5
+
6
+ export default class FlashMessage {
7
+ static alert(message) {
8
+ new FlashMessage({type: "alert", message})
9
+ }
10
+
11
+ static error(message) {
12
+ new FlashMessage({type: "error", message})
13
+ }
14
+
15
+ static errorResponse(error) {
16
+ if (error instanceof ValidationError) {
17
+ if (error.hasUnhandledErrors()) {
18
+ FlashMessage.error(error.message)
19
+ } else {
20
+ FlashMessage.error(I18nOnSteroids.getCurrent().t("js.flash_message.couldnt_submit_because_of_validation_errors"))
21
+ }
22
+ } else if (error instanceof CustomError) {
23
+ const errors = error.args.response.errors
24
+ const errorMessages = errors
25
+ .map((error) => {
26
+ if (typeof error == "string") {
27
+ return error
28
+ }
29
+
30
+ return digg(error, "message")
31
+ })
32
+ const errorMessage = errorMessages.join(". ")
33
+
34
+ FlashMessage.error(errorMessage)
35
+ } else {
36
+ console.error("Didnt know what to do with this", error)
37
+ }
38
+ }
39
+
40
+ static success(message) {
41
+ new FlashMessage({type: "success", message})
42
+ }
43
+
44
+ constructor({message, type}) {
45
+ if (!message) throw new Error("No message given")
46
+ if (!type) throw new Error("No type given")
47
+
48
+ let title
49
+
50
+ if (type == "alert") {
51
+ title = I18nOnSteroids.getCurrent().t("js.flash_message.alert", {defaultValue: "Alert"})
52
+ } else if (type == "error") {
53
+ title = I18nOnSteroids.getCurrent().t("js.flash_message.error", {defaultValue: "Error"})
54
+ } else if (type == "success") {
55
+ title = I18nOnSteroids.getCurrent().t("js.flash_message.success", {defaultValue: "Success"})
56
+ } else {
57
+ title = I18nOnSteroids.getCurrent().t("js.flash_message.notification", {defaultValue: "Notification"})
58
+ }
59
+
60
+ const event = new CustomEvent("pushNotification", {
61
+ detail: {
62
+ message,
63
+ title,
64
+ type
65
+ }
66
+ })
67
+
68
+ globalThis.dispatchEvent(event)
69
+ }
70
+ }
package/src/form.jsx ADDED
@@ -0,0 +1,91 @@
1
+ import React, {createContext, useContext, useMemo} from "react"
2
+ import BaseComponent from "./base-component"
3
+ import FormDataObjectizer from "form-data-objectizer"
4
+ import memo from "set-state-compare/src/memo"
5
+ import {Platform} from "react-native"
6
+ import PropTypes from "prop-types"
7
+ import {shapeComponent} from "set-state-compare/src/shape-component"
8
+
9
+ const FormContext = createContext(null)
10
+ const useForm = () => useContext(FormContext)
11
+
12
+ class FormInputs {
13
+ constructor(props) {
14
+ this.inputs = {}
15
+ this.onSubmit = props?.onSubmit
16
+ }
17
+
18
+ asObject() {
19
+ const result = {}
20
+ const formDataObjectizer = new FormDataObjectizer()
21
+
22
+ for(const key in this.inputs) {
23
+ const value = this.inputs[key]
24
+
25
+ formDataObjectizer.treatInitial(key, value, result)
26
+ }
27
+
28
+ return result
29
+ }
30
+
31
+ setValue(name, value) {
32
+ if (!name) throw new Error("'name' is required")
33
+
34
+ this.inputs[name] = value
35
+ }
36
+
37
+ setValueWithHidden(name, value) {
38
+ this.setValue(name, value)
39
+
40
+ if (Platform.OS == "web") {
41
+ return <input name={name} type="hidden" value={value !== null && value !== undefined ? value : ""} />
42
+ }
43
+ }
44
+
45
+ submit() {
46
+ if (this.onSubmit) {
47
+ this.onSubmit()
48
+ }
49
+ }
50
+ }
51
+
52
+ const Form = memo(shapeComponent(class Form extends BaseComponent {
53
+ static propTypes = {
54
+ children: PropTypes.node,
55
+ formRef: PropTypes.object,
56
+ onSubmit: PropTypes.func,
57
+ setForm: PropTypes.func
58
+ }
59
+
60
+ render() {
61
+ const {children, formRef, onSubmit, setForm, ...restProps} = this.props
62
+ const form = useMemo(() => new FormInputs({onSubmit}), [])
63
+
64
+ useMemo(() => {
65
+ if (setForm) {
66
+ setForm(form)
67
+ }
68
+ }, [setForm])
69
+
70
+ return (
71
+ <FormContext.Provider value={form}>
72
+ {Platform.OS == "web" &&
73
+ <form ref={formRef} onSubmit={this.tt.onFormSubmit} {...restProps}>
74
+ {children}
75
+ </form>
76
+ }
77
+ {Platform.OS != "web" && this.props.children}
78
+ </FormContext.Provider>
79
+ )
80
+ }
81
+
82
+ onFormSubmit = (e) => {
83
+ e.preventDefault()
84
+
85
+ if (this.props.onSubmit) {
86
+ this.props.onSubmit()
87
+ }
88
+ }
89
+ }))
90
+
91
+ export {Form, FormContext, FormInputs, useForm}
@@ -0,0 +1,23 @@
1
+ import parse from "url-parse"
2
+ import qs from "qs"
3
+
4
+ class HistoryExpo {
5
+ push(path, ...params) {
6
+ const url = parse(path, {})
7
+ const actualParams = Object.assign({}, params)
8
+
9
+ if (url.query) {
10
+ Object.assign(actualParams, qs.parse(url.query.slice(1, url.query.length)))
11
+
12
+ url.set("query", null)
13
+ }
14
+
15
+ const actualPath = url.href
16
+
17
+ router.push({pathname: actualPath, params: actualParams})
18
+ }
19
+ }
20
+
21
+ const historyExpo = new HistoryExpo()
22
+
23
+ export default historyExpo
@@ -0,0 +1,25 @@
1
+ import Config from "./config"
2
+ import parse from "url-parse"
3
+ import qs from "qs"
4
+
5
+ class HistoryReactNative {
6
+ push(path, ...params) {
7
+ const url = parse(path, {})
8
+
9
+ if (url.query) {
10
+ const actualParams = Object.assign({}, params)
11
+
12
+ Object.assign(actualParams, qs.parse(url.query.slice(1, url.query.length)))
13
+
14
+ url.set("query", qs.stringify(actualParams))
15
+ }
16
+
17
+ const {linkTo} = Config.getLinkTo()
18
+
19
+ linkTo(url.href)
20
+ }
21
+ }
22
+
23
+ const historyReactNative = new HistoryReactNative()
24
+
25
+ export default historyReactNative
package/src/history.js ADDED
@@ -0,0 +1,3 @@
1
+ import {createBrowserHistory} from "history"
2
+
3
+ export default createBrowserHistory()
package/src/index.js ADDED
@@ -0,0 +1,3 @@
1
+ const stub = "Hello World"
2
+
3
+ export {stub}
@@ -0,0 +1,108 @@
1
+ import BaseComponent from "../base-component"
2
+ import classNames from "classnames"
3
+ import {Input as ApiMakerInput} from "@kaspernj/api-maker/build/inputs/input"
4
+ import Checkbox from "./checkbox"
5
+ import memo from "set-state-compare/src/memo"
6
+ import PropTypes from "prop-types"
7
+ import React from "react"
8
+ import {shapeComponent} from "set-state-compare/src/shape-component"
9
+ import useI18n from "i18n-on-steroids/src/use-i18n"
10
+ import useInput from "../use-input"
11
+
12
+ export default memo(shapeComponent(class ApiMakerInputsAttachment extends BaseComponent {
13
+ static propTypes = {
14
+ className: PropTypes.string,
15
+ model: PropTypes.object.isRequired,
16
+ onPurgeChanged: PropTypes.func,
17
+ purgeName: PropTypes.string
18
+ }
19
+
20
+ setup() {
21
+ const {t} = useI18n({namespace: "js.api_maker.inputs.attachment"})
22
+ const {inputProps} = useInput({props: this.props})
23
+
24
+ this.setInstance({inputProps, t})
25
+ this.useStates({
26
+ purgeChecked: false
27
+ })
28
+ }
29
+
30
+ render() {
31
+ const {inputProps, t} = this.tt
32
+ const {attribute, checkboxComponent, className, label, model, name, onPurgeChanged, purgeName, wrapperOpts, ...restProps} = this.props
33
+ const CheckboxComponent = checkboxComponent || Checkbox
34
+ const newInputProps = Object.assign({}, inputProps, {type: "file"})
35
+
36
+ return (
37
+ <div className={classNames("api-maker--inputs--attachment", "components--inputs--input", className)} {...restProps}>
38
+ {this.isImage() &&
39
+ <a href={this.getUrl()} target="_blank">
40
+ <img src={this.getUrl()} style={{maxWidth: "200px", maxHeight: "200px"}} />
41
+ </a>
42
+ }
43
+ {this.getUrl() &&
44
+ <div className="input-checkbox" style={{paddingTop: "15px", paddingBottom: "15px"}}>
45
+ <CheckboxComponent id={this.getPurgeInputId()} name={this.getPurgeInputName()} onChange={this.props.onPurgeChanged} />
46
+ <label className="checkbox-label" htmlFor={this.getPurgeInputId()}>
47
+ {t("js.shared.delete")}
48
+ </label>
49
+ </div>
50
+ }
51
+ {!this.s.purgeChecked &&
52
+ <ApiMakerInput
53
+ defaultValue={null}
54
+ inputProps={newInputProps}
55
+ model={model}
56
+ />
57
+ }
58
+ </div>
59
+ )
60
+ }
61
+
62
+ getContentType() {
63
+ const {attribute, model} = this.p
64
+ const attributeName = `${attribute}ContentType`
65
+
66
+ if (!(attributeName in model)) throw new Error(`No such method on ${model.modelClassData().name}: ${attributeName}`)
67
+
68
+ return model[attributeName]()
69
+ }
70
+
71
+ getPurgeInputId() {
72
+ const {inputProps} = this.tt
73
+
74
+ return `${inputProps.id}_purge`
75
+ }
76
+
77
+ getPurgeInputName() {
78
+ if ("purgeName" in this.props) return this.props.purgeName
79
+
80
+ const {inputProps} = this.tt
81
+
82
+ if (!inputProps.name) return null
83
+
84
+ const match = inputProps.name.match(/^(.+)\[(.+?)\]$/)
85
+ const purgeInputName = `${match[1]}[${match[2]}_purge]`
86
+
87
+ return purgeInputName
88
+ }
89
+
90
+ getUrl() {
91
+ const {attribute, model} = this.p
92
+ const attributeName = `${attribute}Url`
93
+
94
+ if (!(attributeName in model)) throw new Error(`No such method on ${model.modelClassData().name}: ${attributeName}`)
95
+
96
+ return model[attributeName]()
97
+ }
98
+
99
+ isImage() {
100
+ return this.getContentType()?.startsWith("image/")
101
+ }
102
+
103
+ onPurgeChanged = (e) => {
104
+ this.setState({purgeChecked: digg(e, "target", "checked")})
105
+
106
+ if (this.props.onPurgeChanged) this.props.onPurgeChanged(e)
107
+ }
108
+ }))
@@ -0,0 +1,37 @@
1
+ import {digg} from "diggerize"
2
+ import * as inflection from "inflection"
3
+
4
+ export default class ApiMakerInputsAutoSubmit {
5
+ constructor ({component}) {
6
+ this.component = component
7
+ }
8
+
9
+ autoSubmit () {
10
+ const {attribute, model} = this.component.props
11
+ const updateAttributeName = inflection.underscore(attribute)
12
+ const updateParams = {}
13
+
14
+ updateParams[updateAttributeName] = this.value()
15
+
16
+ model.update(updateParams)
17
+ }
18
+
19
+ value () {
20
+ const inputRef = this.component.props.inputRef || this.component.props.inputProps?.ref || this.component.inputProps?.ref || this.component.inputRef
21
+ const input = digg(inputRef, "current")
22
+
23
+ if (input.type == "checkbox") {
24
+ if (input.checked) {
25
+ if (input.value !== undefined) {
26
+ return input.value
27
+ } else {
28
+ return 1
29
+ }
30
+ } else {
31
+ return 0
32
+ }
33
+ }
34
+
35
+ return digg(input, "value")
36
+ }
37
+ }
@@ -0,0 +1,125 @@
1
+ import React, {useMemo} from "react"
2
+ import AutoSubmit from "./auto-submit"
3
+ import BaseComponent from "../base-component"
4
+ import {digg} from "diggerize"
5
+ import PropTypes from "prop-types"
6
+ import memo from "set-state-compare/src/memo"
7
+ import {shapeComponent} from "set-state-compare/src/shape-component"
8
+ import useInput from "../use-input"
9
+ import {useForm} from "../form"
10
+ import useUpdatedEvent from "../use-updated-event"
11
+
12
+ export default memo(shapeComponent(class ApiMakerInputsCheckbox extends BaseComponent {
13
+ static defaultProps = {
14
+ autoRefresh: false,
15
+ autoSubmit: false,
16
+ defaultValue: 1,
17
+ model: null,
18
+ zeroInput: true
19
+ }
20
+
21
+ static propTypes = {
22
+ attribute: PropTypes.string,
23
+ autoRefresh: PropTypes.bool.isRequired,
24
+ autoSubmit: PropTypes.bool.isRequired,
25
+ defaultChecked: PropTypes.bool,
26
+ defaultValue: PropTypes.node,
27
+ id: PropTypes.string,
28
+ inputRef: PropTypes.object,
29
+ model: PropTypes.object,
30
+ name: PropTypes.string,
31
+ onErrors: PropTypes.func,
32
+ onMatchValidationError: PropTypes.func,
33
+ zeroInput: PropTypes.bool
34
+ }
35
+
36
+ setup() {
37
+ const {autoRefresh, model} = this.p
38
+ const {inputProps, restProps: useInputRestProps} = useInput({props: this.props, wrapperOptions: {type: "checkbox"}})
39
+ const {defaultValue, name} = inputProps
40
+
41
+ this.setInstance({
42
+ form: useForm(),
43
+ inputProps,
44
+ useInputRestProps
45
+ })
46
+
47
+ useMemo(() => {
48
+ if (name) {
49
+ this.tt.form?.setValue(name, defaultValue)
50
+ }
51
+ }, [])
52
+
53
+ useUpdatedEvent(model, this.tt.onModelUpdated, {active: Boolean(autoRefresh && model)})
54
+ }
55
+
56
+ render () {
57
+ const {inputProps, useInputRestProps} = this.tt
58
+ const {
59
+ attribute,
60
+ autoRefresh,
61
+ autoSubmit,
62
+ checked,
63
+ defaultChecked,
64
+ defaultValue,
65
+ id,
66
+ inputRef,
67
+ model,
68
+ name,
69
+ onChange,
70
+ zeroInput,
71
+ ...restProps
72
+ } = useInputRestProps
73
+
74
+ return (
75
+ <>
76
+ {zeroInput && inputProps.name &&
77
+ <input defaultValue="0" name={inputProps.name} type="hidden" />
78
+ }
79
+ <input
80
+ {...inputProps}
81
+ data-auto-refresh={autoRefresh}
82
+ data-auto-submit={autoSubmit}
83
+ defaultValue={defaultValue}
84
+ onChange={this.tt.onChanged}
85
+ type="checkbox"
86
+ {...restProps}
87
+ />
88
+ </>
89
+ )
90
+ }
91
+
92
+ onChanged = (...args) => {
93
+ const {form, inputProps} = this.tt
94
+ const {attribute, autoSubmit, model, onChange} = this.props
95
+ const {name} = inputProps
96
+
97
+ if (attribute && autoSubmit && model) new AutoSubmit({component: this}).autoSubmit()
98
+
99
+ if (form && name) {
100
+ const checked = args[0].target.checked
101
+
102
+ form.setValue(name, checked)
103
+ }
104
+
105
+ if (onChange) onChange(...args)
106
+ }
107
+
108
+ onModelUpdated = (args) => {
109
+ const inputRef = digg(this.tt.inputProps, "ref")
110
+
111
+ if (!inputRef.current) {
112
+ // This can happen if the component is being unmounted
113
+ return
114
+ }
115
+
116
+ const {attribute} = this.p
117
+ const newModel = digg(args, "model")
118
+ const currentChecked = digg(inputRef, "current", "checked")
119
+ const newValue = newModel.readAttribute(attribute)
120
+
121
+ if (currentChecked != newValue) {
122
+ inputRef.current.checked = newValue
123
+ }
124
+ }
125
+ }))
@@ -0,0 +1,116 @@
1
+ import BaseComponent from "../base-component"
2
+ import classNames from "classnames"
3
+ import {digs} from "diggerize"
4
+ import inputWrapper from "./input-wrapper"
5
+ import * as inflection from "inflection"
6
+ import InvalidFeedback from "../bootstrap/invalid-feedback"
7
+ import PropTypes from "prop-types"
8
+ import propTypesExact from "prop-types-exact"
9
+ import React from "react"
10
+ import memo from "set-state-compare/src/memo"
11
+ import {shapeComponent} from "set-state-compare/src/shape-component"
12
+
13
+ const ApiMakerInputsCheckboxes = memo(shapeComponent(class ApiMakerInputsCheckboxes extends BaseComponent {
14
+ static propTypes = propTypesExact({
15
+ attribute: PropTypes.string,
16
+ defaultValue: PropTypes.array,
17
+ id: PropTypes.string,
18
+ inputProps: PropTypes.object.isRequired,
19
+ label: PropTypes.node,
20
+ model: PropTypes.object,
21
+ name: PropTypes.string,
22
+ onChange: PropTypes.func,
23
+ options: PropTypes.array.isRequired,
24
+ wrapperOpts: PropTypes.object
25
+ })
26
+
27
+ render () {
28
+ const {className, inputProps, label, wrapperOpts, ...restProps} = this.props
29
+
30
+ return (
31
+ <div className={classNames("component-bootstrap-check-boxes", className)} {...restProps}>
32
+ <input name={this.inputName()} ref={this.props.inputProps.ref} type="hidden" value="" />
33
+ {this.props.options.map((option, index) => this.optionElement(option, index))}
34
+ </div>
35
+ )
36
+ }
37
+
38
+ inputDefaultValue () {
39
+ const {attribute, defaultValue, model} = this.props
40
+
41
+ if (defaultValue) {
42
+ return defaultValue
43
+ } else if (attribute && model) {
44
+ if (!model[attribute])
45
+ throw `No such attribute: ${attribute}`
46
+
47
+ return this.props.model[attribute]()
48
+ }
49
+ }
50
+
51
+ inputCheckboxClassName () {
52
+ const classNames = []
53
+
54
+ if (this.props.wrapperOpts.errors.length > 0) classNames.push("is-invalid")
55
+
56
+ return classNames.join(" ")
57
+ }
58
+
59
+ inputName () {
60
+ if (this.props.name) {
61
+ return `${this.props.name}[]`
62
+ } else if (this.props.model) {
63
+ return `${this.props.model.modelClassData().paramKey}[${inflection.underscore(this.props.attribute)}]`
64
+ }
65
+ }
66
+
67
+ isDefaultSelected (option) {
68
+ let defaultValue = this.inputDefaultValue()
69
+
70
+ if (!defaultValue) return false
71
+
72
+ if (defaultValue.constructor === Array) {
73
+ return defaultValue.includes(option)
74
+ } else {
75
+ return defaultValue == option
76
+ }
77
+ }
78
+
79
+ generatedId () {
80
+ if (!this.generatedIdValue)
81
+ this.generatedIdValue = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
82
+
83
+ return this.generatedIdValue
84
+ }
85
+
86
+ optionElement (option, index) {
87
+ const {onChange, options, wrapperOpts} = this.props
88
+ const {errors} = digs(wrapperOpts, "errors")
89
+ const id = `${this.generatedId()}-${index}`
90
+
91
+ return (
92
+ <div className="checkboxes-option" key={`option-${option[1]}`}>
93
+ <input
94
+ className={this.inputCheckboxClassName()}
95
+ data-option-value={option[1]}
96
+ defaultChecked={this.isDefaultSelected(option[1])}
97
+ id={id}
98
+ name={this.inputName()}
99
+ onChange={onChange}
100
+ type="checkbox"
101
+ value={option[1]}
102
+ />
103
+
104
+ <label className="ml-1" htmlFor={id}>
105
+ {option[0]}
106
+ </label>
107
+
108
+ {(index + 1) == options.length && errors.length > 0 &&
109
+ <InvalidFeedback errors={errors} />
110
+ }
111
+ </div>
112
+ )
113
+ }
114
+ }))
115
+
116
+ export default inputWrapper(ApiMakerInputsCheckboxes)
@@ -0,0 +1,15 @@
1
+ import * as inflection from "inflection"
2
+
3
+ export default function apiMakerIdForComponent(component) {
4
+ if ("id" in component.props) {
5
+ return component.props.id
6
+ } else if (component.props.attribute && component.props.model) {
7
+ return `${component.props.model.modelClassData().paramKey}_${inflection.underscore(component.props.attribute)}`
8
+ } else if (component.generatedInputId) {
9
+ return component.generatedInputId
10
+ } else {
11
+ const generatedInputId = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
12
+ component.generatedInputId = generatedInputId
13
+ return generatedInputId
14
+ }
15
+ }
@@ -0,0 +1,16 @@
1
+ import React from "react"
2
+ import useInput from "../use-input"
3
+
4
+ const inputWrapper = (WrapperComponentClass, wrapperOptions = {}) => (props) => {
5
+ const {inputProps, restProps, wrapperOpts} = useInput({props, wrapperOptions})
6
+
7
+ return (
8
+ <WrapperComponentClass
9
+ inputProps={inputProps}
10
+ wrapperOpts={wrapperOpts}
11
+ {...restProps}
12
+ />
13
+ )
14
+ }
15
+
16
+ export default inputWrapper