tybo 0.0.3 → 0.0.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 (141) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +23 -0
  4. data/Rakefile +8 -0
  5. data/app/assets/config/tybo_manifest.js +1 -0
  6. data/app/assets/stylesheets/tybo/application.css +15 -0
  7. data/{lib/app → app}/components/attachment_card_component.html.erb +0 -0
  8. data/{lib/app → app}/components/attachment_card_component.rb +0 -0
  9. data/{lib/app → app}/components/attachments_list_component.html.erb +0 -0
  10. data/{lib/app → app}/components/attachments_list_component.rb +0 -0
  11. data/{lib/app → app}/components/current_user_mini_card_component.html.erb +2 -2
  12. data/{lib/app → app}/components/current_user_mini_card_component.rb +0 -0
  13. data/{lib/app → app}/components/form_component.html.erb +0 -0
  14. data/{lib/app → app}/components/form_component.rb +0 -0
  15. data/{lib/app → app}/components/forms/breadcrumb_component.html.erb +0 -0
  16. data/{lib/app → app}/components/forms/breadcrumb_component.rb +0 -0
  17. data/{lib/app → app}/components/forms/delete_button_component.html.erb +0 -0
  18. data/{lib/app → app}/components/forms/delete_button_component.rb +0 -0
  19. data/{lib/app → app}/components/forms/divider_component.html.erb +0 -0
  20. data/{lib/app → app}/components/forms/divider_component.rb +0 -0
  21. data/{lib/app → app}/components/forms/submit_button_component.html.erb +0 -0
  22. data/{lib/app → app}/components/forms/submit_button_component.rb +0 -0
  23. data/{lib/app → app}/components/forms/subtitle_component.html.erb +0 -0
  24. data/{lib/app → app}/components/forms/subtitle_component.rb +0 -0
  25. data/{lib/app → app}/components/forms/title_component.html.erb +0 -0
  26. data/{lib/app → app}/components/forms/title_component.rb +0 -0
  27. data/{lib/app → app}/components/icons/collection_component.html.erb +0 -0
  28. data/{lib/app → app}/components/icons/collection_component.rb +0 -0
  29. data/{lib/app → app}/components/icons/home_component.html.erb +0 -0
  30. data/{lib/app → app}/components/icons/home_component.rb +0 -0
  31. data/{lib/app → app}/components/icons/mic_component.html.erb +0 -0
  32. data/{lib/app → app}/components/icons/mic_component.rb +0 -0
  33. data/{lib/app → app}/components/icons/news_paper_component.html.erb +0 -0
  34. data/{lib/app → app}/components/icons/news_paper_component.rb +0 -0
  35. data/{lib/app → app}/components/icons/office_building_component.html.erb +0 -0
  36. data/{lib/app → app}/components/icons/office_building_component.rb +0 -0
  37. data/{lib/app → app}/components/icons/question_mark_circle_component.html.erb +0 -0
  38. data/{lib/app → app}/components/icons/question_mark_circle_component.rb +0 -0
  39. data/{lib/app → app}/components/icons/trash_component.html.erb +0 -0
  40. data/{lib/app → app}/components/icons/trash_component.rb +0 -0
  41. data/{lib/app → app}/components/icons/users_component.html.erb +0 -0
  42. data/{lib/app → app}/components/icons/users_component.rb +0 -0
  43. data/{lib/app → app}/components/index_component.html.erb +0 -0
  44. data/{lib/app → app}/components/index_component.rb +0 -0
  45. data/{lib/app → app}/components/index_header_add_component.html.erb +0 -0
  46. data/{lib/app → app}/components/index_header_add_component.rb +0 -0
  47. data/{lib/app → app}/components/index_header_component.html.erb +0 -0
  48. data/{lib/app → app}/components/index_header_component.rb +0 -0
  49. data/{lib/app → app}/components/input/file_component.html.erb +0 -0
  50. data/{lib/app → app}/components/input/file_component.rb +0 -0
  51. data/{lib/app → app}/components/sidebar_component.html.erb +0 -0
  52. data/{lib/app → app}/components/sidebar_component.rb +0 -0
  53. data/{lib/app → app}/components/sidebar_item_component.html.erb +0 -0
  54. data/{lib/app → app}/components/sidebar_item_component.rb +0 -0
  55. data/{lib/app → app}/components/sign_out_button_component.html.erb +1 -1
  56. data/{lib/app → app}/components/sign_out_button_component.rb +3 -0
  57. data/{lib/app → app}/components/tables/active_record_th_component.html.erb +0 -0
  58. data/{lib/app → app}/components/tables/active_record_th_component.rb +1 -0
  59. data/{lib/app → app}/components/tables/table_component.html.erb +0 -0
  60. data/{lib/app → app}/components/tables/table_component.rb +0 -0
  61. data/{lib/app → app}/components/tables/tbody_component.html.erb +0 -0
  62. data/{lib/app → app}/components/tables/tbody_component.rb +0 -0
  63. data/{lib/app → app}/components/tables/td_component.html.erb +1 -1
  64. data/{lib/app → app}/components/tables/td_component.rb +0 -0
  65. data/{lib/app → app}/components/tables/th_component.html.erb +0 -0
  66. data/{lib/app → app}/components/tables/th_component.rb +0 -0
  67. data/{lib/app → app}/components/tables/thead_component.html.erb +0 -0
  68. data/{lib/app → app}/components/tables/thead_component.rb +0 -0
  69. data/{lib/app → app}/components/tables/tr_component.html.erb +0 -0
  70. data/{lib/app → app}/components/tables/tr_component.rb +0 -0
  71. data/app/controllers/tybo/application_controller.rb +4 -0
  72. data/app/controllers/tybo/login_controller.rb +8 -0
  73. data/app/helpers/tybo/application_helper.rb +5 -0
  74. data/app/helpers/tybo/flash_helper.rb +12 -0
  75. data/app/jobs/tybo/application_job.rb +4 -0
  76. data/app/mailers/tybo/application_mailer.rb +6 -0
  77. data/app/models/tybo/application_record.rb +5 -0
  78. data/app/views/devise/confirmations/new.html.erb +20 -0
  79. data/app/views/devise/login/home.html.erb +20 -0
  80. data/app/views/devise/mailer/_reset_password_instructions.html.erb +8 -0
  81. data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  82. data/app/views/devise/mailer/email_changed.html.erb +7 -0
  83. data/app/views/devise/mailer/password_change.html.erb +3 -0
  84. data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  85. data/app/views/devise/passwords/edit.html.erb +36 -0
  86. data/app/views/devise/passwords/new.html.erb +34 -0
  87. data/app/views/devise/registrations/edit.html.erb +35 -0
  88. data/app/views/devise/registrations/new.html.erb +25 -0
  89. data/app/views/devise/sessions/new.html.erb +50 -0
  90. data/app/views/devise/shared/_devise_errors.html.erb +26 -0
  91. data/app/views/devise/shared/_error_messages.html.erb +15 -0
  92. data/app/views/devise/shared/_links.html.erb +65 -0
  93. data/app/views/devise/unlocks/new.html.erb +19 -0
  94. data/app/views/layouts/_errors.html.erb +22 -0
  95. data/app/views/layouts/_flash.html.erb +24 -0
  96. data/app/views/layouts/devise_admin.html.erb +16 -0
  97. data/app/views/layouts/tybo/application.html.erb +14 -0
  98. data/app/views/login/home.html.erb +19 -0
  99. data/app/views/shared/_pagination.html.erb +36 -0
  100. data/config/initializers/devise.rb +311 -0
  101. data/config/initializers/pagy.rb +246 -0
  102. data/config/initializers/ransack.rb +13 -0
  103. data/config/locales/devise.en.yml +65 -0
  104. data/config/routes.rb +3 -0
  105. data/lib/generators/bo/USAGE +12 -0
  106. data/lib/generators/bo/bo_generator.rb +88 -0
  107. data/lib/generators/bo/templates/_form.html.erb +32 -0
  108. data/lib/generators/bo/templates/_search_bar.html.erb +96 -0
  109. data/lib/generators/bo/templates/_table.html.erb +29 -0
  110. data/lib/generators/bo/templates/controller.rb +66 -0
  111. data/lib/generators/bo/templates/index.html.erb +19 -0
  112. data/lib/generators/bo/templates/item.html.erb +17 -0
  113. data/lib/generators/bo/templates/new.html.erb +1 -0
  114. data/lib/generators/bo/templates/show.html.erb +1 -0
  115. data/lib/generators/bo/utils/files/fr.json +19 -0
  116. data/lib/generators/bo/utils/translations.rb +47 -0
  117. data/lib/generators/bo_namespace/USAGE +11 -0
  118. data/lib/generators/bo_namespace/bo_namespace_generator.rb +50 -0
  119. data/lib/generators/bo_namespace/templates/admin.html.erb +27 -0
  120. data/lib/generators/bo_namespace/templates/admin_controller.rb +7 -0
  121. data/lib/generators/bo_namespace/templates/seeds.rb +9 -0
  122. data/lib/generators/bo_namespace/templates/side_bar.html.erb +4 -0
  123. data/lib/generators/tybo_install/templates/application.tailwind.css +112 -0
  124. data/lib/generators/tybo_install/templates/simple_form_tailwind.rb +147 -0
  125. data/lib/generators/tybo_install/templates/tailwind.config.js +40 -0
  126. data/lib/generators/tybo_install/templates/tom-select.css +458 -0
  127. data/lib/generators/tybo_install/tybo_install_generator.rb +44 -0
  128. data/lib/tybo/engine.rb +19 -0
  129. data/lib/tybo/version.rb +3 -0
  130. data/lib/tybo.rb +4 -43
  131. metadata +186 -98
  132. data/lib/app/helpers/application_helper.rb +0 -5
  133. data/lib/app/helpers/flash_helper.rb +0 -16
  134. data/lib/app/javascript/controllers/attachments_controller.js +0 -14
  135. data/lib/app/javascript/controllers/dropdown_controller.js +0 -15
  136. data/lib/app/javascript/controllers/flash_controller.js +0 -7
  137. data/lib/app/javascript/controllers/index.js +0 -6
  138. data/lib/app/javascript/controllers/questions_controller.js +0 -61
  139. data/lib/app/javascript/controllers/search_form_controller.js +0 -20
  140. data/lib/app/javascript/controllers/ts/search_controller.js +0 -35
  141. data/lib/app/javascript/controllers/ts/select_controller.js +0 -9
