uchi 0.1.3 → 0.1.4

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 (283) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +222 -0
  3. data/app/assets/config/uchi_manifest.js +2 -0
  4. data/app/assets/javascripts/uchi/application.js +6095 -0
  5. data/app/assets/javascripts/uchi.js +4 -0
  6. data/app/assets/stylesheets/uchi/application.css +3971 -0
  7. data/app/assets/stylesheets/uchi/uchi.css +17 -0
  8. data/app/assets/tailwind/uchi.css +21 -0
  9. data/app/components/flowbite/breadcrumb.rb +33 -0
  10. data/app/components/flowbite/breadcrumb_home.rb +26 -0
  11. data/app/components/flowbite/breadcrumb_item/current.rb +33 -0
  12. data/app/components/flowbite/breadcrumb_item/first.rb +35 -0
  13. data/app/components/flowbite/breadcrumb_item.rb +48 -0
  14. data/app/components/flowbite/breadcrumb_separator.rb +30 -0
  15. data/app/components/flowbite/button/outline.rb +22 -0
  16. data/app/components/flowbite/button/pill.rb +40 -0
  17. data/app/components/flowbite/button.rb +92 -0
  18. data/app/components/flowbite/card.rb +45 -0
  19. data/app/components/flowbite/input/checkbox.rb +73 -0
  20. data/app/components/flowbite/input/date.rb +11 -0
  21. data/app/components/flowbite/input/date_time.rb +11 -0
  22. data/app/components/flowbite/input/email.rb +12 -0
  23. data/app/components/flowbite/input/field.rb +117 -0
  24. data/app/components/flowbite/input/file.rb +30 -0
  25. data/app/components/flowbite/input/hint.rb +57 -0
  26. data/app/components/flowbite/input/label.rb +82 -0
  27. data/app/components/flowbite/input/number.rb +11 -0
  28. data/app/components/flowbite/input/password.rb +11 -0
  29. data/app/components/flowbite/input/phone.rb +11 -0
  30. data/app/components/flowbite/input/radio_button.rb +50 -0
  31. data/app/components/flowbite/input/select.rb +49 -0
  32. data/app/components/flowbite/input/textarea.rb +42 -0
  33. data/app/components/flowbite/input/url.rb +12 -0
  34. data/app/components/flowbite/input/validation_error.rb +11 -0
  35. data/app/components/flowbite/input_field/checkbox.html.erb +14 -0
  36. data/app/components/flowbite/input_field/checkbox.rb +54 -0
  37. data/app/components/flowbite/input_field/date.rb +13 -0
  38. data/app/components/flowbite/input_field/date_time.rb +13 -0
  39. data/app/components/flowbite/input_field/email.rb +13 -0
  40. data/app/components/flowbite/input_field/file.rb +13 -0
  41. data/app/components/flowbite/input_field/input_field.html.erb +8 -0
  42. data/app/components/flowbite/input_field/number.rb +13 -0
  43. data/app/components/flowbite/input_field/password.rb +13 -0
  44. data/app/components/flowbite/input_field/phone.rb +13 -0
  45. data/app/components/flowbite/input_field/radio_button.html.erb +14 -0
  46. data/app/components/flowbite/input_field/radio_button.rb +86 -0
  47. data/app/components/flowbite/input_field/select.rb +31 -0
  48. data/app/components/flowbite/input_field/text.rb +8 -0
  49. data/app/components/flowbite/input_field/textarea.rb +13 -0
  50. data/app/components/flowbite/input_field/url.rb +13 -0
  51. data/app/components/flowbite/input_field.rb +192 -0
  52. data/app/components/flowbite/link.rb +21 -0
  53. data/app/components/flowbite/style.rb +13 -0
  54. data/app/components/flowbite/toast/icon.html.erb +5 -0
  55. data/app/components/flowbite/toast/icon.rb +57 -0
  56. data/app/components/flowbite/toast/toast.html.erb +11 -0
  57. data/app/components/flowbite/toast.rb +34 -0
  58. data/app/components/uchi/field/base.rb +57 -0
  59. data/app/components/uchi/field/belongs_to/edit.html.erb +1 -0
  60. data/app/components/uchi/field/belongs_to/index.html.erb +1 -0
  61. data/app/components/uchi/field/belongs_to/show.html.erb +3 -0
  62. data/app/components/uchi/field/belongs_to.rb +105 -0
  63. data/app/components/uchi/field/blank/edit.html.erb +1 -0
  64. data/app/components/uchi/field/blank/index.html.erb +1 -0
  65. data/app/components/uchi/field/blank/show.html.erb +1 -0
  66. data/app/components/uchi/field/blank.rb +16 -0
  67. data/app/components/uchi/field/boolean/edit.html.erb +1 -0
  68. data/app/components/uchi/field/boolean/index.html.erb +9 -0
  69. data/app/components/uchi/field/boolean/show.html.erb +9 -0
  70. data/app/components/uchi/field/boolean.rb +27 -0
  71. data/app/components/uchi/field/date/edit.html.erb +1 -0
  72. data/app/components/uchi/field/date/index.html.erb +1 -0
  73. data/app/components/uchi/field/date/show.html.erb +1 -0
  74. data/app/components/uchi/field/date.rb +27 -0
  75. data/app/components/uchi/field/date_time/edit.html.erb +1 -0
  76. data/app/components/uchi/field/date_time/index.html.erb +1 -0
  77. data/app/components/uchi/field/date_time/show.html.erb +1 -0
  78. data/app/components/uchi/field/date_time.rb +27 -0
  79. data/app/components/uchi/field/file/edit.html.erb +1 -0
  80. data/app/components/uchi/field/file/index.html.erb +6 -0
  81. data/app/components/uchi/field/file/show.html.erb +8 -0
  82. data/app/components/uchi/field/file.rb +37 -0
  83. data/app/components/uchi/field/has_and_belongs_to_many/edit.html.erb +9 -0
  84. data/app/components/uchi/field/has_and_belongs_to_many/index.html.erb +1 -0
  85. data/app/components/uchi/field/has_and_belongs_to_many/show.html.erb +28 -0
  86. data/app/components/uchi/field/has_and_belongs_to_many.rb +131 -0
  87. data/app/components/uchi/field/has_many/edit.html.erb +1 -0
  88. data/app/components/uchi/field/has_many/index.html.erb +1 -0
  89. data/app/components/uchi/field/has_many/show.html.erb +28 -0
  90. data/app/components/uchi/field/has_many.rb +107 -0
  91. data/app/components/uchi/field/id/index.html.erb +4 -0
  92. data/app/components/uchi/field/id/show.html.erb +4 -0
  93. data/app/components/uchi/field/id.rb +26 -0
  94. data/app/components/uchi/field/image/edit.html.erb +1 -0
  95. data/app/components/uchi/field/image/index.html.erb +6 -0
  96. data/app/components/uchi/field/image/show.html.erb +6 -0
  97. data/app/components/uchi/field/image.rb +38 -0
  98. data/app/components/uchi/field/number/edit.html.erb +1 -0
  99. data/app/components/uchi/field/number/index.html.erb +1 -0
  100. data/app/components/uchi/field/number/show.html.erb +1 -0
  101. data/app/components/uchi/field/number.rb +32 -0
  102. data/app/components/uchi/field/string/edit.html.erb +1 -0
  103. data/app/components/uchi/field/string/index.html.erb +1 -0
  104. data/app/components/uchi/field/string/show.html.erb +1 -0
  105. data/app/components/uchi/field/string.rb +33 -0
  106. data/app/components/uchi/field/text/edit.html.erb +1 -0
  107. data/app/components/uchi/field/text/index.html.erb +1 -0
  108. data/app/components/uchi/field/text/show.html.erb +1 -0
  109. data/app/components/uchi/field/text.rb +38 -0
  110. data/app/components/uchi/ui/breadcrumb/breadcrumb.html.erb +13 -0
  111. data/app/components/uchi/ui/breadcrumb.rb +14 -0
  112. data/app/components/uchi/ui/form/footer/footer.html.erb +5 -0
  113. data/app/components/uchi/ui/form/footer.rb +15 -0
  114. data/app/components/uchi/ui/form/input/collection_checkboxes.html.erb +32 -0
  115. data/app/components/uchi/ui/form/input/collection_checkboxes.rb +125 -0
  116. data/app/components/uchi/ui/frame/frame.html.erb +3 -0
  117. data/app/components/uchi/ui/frame.rb +10 -0
  118. data/app/components/uchi/ui/index/records_table/records_table.html.erb +67 -0
  119. data/app/components/uchi/ui/index/records_table/search_form/search_form.html.erb +21 -0
  120. data/app/components/uchi/ui/index/records_table/search_form.rb +49 -0
  121. data/app/components/uchi/ui/index/records_table.rb +29 -0
  122. data/app/components/uchi/ui/index/turbo_frame.rb +50 -0
  123. data/app/components/uchi/ui/page_header/page_header.html.erb +24 -0
  124. data/app/components/uchi/ui/page_header.rb +18 -0
  125. data/app/components/uchi/ui/pagination/current_link.html.erb +3 -0
  126. data/app/components/uchi/ui/pagination/current_link.rb +10 -0
  127. data/app/components/uchi/ui/pagination/gap.html.erb +3 -0
  128. data/app/components/uchi/ui/pagination/gap.rb +10 -0
  129. data/app/components/uchi/ui/pagination/item.rb +24 -0
  130. data/app/components/uchi/ui/pagination/link.html.erb +3 -0
  131. data/app/components/uchi/ui/pagination/link.rb +10 -0
  132. data/app/components/uchi/ui/pagination/next_link.html.erb +8 -0
  133. data/app/components/uchi/ui/pagination/next_link.rb +22 -0
  134. data/app/components/uchi/ui/pagination/pagination.html.erb +15 -0
  135. data/app/components/uchi/ui/pagination/previous_link.html.erb +8 -0
  136. data/app/components/uchi/ui/pagination/previous_link.rb +22 -0
  137. data/app/components/uchi/ui/pagination.rb +48 -0
  138. data/app/components/uchi/ui/show/attribute_fields/attribute_fields.html.erb +14 -0
  139. data/app/components/uchi/ui/show/attribute_fields.rb +18 -0
  140. data/app/components/uchi/ui/spinner/spinner.html.erb +7 -0
  141. data/app/components/uchi/ui/spinner.rb +15 -0
  142. data/app/controllers/uchi/application_controller.rb +4 -0
  143. data/app/controllers/uchi/controller.rb +13 -0
  144. data/app/controllers/uchi/repository_controller.rb +166 -0
  145. data/app/helpers/uchi/application_helper.rb +17 -0
  146. data/app/jobs/uchi/application_job.rb +4 -0
  147. data/app/mailers/uchi/application_mailer.rb +6 -0
  148. data/app/views/layouts/uchi/_flash_messages.html.erb +10 -0
  149. data/app/views/layouts/uchi/application.html.erb +33 -0
  150. data/app/views/uchi/repository/edit.html.erb +40 -0
  151. data/app/views/uchi/repository/index.html.erb +49 -0
  152. data/app/views/uchi/repository/new.html.erb +37 -0
  153. data/app/views/uchi/repository/show.html.erb +41 -0
  154. data/lib/generators/uchi/controller/controller_generator.rb +16 -0
  155. data/lib/generators/uchi/controller/templates/controller.rb.tt +11 -0
  156. data/lib/generators/uchi/install/install_generator.rb +13 -0
  157. data/lib/generators/uchi/repository/repository_generator.rb +16 -0
  158. data/lib/generators/uchi/repository/templates/repository.rb.tt +11 -0
  159. data/lib/tasks/uchi_tasks.rake +4 -0
  160. data/lib/uchi/application_record.rb +5 -0
  161. data/lib/uchi/engine.rb +24 -0
  162. data/lib/uchi/field/configuration.rb +142 -0
  163. data/lib/uchi/field.rb +80 -0
  164. data/lib/uchi/i18n.rb +13 -0
  165. data/lib/uchi/pagination/controller.rb +26 -0
  166. data/lib/uchi/pagination/page.rb +20 -0
  167. data/lib/uchi/pagy/LICENSE.txt +21 -0
  168. data/lib/uchi/pagy/classes/exceptions.rb +35 -0
  169. data/lib/uchi/pagy/classes/offset/offset.rb +56 -0
  170. data/lib/uchi/pagy/classes/request.rb +38 -0
  171. data/lib/uchi/pagy/modules/abilities/configurable.rb +38 -0
  172. data/lib/uchi/pagy/modules/abilities/linkable.rb +62 -0
  173. data/lib/uchi/pagy/modules/abilities/rangeable.rb +17 -0
  174. data/lib/uchi/pagy/modules/abilities/shiftable.rb +14 -0
  175. data/lib/uchi/pagy/modules/console.rb +40 -0
  176. data/lib/uchi/pagy/toolbox/helpers/loader.rb +19 -0
  177. data/lib/uchi/pagy/toolbox/helpers/page_url.rb +25 -0
  178. data/lib/uchi/pagy/toolbox/paginators/method.rb +21 -0
  179. data/lib/uchi/pagy/toolbox/paginators/offset.rb +35 -0
  180. data/lib/uchi/pagy.rb +60 -0
  181. data/lib/uchi/repository/routes.rb +62 -0
  182. data/lib/uchi/repository/translate.rb +284 -0
  183. data/lib/uchi/repository.rb +156 -0
  184. data/lib/uchi/sort_order.rb +35 -0
  185. data/lib/uchi/version.rb +5 -0
  186. data/lib/uchi.rb +18 -0
  187. data/uchi.gemspec +35 -0
  188. metadata +189 -97
  189. data/.github/dependabot.yml +0 -17
  190. data/.github/workflows/build.yml +0 -23
  191. data/.github/workflows/lint.yml +0 -30
  192. data/CHANGELOG.md +0 -29
  193. data/docs/fields.md +0 -82
  194. data/docs/repositories.md +0 -63
  195. data/package.json +0 -31
  196. data/sig/uchi.rbs +0 -4
  197. data/test/components/uchi/field/belongs_to_test.rb +0 -134
  198. data/test/components/uchi/field/blank_test.rb +0 -119
  199. data/test/components/uchi/field/boolean_test.rb +0 -163
  200. data/test/components/uchi/field/date_test.rb +0 -163
  201. data/test/components/uchi/field/date_time_test.rb +0 -152
  202. data/test/components/uchi/field/has_and_belongs_to_many_test.rb +0 -144
  203. data/test/components/uchi/field/has_many_test.rb +0 -138
  204. data/test/components/uchi/field/id_test.rb +0 -113
  205. data/test/components/uchi/field/number_test.rb +0 -163
  206. data/test/components/uchi/field/string_test.rb +0 -159
  207. data/test/components/uchi/field/text_test.rb +0 -160
  208. data/test/components/uchi/ui/form/input/collection_checkboxes_test.rb +0 -171
  209. data/test/controllers/uchi/authors_controller_test.rb +0 -120
  210. data/test/controllers/uchi/repository_controller_test.rb +0 -93
  211. data/test/controllers/uchi/scoped_repository_controller_test.rb +0 -73
  212. data/test/dummy/Rakefile +0 -6
  213. data/test/dummy/app/assets/images/.keep +0 -0
  214. data/test/dummy/app/assets/stylesheets/application.css +0 -15
  215. data/test/dummy/app/controllers/application_controller.rb +0 -4
  216. data/test/dummy/app/controllers/concerns/.keep +0 -0
  217. data/test/dummy/app/controllers/uchi/authors_controller.rb +0 -7
  218. data/test/dummy/app/controllers/uchi/books_controller.rb +0 -7
  219. data/test/dummy/app/controllers/uchi/titles_controller.rb +0 -7
  220. data/test/dummy/app/helpers/application_helper.rb +0 -2
  221. data/test/dummy/app/jobs/application_job.rb +0 -7
  222. data/test/dummy/app/mailers/application_mailer.rb +0 -4
  223. data/test/dummy/app/models/application_record.rb +0 -3
  224. data/test/dummy/app/models/author.rb +0 -5
  225. data/test/dummy/app/models/book.rb +0 -4
  226. data/test/dummy/app/models/concerns/.keep +0 -0
  227. data/test/dummy/app/models/title.rb +0 -3
  228. data/test/dummy/app/uchi/repositories/author.rb +0 -20
  229. data/test/dummy/app/uchi/repositories/book.rb +0 -16
  230. data/test/dummy/app/uchi/repositories/title.rb +0 -17
  231. data/test/dummy/app/views/layouts/application.html.erb +0 -27
  232. data/test/dummy/app/views/layouts/mailer.html.erb +0 -13
  233. data/test/dummy/app/views/layouts/mailer.text.erb +0 -1
  234. data/test/dummy/app/views/pwa/manifest.json.erb +0 -22
  235. data/test/dummy/app/views/pwa/service-worker.js +0 -26
  236. data/test/dummy/bin/dev +0 -2
  237. data/test/dummy/bin/rails +0 -4
  238. data/test/dummy/bin/rake +0 -4
  239. data/test/dummy/bin/setup +0 -34
  240. data/test/dummy/config/application.rb +0 -29
  241. data/test/dummy/config/boot.rb +0 -5
  242. data/test/dummy/config/cable.yml +0 -10
  243. data/test/dummy/config/database.yml +0 -32
  244. data/test/dummy/config/environment.rb +0 -5
  245. data/test/dummy/config/environments/development.rb +0 -69
  246. data/test/dummy/config/environments/production.rb +0 -89
  247. data/test/dummy/config/environments/test.rb +0 -53
  248. data/test/dummy/config/initializers/content_security_policy.rb +0 -25
  249. data/test/dummy/config/initializers/filter_parameter_logging.rb +0 -8
  250. data/test/dummy/config/initializers/inflections.rb +0 -16
  251. data/test/dummy/config/locales/da.yml +0 -52
  252. data/test/dummy/config/locales/en.yml +0 -31
  253. data/test/dummy/config/puma.rb +0 -38
  254. data/test/dummy/config/routes.rb +0 -9
  255. data/test/dummy/config/storage.yml +0 -34
  256. data/test/dummy/config.ru +0 -6
  257. data/test/dummy/db/migrate/20251002183635_create_authors.rb +0 -11
  258. data/test/dummy/db/migrate/20251005131726_create_books.rb +0 -9
  259. data/test/dummy/db/migrate/20251005131811_create_titles.rb +0 -11
  260. data/test/dummy/db/migrate/20251031140958_add_author_books_join_table.rb +0 -9
  261. data/test/dummy/db/schema.rb +0 -44
  262. data/test/dummy/log/.keep +0 -0
  263. data/test/dummy/public/400.html +0 -114
  264. data/test/dummy/public/404.html +0 -114
  265. data/test/dummy/public/406-unsupported-browser.html +0 -114
  266. data/test/dummy/public/422.html +0 -114
  267. data/test/dummy/public/500.html +0 -114
  268. data/test/dummy/public/icon.png +0 -0
  269. data/test/dummy/public/icon.svg +0 -3
  270. data/test/dummy/storage/.keep +0 -0
  271. data/test/dummy/test/fixtures/authors.yml +0 -11
  272. data/test/dummy/test/models/author_test.rb +0 -7
  273. data/test/dummy/tmp/.keep +0 -0
  274. data/test/dummy/tmp/pids/.keep +0 -0
  275. data/test/dummy/tmp/storage/.keep +0 -0
  276. data/test/test_helper.rb +0 -15
  277. data/test/uchi/field_test.rb +0 -77
  278. data/test/uchi/i18n_test.rb +0 -18
  279. data/test/uchi/repository/routes_test.rb +0 -49
  280. data/test/uchi/repository/translate_test.rb +0 -272
  281. data/test/uchi/repository_test.rb +0 -137
  282. data/test/uchi/sort_order_test.rb +0 -47
  283. data/test/uchi_test.rb +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 92849fb71ff71c56d796e3e43601dd99eabc565180c902ac129feb25f8cc5fc0