@@ -0,0 +1,246 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Pagy initializer file (5.10.1)
4
+ # Customize only what you really need and notice that the core Pagy works also without any of the following lines.
5
+ # Should you just cherry pick part of this file, please maintain the require-order of the extras
6
+
7
+
8
+ # Pagy DEFAULT Variables
9
+ # See https://ddnexus.github.io/pagy/api/pagy#variables
10
+ # All the Pagy::DEFAULT are set for all the Pagy instances but can be overridden per instance by just passing them to
11
+ # Pagy.new|Pagy::Countless.new|Pagy::Calendar::*.new or any of the #pagy* controller methods
12
+
13
+
14
+ # Instance variables
15
+ # See https://ddnexus.github.io/pagy/api/pagy#instance-variables
16
+ # Pagy::DEFAULT[:page] = 1 # default
17
+ Pagy::DEFAULT[:items] = 20 # default
18
+ # Pagy::DEFAULT[:outset] = 0 # default
19
+
20
+
21
+ # Other Variables
22
+ # See https://ddnexus.github.io/pagy/api/pagy#other-variables
23
+ # Pagy::DEFAULT[:size] = [1,4,4,1] # default
24
+ # Pagy::DEFAULT[:page_param] = :page # default
25
+ # The :params can be also set as a lambda e.g ->(params){ params.exclude('useless').merge!('custom' => 'useful') }
26
+ # Pagy::DEFAULT[:params] = {} # default
27
+ # Pagy::DEFAULT[:fragment] = '#fragment' # example
28
+ # Pagy::DEFAULT[:link_extra] = 'data-remote="true"' # example
29
+ # Pagy::DEFAULT[:i18n_key] = 'pagy.item_name' # default
30
+ # Pagy::DEFAULT[:cycle] = true # example
31
+
32
+
33
+ # Extras
34
+ # See https://ddnexus.github.io/pagy/extras
35
+
36
+
37
+ # Backend Extras
38
+
39
+ # Array extra: Paginate arrays efficiently, avoiding expensive array-wrapping and without overriding
40
+ # See https://ddnexus.github.io/pagy/extras/array
41
+ # require 'pagy/extras/array'
42
+
43
+ # Calendar extra: Add pagination filtering by calendar time unit (year, quarter, month, week, day)
44
+ # See https://ddnexus.github.io/pagy/extras/calendar
45
+ # require 'pagy/extras/calendar'
46
+ # Default for each unit
47
+ # Pagy::Calendar::Year::DEFAULT[:order] = :asc # Time direction of pagination
48
+ # Pagy::Calendar::Year::DEFAULT[:format] = '%Y' # strftime format
49
+ #
50
+ # Pagy::Calendar::Quarter::DEFAULT[:order] = :asc # Time direction of pagination
51
+ # Pagy::Calendar::Quarter::DEFAULT[:format] = '%Y-Q%q' # strftime format
52
+ #
53
+ # Pagy::Calendar::Month::DEFAULT[:order] = :asc # Time direction of pagination
54
+ # Pagy::Calendar::Month::DEFAULT[:format] = '%Y-%m' # strftime format
55
+ #
56
+ # Pagy::Calendar::Week::DEFAULT[:order] = :asc # Time direction of pagination
57
+ # Pagy::Calendar::Week::DEFAULT[:format] = '%Y-%W' # strftime format
58
+ #
59
+ # Pagy::Calendar::Day::DEFAULT[:order] = :asc # Time direction of pagination
60
+ # Pagy::Calendar::Day::DEFAULT[:format] = '%Y-%m-%d' # strftime format
61
+ #
62
+ # Uncomment the following lines, if you need calendar localization without using the I18n extra
63
+ # module LocalizePagyCalendar
64
+ # def localize(time, opts)
65
+ # ::I18n.l(time, **opts)
66
+ # end
67
+ # end
68
+ # Pagy::Calendar.prepend LocalizePagyCalendar
69
+
70
+ # Countless extra: Paginate without any count, saving one query per rendering
71
+ # See https://ddnexus.github.io/pagy/extras/countless
72
+ # require 'pagy/extras/countless'
73
+ # Pagy::DEFAULT[:countless_minimal] = false # default (eager loading)
74
+
75
+ # Elasticsearch Rails extra: Paginate `ElasticsearchRails::Results` objects
76
+ # See https://ddnexus.github.io/pagy/extras/elasticsearch_rails
77
+ # Default :pagy_search method: change only if you use also
78
+ # the searchkick or meilisearch extra that defines the same
79
+ # Pagy::DEFAULT[:elasticsearch_rails_pagy_search] = :pagy_search
80
+ # Default original :search method called internally to do the actual search
81
+ # Pagy::DEFAULT[:elasticsearch_rails_search] = :search
82
+ # require 'pagy/extras/elasticsearch_rails'
83
+
84
+ # Headers extra: http response headers (and other helpers) useful for API pagination
85
+ # See http://ddnexus.github.io/pagy/extras/headers
86
+ # require 'pagy/extras/headers'
87
+ # Pagy::DEFAULT[:headers] = { page: 'Current-Page',
88
+ # items: 'Page-Items',
89
+ # count: 'Total-Count',
90
+ # pages: 'Total-Pages' } # default
91
+
92
+ # Meilisearch extra: Paginate `Meilisearch` result objects
93
+ # See https://ddnexus.github.io/pagy/extras/meilisearch
94
+ # Default :pagy_search method: change only if you use also
95
+ # the elasticsearch_rails or searchkick extra that define the same method
96
+ # Pagy::DEFAULT[:meilisearch_pagy_search] = :pagy_search
97
+ # Default original :search method called internally to do the actual search
98
+ # Pagy::DEFAULT[:meilisearch_search] = :ms_search
99
+ # require 'pagy/extras/meilisearch'
100
+
101
+ # Metadata extra: Provides the pagination metadata to Javascript frameworks like Vue.js, react.js, etc.
102
+ # See https://ddnexus.github.io/pagy/extras/metadata
103
+ # you must require the frontend helpers internal extra (BEFORE the metadata extra) ONLY if you need also the :sequels
104
+ # require 'pagy/extras/frontend_helpers'
105
+ # require 'pagy/extras/metadata'
106
+ # For performance reasons, you should explicitly set ONLY the metadata you use in the frontend
107
+ # Pagy::DEFAULT[:metadata] = %i[scaffold_url page prev next last] # example
108
+
109
+ # Searchkick extra: Paginate `Searchkick::Results` objects
110
+ # See https://ddnexus.github.io/pagy/extras/searchkick
111
+ # Default :pagy_search method: change only if you use also
112
+ # the elasticsearch_rails or meilisearch extra that defines the same
113
+ # DEFAULT[:searchkick_pagy_search] = :pagy_search
114
+ # Default original :search method called internally to do the actual search
115
+ # Pagy::DEFAULT[:searchkick_search] = :search
116
+ # require 'pagy/extras/searchkick'
117
+ # uncomment if you are going to use Searchkick.pagy_search
118
+ # Searchkick.extend Pagy::Searchkick
119
+
120
+
121
+ # Frontend Extras
122
+
123
+ # Bootstrap extra: Add nav, nav_js and combo_nav_js helpers and templates for Bootstrap pagination
124
+ # See https://ddnexus.github.io/pagy/extras/bootstrap
125
+ # require 'pagy/extras/bootstrap'
126
+
127
+ # Bulma extra: Add nav, nav_js and combo_nav_js helpers and templates for Bulma pagination
128
+ # See https://ddnexus.github.io/pagy/extras/bulma
129
+ # require 'pagy/extras/bulma'
130
+
131
+ # Foundation extra: Add nav, nav_js and combo_nav_js helpers and templates for Foundation pagination
132
+ # See https://ddnexus.github.io/pagy/extras/foundation
133
+ # require 'pagy/extras/foundation'
134
+
135
+ # Materialize extra: Add nav, nav_js and combo_nav_js helpers for Materialize pagination
136
+ # See https://ddnexus.github.io/pagy/extras/materialize
137
+ # require 'pagy/extras/materialize'
138
+
139
+ # Navs extra: Add nav_js and combo_nav_js javascript helpers
140
+ # Notice: the other frontend extras add their own framework-styled versions,
141
+ # so require this extra only if you need the unstyled version
142
+ # See https://ddnexus.github.io/pagy/extras/navs
143
+ # require 'pagy/extras/navs'
144
+
145
+ # Semantic extra: Add nav, nav_js and combo_nav_js helpers for Semantic UI pagination
146
+ # See https://ddnexus.github.io/pagy/extras/semantic
147
+ # require 'pagy/extras/semantic'
148
+
149
+ # UIkit extra: Add nav helper and templates for UIkit pagination
150
+ # See https://ddnexus.github.io/pagy/extras/uikit
151
+ # require 'pagy/extras/uikit'
152
+
153
+ # Multi size var used by the *_nav_js helpers
154
+ # See https://ddnexus.github.io/pagy/extras/navs#steps
155
+ # Pagy::DEFAULT[:steps] = { 0 => [2,3,3,2], 540 => [3,5,5,3], 720 => [5,7,7,5] } # example
156
+
157
+
158
+ # Feature Extras
159
+
160
+ # Gearbox extra: Automatically change the number of items per page depending on the page number
161
+ # See https://ddnexus.github.io/pagy/extras/gearbox
162
+ # require 'pagy/extras/gearbox'
163
+ # set to false only if you want to make :gearbox_extra an opt-in variable
164
+ # Pagy::DEFAULT[:gearbox_extra] = false # default true
165
+ # Pagy::DEFAULT[:gearbox_items] = [15, 30, 60, 100] # default
166
+
167
+ # Items extra: Allow the client to request a custom number of items per page with an optional selector UI
168
+ # See https://ddnexus.github.io/pagy/extras/items
169
+ # require 'pagy/extras/items'
170
+ # set to false only if you want to make :items_extra an opt-in variable
171
+ # Pagy::DEFAULT[:items_extra] = false # default true
172
+ # Pagy::DEFAULT[:items_param] = :items # default
173
+ # Pagy::DEFAULT[:max_items] = 100 # default
174
+
175
+ # Overflow extra: Allow for easy handling of overflowing pages
176
+ # See https://ddnexus.github.io/pagy/extras/overflow
177
+ # require 'pagy/extras/overflow'
178
+ # Pagy::DEFAULT[:overflow] = :empty_page # default (other options: :last_page and :exception)
179
+
180
+ # Support extra: Extra support for features like: incremental, infinite, auto-scroll pagination
181
+ # See https://ddnexus.github.io/pagy/extras/support
182
+ # require 'pagy/extras/support'
183
+
184
+ # Trim extra: Remove the page=1 param from links
185
+ # See https://ddnexus.github.io/pagy/extras/trim
186
+ # require 'pagy/extras/trim'
187
+ # set to false only if you want to make :trim_extra an opt-in variable
188
+ # Pagy::DEFAULT[:trim_extra] = false # default true
189
+
190
+ # Standalone extra: Use pagy in non Rack environment/gem
191
+ # See https://ddnexus.github.io/pagy/extras/standalone
192
+ # require 'pagy/extras/standalone'
193
+ # Pagy::DEFAULT[:url] = 'http://www.example.com/subdir' # optional default
194
+
195
+
196
+ # Rails
197
+ # Enable the .js file required by the helpers that use javascript
198
+ # (pagy*_nav_js, pagy*_combo_nav_js, and pagy_items_selector_js)
199
+ # See https://ddnexus.github.io/pagy/extras#javascript
200
+
201
+ # With the asset pipeline
202
+ # Sprockets need to look into the pagy javascripts dir, so add it to the assets paths
203
+ # Rails.application.config.assets.paths << Pagy.root.join('javascripts')
204
+
205
+ # I18n
206
+
207
+ # Pagy internal I18n: ~18x faster using ~10x less memory than the i18n gem
208
+ # See https://ddnexus.github.io/pagy/api/frontend#i18n
209
+ # Notice: No need to configure anything in this section if your app uses only "en"
210
+ # or if you use the i18n extra below
211
+ #
212
+ # Examples:
213
+ # load the "de" built-in locale:
214
+ # Pagy::I18n.load(locale: 'de')
215
+ #
216
+ # load the "de" locale defined in the custom file at :filepath:
217
+ # Pagy::I18n.load(locale: 'de', filepath: 'path/to/pagy-de.yml')
218
+ #
219
+ # load the "de", "en" and "es" built-in locales:
220
+ # (the first passed :locale will be used also as the default_locale)
221
+ # Pagy::I18n.load({ locale: 'de' },
222
+ # { locale: 'en' },
223
+ # { locale: 'es' })
224
+ #
225
+ # load the "en" built-in locale, a custom "es" locale,
226
+ # and a totally custom locale complete with a custom :pluralize proc:
227
+ # (the first passed :locale will be used also as the default_locale)
228
+ # Pagy::I18n.load({ locale: 'en' },
229
+ # { locale: 'es', filepath: 'path/to/pagy-es.yml' },
230
+ # { locale: 'xyz', # not built-in
231
+ # filepath: 'path/to/pagy-xyz.yml',
232
+ # pluralize: lambda{ |count| ... } )
233
+
234
+
235
+ # I18n extra: uses the standard i18n gem which is ~18x slower using ~10x more memory
236
+ # than the default pagy internal i18n (see above)
237
+ # See https://ddnexus.github.io/pagy/extras/i18n
238
+ # require 'pagy/extras/i18n'
239
+
240
+ # Default i18n key
241
+ # Pagy::DEFAULT[:i18n_key] = 'pagy.item_name' # default
242
+
243
+
244
+ # When you are done setting your own default freeze it, so it will not get changed accidentally
245
+ Pagy::DEFAULT.freeze
246
+
@@ -0,0 +1,13 @@
1
+ Ransack.configure do |config|
2
+ config.add_predicate 'from_date',
3
+ arel_predicate: 'gteq',
4
+ formatter: proc { |v| v.beginning_of_day },
5
+ validator: proc { |v| v.present? },
6
+ type: :date
7
+
8
+ config.add_predicate 'to_date',
9
+ arel_predicate: 'lteq',
10
+ formatter: proc { |v| v.end_of_day },
11
+ validator: proc { |v| v.present? },
12
+ type: :date
13
+ end
@@ -0,0 +1,65 @@
1
+ # Additional translations at https://github.com/heartcombo/devise/wiki/I18n
2
+
3
+ en:
4
+ devise:
5
+ confirmations:
6
+ confirmed: "Your email address has been successfully confirmed."
7
+ send_instructions: "You will receive an email with instructions for how to confirm your email address in a few minutes."
8
+ send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes."
9
+ failure:
10
+ already_authenticated: "You are already signed in."
11
+ inactive: "Your account is not activated yet."
12
+ invalid: "Invalid %{authentication_keys} or password."
13
+ locked: "Your account is locked."
14
+ last_attempt: "You have one more attempt before your account is locked."
15
+ not_found_in_database: "Invalid %{authentication_keys} or password."
16
+ timeout: "Your session expired. Please sign in again to continue."
17
+ unauthenticated: "You need to sign in or sign up before continuing."
18
+ unconfirmed: "You have to confirm your email address before continuing."
19
+ mailer:
20
+ confirmation_instructions:
21
+ subject: "Confirmation instructions"
22
+ reset_password_instructions:
23
+ subject: "Reset password instructions"
24
+ unlock_instructions:
25
+ subject: "Unlock instructions"
26
+ email_changed:
27
+ subject: "Email Changed"
28
+ password_change:
29
+ subject: "Password Changed"
30
+ omniauth_callbacks:
31
+ failure: "Could not authenticate you from %{kind} because \"%{reason}\"."
32
+ success: "Successfully authenticated from %{kind} account."
33
+ passwords:
34
+ no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided."
35
+ send_instructions: "You will receive an email with instructions on how to reset your password in a few minutes."
36
+ send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
37
+ updated: "Your password has been changed successfully. You are now signed in."
38
+ updated_not_active: "Your password has been changed successfully."
39
+ registrations:
40
+ destroyed: "Bye! Your account has been successfully cancelled. We hope to see you again soon."
41
+ signed_up: "Welcome! You have signed up successfully."
42
+ signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated."
43
+ signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked."
44
+ signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account."
45
+ update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirmation link to confirm your new email address."
46
+ updated: "Your account has been updated successfully."
47
+ updated_but_not_signed_in: "Your account has been updated successfully, but since your password was changed, you need to sign in again."
48
+ sessions:
49
+ signed_in: "Signed in successfully."
50
+ signed_out: "Signed out successfully."
51
+ already_signed_out: "Signed out successfully."
52
+ unlocks:
53
+ send_instructions: "You will receive an email with instructions for how to unlock your account in a few minutes."
54
+ send_paranoid_instructions: "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes."
55
+ unlocked: "Your account has been unlocked successfully. Please sign in to continue."
56
+ errors:
57
+ messages:
58
+ already_confirmed: "was already confirmed, please try signing in"
59
+ confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one"
60
+ expired: "has expired, please request a new one"
61
+ not_found: "not found"
62
+ not_locked: "was not locked"
63
+ not_saved:
64
+ one: "1 error prohibited this %{resource} from being saved:"
65
+ other: "%{count} errors prohibited this %{resource} from being saved:"
data/config/routes.rb ADDED
@@ -0,0 +1,3 @@
1
+ Tybo::Engine.routes.draw do
2
+ root to: 'login#home'
3
+ end
@@ -0,0 +1,12 @@
1
+ Description:
2
+ Create CRUD views for a model
3
+ `rails g bo BlogPost`
4
+ By default it create views in the administrators namespace
5
+ Example:
6
+ `rails g bo BlogPost --namespace employers`
7
+ This will create:
8
+ - CRUD views
9
+ - CRUD controllers
10
+ - Base filters on index pages
11
+ - base routes
12
+ - base seeds
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ class BoGenerator < Rails::Generators::NamedBase
4
+ source_root File.expand_path('templates', __dir__)
5
+ require_relative "./utils/translations.rb"
6
+
7
+ check_class_collision suffix: 'bo'
8
+ class_option :namespace, type: :string, default: 'administrators'
9
+ def create_bo_file
10
+ # Template method
11
+ # First argument is the name of the template
12
+ # Second argument is where to create the resulting file. In this case, app/bo/my_bo.rb
13
+ template 'new.html.erb', File.join("app/views/#{options[:namespace]}", "#{plural_name}/new.html.erb")
14
+ template 'item.html.erb', File.join("app/views/#{options[:namespace]}", "#{plural_name}/_#{file_name.underscore}.html.erb")
15
+ template '_form.html.erb', File.join("app/views/#{options[:namespace]}", "#{plural_name}/_form.html.erb")
16
+ template 'index.html.erb', File.join("app/views/#{options[:namespace]}", "#{plural_name}/index.html.erb")
17
+ template '_table.html.erb', File.join("app/views/#{options[:namespace]}", "#{plural_name}/_table.html.erb")
18
+ template '_search_bar.html.erb', File.join("app/views/#{options[:namespace]}", "#{plural_name}/_search_bar.html.erb")
19
+ template 'show.html.erb', File.join("app/views/#{options[:namespace]}", "#{plural_name}/show.html.erb")
20
+ template 'controller.rb', File.join("app/controllers/#{options[:namespace]}", "#{plural_name}_controller.rb")
21
+ create_translations
22
+ end
23
+
24
+ def bo_model
25
+ class_name.constantize
26
+ end
27
+
28
+ def plural_name
29
+ file_name.pluralize
30
+ end
31
+
32
+ def create_routes
33
+ inject_into_file 'config/routes.rb', after: " namespace :#{options[:namespace]} do\n" do
34
+ " resources :#{plural_name} \n"
35
+ end
36
+ end
37
+
38
+ def model_columns
39
+ bo_model.column_names.map(&:to_sym)
40
+ end
41
+
42
+ def bo_model_title(model=nil)
43
+ return unless model
44
+
45
+ (%i[title name email id] & model.column_names.map(&:to_sym)).first
46
+ end
47
+
48
+ def excluded_columns
49
+ %i[id created_at updated_at]
50
+ end
51
+
52
+ def permited_params
53
+ params = {}
54
+ action_text_columns= has_one_assoc&.select {|a| a.name == :rich_text_content}
55
+ model_columns&.map do |col|
56
+ params["#{col}".to_sym] = nil
57
+ end
58
+ action_text_columns&.map do |col|
59
+ params["#{col.name.to_s.remove('rich_text_' )}".to_sym] = nil
60
+ end
61
+ has_many_assoc&.map do |association|
62
+ params["#{association.class_name.underscore}_ids".to_sym] = []
63
+ end
64
+ params
65
+ end
66
+
67
+ def has_many_assoc
68
+ bo_model.reflect_on_all_associations(:has_many)
69
+ end
70
+
71
+ def belongs_to_assoc
72
+ bo_model.reflect_on_all_associations(:belongs_to)
73
+ end
74
+
75
+ def has_one_assoc
76
+ bo_model.reflect_on_all_associations(:has_one)
77
+ end
78
+
79
+ def permited_columns
80
+ model_columns - excluded_columns
81
+ end
82
+
83
+ def add_link_to_side_bar
84
+ inject_into_file "app/views/#{options[:namespace]}/layouts/_side_bar.html.erb", before: " <%= sidebar.with_current_user_card(user: current_#{options[:namespace].singularize}) %>\n" do
85
+ " <%= sidebar.with_item(path: #{options[:namespace]}_#{plural_name}_path, icon: Icons::UsersComponent, label: I18n.t('bo.#{file_name}.others').capitalize) %>\n"
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,32 @@
1
+ <%%= simple_form_for [:<%= options[:namespace] %>, <%= class_name.underscore %>], html: { class: "<%= class_name.underscore %> form" } do |f| %>
2
+ <!-- Model columns -->
3
+ <%- bo_model.column_names.each do |column| -%>
4
+ <%- next if excluded_columns.include?(column.to_sym) || bo_model.reflect_on_all_associations.map(&:foreign_key).include?(column) -%>
5
+ <%%= f.input :<%= column %> %>
6
+ <%- end -%>
7
+ <!-- belongs_to Associations -->
8
+ <%- belongs_to_assoc.each do |association| -%>
9
+ <%%= f.association :<%= association.name %>, collection: <%= association.class_name %>.all.map { |item| [item.<%=bo_model_title(association.class_name.constantize)%>, item.id] } %>
10
+ <%- end -%>
11
+ <!-- has_one Associations -->
12
+ <%- has_one_assoc.each do |association| -%>
13
+ <%- if association.options[:class_name] == "ActionText::RichText" -%>
14
+ <%%= f.rich_text_area :<%= association.name.to_s.remove('rich_text_' )%> %>
15
+ <%- else -%>
16
+ <%%= f.input :<%= association.foreign_key %>, collection: <%= association.class_name %>.all.map { |item| [item.<%=bo_model_title(association.class_name.constantize)%>, item.id] } %>
17
+ <%- end -%>
18
+ <%- end -%>
19
+
20
+ <!-- has_many Associations -->
21
+ <%- has_many_assoc.each do |association| -%>
22
+ <div class="my-5 select">
23
+ <label class="block text-sm font-medium text-gray-700 string optional text-sm font-medium text-gray-600" for="<%= "#{class_name.underscore}_#{association.class_name.underscore}_ids" %>"><%= association.class_name.underscore%></label>
24
+ <%%= f.select :<%= "#{association.class_name.underscore}_ids" %>,
25
+ <%= association.class_name %>.all.map { |item| [item.<%=bo_model_title(association.class_name.constantize)%>, item.id] },
26
+ { include_blank: true },
27
+ multiple: true,
28
+ data: { controller: 'ts--select' } %>
29
+ </div>
30
+ <%- end -%>
31
+ <%%= render(Forms::SubmitButtonComponent.new) %>
32
+ <%% end %>
@@ -0,0 +1,96 @@
1
+ <div class="relative inline-block text-left" data-controller="dropdown">
2
+ <div>
3
+ <button data-action="click->dropdown#toggle click@window->dropdown#hide" type="button" class="inline-flex w-full justify-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none " id="menu-button" aria-expanded="true" aria-haspopup="true">
4
+ <%%= I18n.t('bo.filters') %>
5
+ <svg class="-mr-1 ml-2 h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
6
+ <path fill-rule="evenodd" d="M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z" clip-rule="evenodd" />
7
+ </svg>
8
+ </button>
9
+ </div>
10
+ <div data-dropdown-target="menu" class="drop-shadow-md hidden absolute py-5 px-5 left-0 z-10 mt-2 w-[40rem] origin-top-right rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none" role="menu" aria-orientation="vertical" aria-labelledby="menu-button" tabindex="-1">
11
+ <%%= search_form_for [:<%=options[:namespace].underscore %>, @q], method: :post, class: "", data: { controller: "search-form", search_form_target: "form", turbo_frame: '<%=class_name.underscore.pluralize%>' } do |f| %>
12
+ <%- bo_model.columns.group_by(&:type).each do |type| -%>
13
+ <!-- columns -->
14
+ <%- type.second.sort_by(&:type).each do |col| -%>
15
+ <%- next if bo_model.reflect_on_all_associations.map(&:foreign_key).include?(col.name) -%>
16
+ <%- if col.type == :string || col.type == :text -%>
17
+ <div class="sm:grid sm:grid-cols-3 sm:items-start sm:gap-4 pt-5">
18
+ <label class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2">
19
+ <%%= I18n.t('bo.<%= class_name.underscore %>.attributes.<%= col.name %>') %>
20
+ </label>
21
+ <div class="mt-1 sm:col-span-2 sm:mt-0">
22
+ <%%= f.text_field :<%= col.name %>_cont, placeholder: I18n.t('bo.<%= class_name.underscore %>.attributes.<%= col.name %>'), data: { action: "input->search-form#search" }, class: "block w-full max-w-lg rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:max-w-xs sm:text-sm" %>
23
+ </div>
24
+ </div>
25
+ <%- elsif col.type ==:integer -%>
26
+ <div class="sm:grid sm:grid-cols-3 sm:items-start sm:gap-4 pt-5">
27
+ <label class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2">
28
+ <%%= I18n.t('bo.<%= class_name.underscore %>.attributes.<%= col.name %>') %>
29
+ </label>
30
+ <div class="mt-1 sm:col-span-2 sm:mt-0">
31
+ <%%= f.number_field :<%= col.name %>_eq, placeholder: I18n.t('bo.<%= class_name.underscore %>.attributes.<%= col.name %>'), data: { action: "input->search-form#search" }, class: "block w-full max-w-lg rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:max-w-xs sm:text-sm" %>
32
+ </div>
33
+ </div>
34
+ <%- elsif col.type == :boolean -%>
35
+ <div class="sm:grid sm:grid-cols-3 sm:items-start sm:gap-4 pt-5">
36
+ <label class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2">
37
+ <%%= I18n.t('bo.<%= class_name.underscore %>.attributes.<%= col.name %>') %>
38
+ </label>
39
+ <div class="mt-1 sm:col-span-2 sm:mt-0">
40
+ <span class="isolate inline-flex rounded-md shadow-sm">
41
+ <button type="button"
42
+ data-target-id='q_<%= col.name %>_eq'
43
+ data-action="click->search-form#setBooleanField"
44
+ class="relative inline-flex items-center rounded-l-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 focus:z-10 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500">
45
+ -
46
+ </button>
47
+ <button type="button"
48
+ data-action="click->search-form#setBooleanField"
49
+ data-value='true'
50
+ data-target-id='q_<%= col.name %>_eq'
51
+ class="relative inline-flex items-center rounded-l-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 focus:z-10 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500">ON
52
+ </button>
53
+ <button type="button"
54
+ data-action="click->search-form#setBooleanField"
55
+ data-value='false'
56
+ data-target-id='q_<%= col.name %>_eq'
57
+ class="relative inline-flex items-center rounded-l-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 focus:z-10 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500">OFF</button>
58
+ </span>
59
+ <%%= f.hidden_field :<%= col.name %>_eq, value: nil, data: { action: "change->search-form#search"}%>
60
+ </div>
61
+ </div>
62
+ <%- elsif col.type == :datetime || col.type == :date -%>
63
+ <div class="sm:grid sm:grid-cols-12 sm:items-start sm:gap-4 pt-5">
64
+ <div class="mt-1 sm:col-span-4 sm:mt-">
65
+ <label class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2">
66
+ <%%= I18n.t('bo.<%= class_name.underscore %>.attributes.<%= col.name %>') %>
67
+ </label>
68
+ </div>
69
+ <div class="mt-1 sm:col-span-3 sm:mt-0">
70
+ <%%= f.date_field :<%= col.name %>_from_date, data: { action: "input->search-form#search" }, class: "rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" %>
71
+ </div>
72
+ <div class="mt-1 sm:col-span-2 text-center">
73
+ to
74
+ </div>
75
+ <div class="mt-1 sm:col-span-3 sm:mt-0">
76
+ <%%= f.date_field :<%= col.name %>_to_date, data: { action: "input->search-form#search" }, class: "rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" %>
77
+ </div>
78
+ </div>
79
+ <%- end -%>
80
+ <%- end -%>
81
+ <%- end -%>
82
+ <!-- belongs_to Associations -->
83
+ <%- belongs_to_assoc.each do |association| -%>
84
+ <div class="sm:grid sm:grid-cols-3 sm:items-start sm:gap-4 pt-5">
85
+ <label for="<%=association.name%>" class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2">
86
+ <%%=I18n.t('bo.<%=association.klass.name.underscore%>.one')%>
87
+ </label>
88
+ <div class="mt-1 sm:col-span-2 sm:mt-0">
89
+ <%%= f.select :<%= association.foreign_key %>_eq, <%=association.klass.name.constantize%>.all.map { |value| [value.<%=bo_model_title(association.class_name.constantize)%>, value.id] }, { include_blank: true }, { class: "block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm", data: { action: "input->search-form#search" } } %>
90
+ </div>
91
+ </div>
92
+ <%- end -%>
93
+ <%% end %>
94
+ </div>
95
+ </div>
96
+
@@ -0,0 +1,29 @@
1
+ <%%= render(Tables::TableComponent.new) do |table| %>
2
+ <%% table.with_thead do |thead| %>
3
+ <%- bo_model.column_names.each do |column| -%>
4
+ <%%= thead.with_active_record_th(column_name: '<%= column %>', ransack_object: @q) %>
5
+ <%- end -%>
6
+ <%% end %>
7
+
8
+ <%% table.with_tbody do |tbody| %>
9
+ <%% @<%= class_name.underscore.pluralize %>&.each_with_index do |<%= class_name.underscore %>, i| %>
10
+ <%%= tbody.with_tr(index: i) do |tr| %>
11
+ <%- bo_model.column_names.each do |column| -%>
12
+ <%%= tr.with_td { <%= class_name.underscore %>.<%= column %>.to_s } -%>
13
+ <%- end -%>
14
+ <%%= tr.with_td do %>
15
+ <%%= link_to <%="#{options[:namespace]}_#{class_name.underscore}_path(#{class_name.underscore})"%>, class: "text-indigo-600 hover:text-indigo-900" do %>
16
+ Détails
17
+ <%% end %>
18
+ <%% end %>
19
+ <%%= tr.with_td do %>
20
+ <%%= link_to <%="#{options[:namespace]}_#{class_name.underscore}_path(#{class_name.underscore})"%>,
21
+ class: "text-indigo-600 hover:text-indigo-900",
22
+ data: {turbo_method: :delete, turbo_confirm: "êtes vous sur ?"} do %>
23
+ <%%= render(Icons::TrashComponent.new) %>
24
+ <%% end %>
25
+ <%% end %>
26
+ <%% end %>
27
+ <%% end %>
28
+ <%% end %>
29
+ <%% end %>
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module <%= options[:namespace].camelize %>
4
+ class <%= class_name.pluralize %>Controller < <%= options[:namespace].singularize.camelize %>Controller
5
+ before_action :set_<%= class_name.underscore %>, only: %i[show edit destroy update]
6
+
7
+ def index
8
+ @q = <%=class_name%>.ransack(params[:q])
9
+ @pagy, @<%= class_name.pluralize.underscore %> = pagy(@q.result(distinct: true))
10
+ end
11
+
12
+ def show; end
13
+
14
+ def new
15
+ @<%= class_name.underscore %> = <%= class_name %>.new
16
+ end
17
+
18
+ def create
19
+ @<%= class_name.underscore %> = <%= class_name %>.new(<%= class_name.underscore %>_params)
20
+
21
+ if @<%= class_name.underscore %>.save
22
+ flash[:success] = t('bo.record.created')
23
+ redirect_to <%="#{options[:namespace]}_#{class_name.underscore.pluralize}_path"%>
24
+
25
+ else
26
+ render :new, status: :unprocessable_entity
27
+ end
28
+ end
29
+
30
+ def edit; end
31
+
32
+ def update
33
+ if @<%= class_name.underscore %>.update(<%= class_name.underscore %>_params)
34
+ flash[:success] = t('bo.record.updated')
35
+ redirect_to <%="#{options[:namespace]}_#{class_name.underscore}_path"%>
36
+ else
37
+ render :show, status: :unprocessable_entity
38
+ end
39
+ end
40
+
41
+ def destroy
42
+ @<%= class_name.underscore %>.destroy
43
+ flash[:success] = t('bo.record.destroyed')
44
+
45
+ redirect_to <%="#{options[:namespace]}_#{class_name.underscore.pluralize}_path"%>, status: :see_other
46
+ end
47
+
48
+ private
49
+
50
+ def set_<%= class_name.underscore %>
51
+ @<%= class_name.underscore %> = <%= class_name %>.find(params[:id])
52
+ end
53
+
54
+ def <%= class_name.underscore %>_params
55
+ params.require(:<%= class_name.underscore %>).permit(
56
+ <%-permited_params.each_with_index do |(key, value), index| -%>
57
+ <%- if value.nil? -%>
58
+ :<%= key %><%=permited_params.count == (index +1) ? '' : ',' %>
59
+ <%- else -%>
60
+ <%= "#{key}: []" %><%=permited_params.count == (index +1) ? '' : ',' %>
61
+ <%- end -%>
62
+ <%- end -%>
63
+ )
64
+ end
65
+ end
66
+ end