4
- data.tar.gz: 789df26e207ac6ed7e8857269bafc4bcd06d21c3ec22b6070c1092c222a42d08
3
+ metadata.gz: 45c91f06accc01dce5031d673f7c0a78c71174fadf6d079dc288b68d815b4a9c
4
+ data.tar.gz: 76542812dc454f122bb54ed3a86b0857860ff5ff633cf3a9a3f120ea28bf782c
5
5
  SHA512:
6
- metadata.gz: 146839a586037ec5e0b713aec63ca699b50346c9d0be98935db42a562fe1f78be1bc6d16d4afe9a4ec38431cb440efb4d63b79527b2873db87ce01225f256153
7
- data.tar.gz: 002ea4b08886edfefbab4c7580db0524b1776824f2aea0d75077c90ed2331cc3297ed3616121cf6dd86bc9e54cc0556e5d4a00ccc8848a749d1af6b593bf9223
6
+ metadata.gz: ec71b43f8744a50005922ba80cd6224ce88cd8c90e4bbf70eb33d9017e327f184bb032f9a1609b3e1c48430b2345cc96a42644eee4cbb63a30577ee530995724
7
+ data.tar.gz: c8e26d886f9153251caf74d123883d529c3247b8252048be18706e65174688223db6f03c0ca7f027f95bab9df278446c951664c55a57727cab212f549b96c9df
data/README.md ADDED
@@ -0,0 +1,222 @@
1
+ # Uchi
2
+ ## Admin framework for Rails applications
3
+
4
+ Build usable and extensible admin panels for your Ruby on Rails application in minutes.
5
+
6
+ Level up your scaffolds with a modern admin backend framework, designed for Rails developers who demand both beauty, functionality, and extensibility. Uchi provides a set of components and conventions for creating user interfaces that are both powerful and easy to use.
7
+
8
+ ## Installation
9
+
10
+ ### 1. Install the gem
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ ```ruby
15
+ gem "uchi"
16
+ ```
17
+
18
+ And then execute:
19
+
20
+ ```bash
21
+ $ bundle
22
+ ```
23
+
24
+ ### 2. Install Uchi
25
+
26
+ ```bash
27
+ $ rails generate uchi:install
28
+ ```
29
+
30
+ ### 3. Create a repository
31
+
32
+ Add a repository for one of your models by running
33
+
34
+ ```bash
35
+ $ rails generate uchi:repository Customer
36
+ ```
37
+
38
+ This adds a repository in `app/uchi/repositories/customer.rb`, a controller to use that repository in `app/controllers/uchi/customers_controller.rb` and a route to `config/routes.rb` to send requests to the controller.
39
+
40
+ You can now visit http://localhost:3000/uchi/customers - welcome to Uchi :)
41
+
42
+ Next up; customize your repository to return the fields you want to expose.
43
+
44
+ ## Fields
45
+
46
+ Each repository defines a method, `#fields`, that returns the fields to include in the views in that repository. For example, a `Customer` repository could return its fields as:
47
+
48
+ ```ruby
49
+ class Uchi::Repository::Customer < Uchi::Repository
50
+ def fields
51
+ [
52
+ Field::String.new(:name),
53
+ Field::Date.new(:started_on),
54
+ Field::BelongsTo.new(:company),
55
+ Field::HasMany.new(:agreements),
56
+ ]
57
+ end
58
+ end
59
+ ```
60
+
61
+ Uchi comes with a bunch of fields that you can choose from, fx:
62
+
63
+ - `Field::BelongsTo`
64
+ - `Field::Boolean`
65
+ - `Field::Date`
66
+ - `Field::DateTime`
67
+ - `Field::HasMany`
68
+ - `Field::Number`
69
+ - `Field::String`
70
+
71
+ If none of the above works for you, you can create your own and use those.
72
+
73
+ For more details about fields see the [Fields documentation](docs/fields.md).
74
+
75
+ ## Repositories
76
+
77
+ The cornerstones of Uchi are the repositories. This is where you configure what parts of your models you want to expose and how to do it.
78
+
79
+ There's a one-to-one mapping between a repository and a model. So if you have a `User` model that you want to include in Uchi, you must have a `User` repository as well.
80
+
81
+ ### Model inference
82
+
83
+ For the most part the model class for each repository is inferred from the repository class name, ie `Uchi::Repository::User` manages the `User` model. In some cases you might need to specify the relationship explicitly. You can override the `Uchi::Repository.model` class method in that case:
84
+
85
+ ```ruby
86
+ class Uchi::Repository::Something < Uchi::Repository
87
+ def self.model
88
+ ::SomethingElse
89
+ end
90
+ end
91
+ ```
92
+
93
+ For more details about repositories see the [Repositories documentation](docs/repositories.md).
94
+
95
+ ## Translations
96
+
97
+ Everything is localizable and translatable out of the box.
98
+
99
+ ### Fields
100
+
101
+ Repository fields are translated using translation keys on the form `uchi.repository.<repository name>.field.<field name>`. For example, the translations for a `User` repository could look like:
102
+
103
+ ```yaml
104
+ en:
105
+ uchi:
106
+ repository:
107
+ user:
108
+ name: "Name"
109
+ password: "Password"
110
+ ```
111
+
112
+ Field translations not specified in the `uchi` scope will default to whatever we get from Rails' `Model#human_attribute_name`.
113
+
114
+ ### Repositories
115
+
116
+ Repository names are based on the models they manage. Their translation keys are on the form `uchi.repository.<repository name>.model` and should have pluralization options. So a `UserRepository` would look like:
117
+
118
+ ```yaml
119
+ en:
120
+ uchi:
121
+ repository:
122
+ user:
123
+ model:
124
+ one: user
125
+ other: users
126
+ ```
127
+
128
+ Repository translations will default to whatever we get from Rails' `Model#model_name.human_name`.
129
+
130
+ ### Views
131
+
132
+ Copy on views can be translated specifically for each view. Their translation keys are on the form `uchi.repository.<repository name>.view.<view name>.<element key>`. For example to translate the "Add" button on the index view for the `UserRepository` you'd use the following translation:
133
+
134
+ ```yaml
135
+ en:
136
+ uchi:
137
+ repository:
138
+ user:
139
+ view:
140
+ index:
141
+ add: "Create %{model}"
142
+ ```
143
+
144
+ ## Authentication
145
+
146
+ ### Basic authentication
147
+
148
+ The simplest way to lock your admin interface down is to enable basic authentication in your `Uchi::ApplicationController`:
149
+
150
+ ```ruby
151
+ module Uchi
152
+ class ApplicationController < Uchi::Controller
153
+ http_basic_authenticate_with :name => "uchi", :password => "rocks"
154
+ end
155
+ end
156
+ ```
157
+
158
+ See https://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Basic.html for more advanced examples.
159
+
160
+ ## Existing authentication
161
+
162
+ Uchi exposes a helper method (both in views and controllers) called `#uchi_user`. By default it calls the global `current_user` method, so it should work with Devise and most Rails authentication systems.
163
+
164
+ In order to require the user to be logged in, you could do something like
165
+
166
+ ```ruby
167
+ module Uchi
168
+ class ApplicationController < Uchi::Controller
169
+ before_action :authenticate_user!
170
+
171
+ private
172
+
173
+ def authenticate_user!
174
+ return if uchi_user
175
+
176
+ # Insert more details authentication requirements here, for example:
177
+ # return unless uchi_user && uchi_user.admin?
178
+
179
+ redirect_to main_app.new_user_session_path, :alert => "You must be signed in to access this section."
180
+ end
181
+ end
182
+ end
183
+ ```
184
+
185
+ ### Not using `current_user`?
186
+
187
+ If you expose the current user model via another method name, override the `uchi_user` method in your `Uchi::ApplicationController`:
188
+
189
+ ```ruby
190
+ module Uchi
191
+ class ApplicationController < Uchi::Controller
192
+ def uchi_user
193
+ current_employee
194
+ end
195
+ end
196
+ end
197
+ ```
198
+
199
+ ## Contributing
200
+
201
+ Bug reports and pull requests are welcome on GitHub at https://github.com/substancelab/uchi.
202
+
203
+ ## Development
204
+
205
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
206
+
207
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
208
+
209
+ ## Principles
210
+
211
+ ### Defaults are defaults
212
+
213
+ Rely on defaults whenever possible. If something has already been decided for us by Rails or Flowbite or Tailwind use their decision.
214
+
215
+ ### I18n is opt in
216
+
217
+ We don't want to force you to translate everything. If a field doesn't need a translation, don't add one, we'll just fall back to the fields name.
218
+
219
+ ## Credits
220
+
221
+ * Uchi contains parts of [Pagy](https://github.com/ddnexus/pagy), Copyright (c) 2017-2025 Domizio Demichelis
222
+ * Uchi contains parts of [Flowbite Components](https://github.com/substancelab/flowbite-components), Copyright (c) 2025 Substance Lab
@@ -0,0 +1,2 @@
1
+ //= link_directory ../javascripts/uchi .js
2
+ //= link_directory ../stylesheets/uchi .css