uchi 0.1.2 → 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.
- checksums.yaml +4 -4
- data/README.md +222 -0
- data/app/assets/config/uchi_manifest.js +2 -0
- data/app/assets/javascripts/uchi/application.js +6095 -0
- data/app/assets/javascripts/uchi.js +4 -0
- data/app/assets/stylesheets/uchi/application.css +3971 -0
- data/app/assets/stylesheets/uchi/uchi.css +17 -0
- data/app/assets/tailwind/uchi.css +21 -0
- data/app/components/flowbite/breadcrumb.rb +33 -0
- data/app/components/flowbite/breadcrumb_home.rb +26 -0
- data/app/components/flowbite/breadcrumb_item/current.rb +33 -0
- data/app/components/flowbite/breadcrumb_item/first.rb +35 -0
- data/app/components/flowbite/breadcrumb_item.rb +48 -0
- data/app/components/flowbite/breadcrumb_separator.rb +30 -0
- data/app/components/flowbite/button/outline.rb +22 -0
- data/app/components/flowbite/button/pill.rb +40 -0
- data/app/components/flowbite/button.rb +92 -0
- data/app/components/flowbite/card.rb +45 -0
- data/app/components/flowbite/input/checkbox.rb +73 -0
- data/app/components/flowbite/input/date.rb +11 -0
- data/app/components/flowbite/input/date_time.rb +11 -0
- data/app/components/flowbite/input/email.rb +12 -0
- data/app/components/flowbite/input/field.rb +117 -0
- data/app/components/flowbite/input/file.rb +30 -0
- data/app/components/flowbite/input/hint.rb +57 -0
- data/app/components/flowbite/input/label.rb +82 -0
- data/app/components/flowbite/input/number.rb +11 -0
- data/app/components/flowbite/input/password.rb +11 -0
- data/app/components/flowbite/input/phone.rb +11 -0
- data/app/components/flowbite/input/radio_button.rb +50 -0
- data/app/components/flowbite/input/select.rb +49 -0
- data/app/components/flowbite/input/textarea.rb +42 -0
- data/app/components/flowbite/input/url.rb +12 -0
- data/app/components/flowbite/input/validation_error.rb +11 -0
- data/app/components/flowbite/input_field/checkbox.html.erb +14 -0
- data/app/components/flowbite/input_field/checkbox.rb +54 -0
- data/app/components/flowbite/input_field/date.rb +13 -0
- data/app/components/flowbite/input_field/date_time.rb +13 -0
- data/app/components/flowbite/input_field/email.rb +13 -0
- data/app/components/flowbite/input_field/file.rb +13 -0
- data/app/components/flowbite/input_field/input_field.html.erb +8 -0
- data/app/components/flowbite/input_field/number.rb +13 -0
- data/app/components/flowbite/input_field/password.rb +13 -0
- data/app/components/flowbite/input_field/phone.rb +13 -0
- data/app/components/flowbite/input_field/radio_button.html.erb +14 -0
- data/app/components/flowbite/input_field/radio_button.rb +86 -0
- data/app/components/flowbite/input_field/select.rb +31 -0
- data/app/components/flowbite/input_field/text.rb +8 -0
- data/app/components/flowbite/input_field/textarea.rb +13 -0
- data/app/components/flowbite/input_field/url.rb +13 -0
- data/app/components/flowbite/input_field.rb +192 -0
- data/app/components/flowbite/link.rb +21 -0
- data/app/components/flowbite/style.rb +13 -0
- data/app/components/flowbite/toast/icon.html.erb +5 -0
- data/app/components/flowbite/toast/icon.rb +57 -0
- data/app/components/flowbite/toast/toast.html.erb +11 -0
- data/app/components/flowbite/toast.rb +34 -0
- data/app/components/uchi/field/base.rb +57 -0
- data/app/components/uchi/field/belongs_to/edit.html.erb +1 -0
- data/app/components/uchi/field/belongs_to/index.html.erb +1 -0
- data/app/components/uchi/field/belongs_to/show.html.erb +3 -0
- data/app/components/uchi/field/belongs_to.rb +105 -0
- data/app/components/uchi/field/blank/edit.html.erb +1 -0
- data/app/components/uchi/field/blank/index.html.erb +1 -0
- data/app/components/uchi/field/blank/show.html.erb +1 -0
- data/app/components/uchi/field/blank.rb +16 -0
- data/app/components/uchi/field/boolean/edit.html.erb +1 -0
- data/app/components/uchi/field/boolean/index.html.erb +9 -0
- data/app/components/uchi/field/boolean/show.html.erb +9 -0
- data/app/components/uchi/field/boolean.rb +27 -0
- data/app/components/uchi/field/date/edit.html.erb +1 -0
- data/app/components/uchi/field/date/index.html.erb +1 -0
- data/app/components/uchi/field/date/show.html.erb +1 -0
- data/app/components/uchi/field/date.rb +27 -0
- data/app/components/uchi/field/date_time/edit.html.erb +1 -0
- data/app/components/uchi/field/date_time/index.html.erb +1 -0
- data/app/components/uchi/field/date_time/show.html.erb +1 -0
- data/app/components/uchi/field/date_time.rb +27 -0
- data/app/components/uchi/field/file/edit.html.erb +1 -0
- data/app/components/uchi/field/file/index.html.erb +6 -0
- data/app/components/uchi/field/file/show.html.erb +8 -0
- data/app/components/uchi/field/file.rb +37 -0
- data/app/components/uchi/field/has_and_belongs_to_many/edit.html.erb +9 -0
- data/app/components/uchi/field/has_and_belongs_to_many/index.html.erb +1 -0
- data/app/components/uchi/field/has_and_belongs_to_many/show.html.erb +28 -0
- data/app/components/uchi/field/has_and_belongs_to_many.rb +131 -0
- data/app/components/uchi/field/has_many/edit.html.erb +1 -0
- data/app/components/uchi/field/has_many/index.html.erb +1 -0
- data/app/components/uchi/field/has_many/show.html.erb +28 -0
- data/app/components/uchi/field/has_many.rb +107 -0
- data/app/components/uchi/field/id/index.html.erb +4 -0
- data/app/components/uchi/field/id/show.html.erb +4 -0
- data/app/components/uchi/field/id.rb +26 -0
- data/app/components/uchi/field/image/edit.html.erb +1 -0
- data/app/components/uchi/field/image/index.html.erb +6 -0
- data/app/components/uchi/field/image/show.html.erb +6 -0
- data/app/components/uchi/field/image.rb +38 -0
- data/app/components/uchi/field/number/edit.html.erb +1 -0
- data/app/components/uchi/field/number/index.html.erb +1 -0
- data/app/components/uchi/field/number/show.html.erb +1 -0
- data/app/components/uchi/field/number.rb +32 -0
- data/app/components/uchi/field/string/edit.html.erb +1 -0
- data/app/components/uchi/field/string/index.html.erb +1 -0
- data/app/components/uchi/field/string/show.html.erb +1 -0
- data/app/components/uchi/field/string.rb +33 -0
- data/app/components/uchi/field/text/edit.html.erb +1 -0
- data/app/components/uchi/field/text/index.html.erb +1 -0
- data/app/components/uchi/field/text/show.html.erb +1 -0
- data/app/components/uchi/field/text.rb +38 -0
- data/app/components/uchi/ui/breadcrumb/breadcrumb.html.erb +13 -0
- data/app/components/uchi/ui/breadcrumb.rb +14 -0
- data/app/components/uchi/ui/form/footer/footer.html.erb +5 -0
- data/app/components/uchi/ui/form/footer.rb +15 -0
- data/app/components/uchi/ui/form/input/collection_checkboxes.html.erb +32 -0
- data/app/components/uchi/ui/form/input/collection_checkboxes.rb +125 -0
- data/app/components/uchi/ui/frame/frame.html.erb +3 -0
- data/app/components/uchi/ui/frame.rb +10 -0
- data/app/components/uchi/ui/index/records_table/records_table.html.erb +67 -0
- data/app/components/uchi/ui/index/records_table/search_form/search_form.html.erb +21 -0
- data/app/components/uchi/ui/index/records_table/search_form.rb +49 -0
- data/app/components/uchi/ui/index/records_table.rb +29 -0
- data/app/components/uchi/ui/index/turbo_frame.rb +50 -0
- data/app/components/uchi/ui/page_header/page_header.html.erb +24 -0
- data/app/components/uchi/ui/page_header.rb +18 -0
- data/app/components/uchi/ui/pagination/current_link.html.erb +3 -0
- data/app/components/uchi/ui/pagination/current_link.rb +10 -0
- data/app/components/uchi/ui/pagination/gap.html.erb +3 -0
- data/app/components/uchi/ui/pagination/gap.rb +10 -0
- data/app/components/uchi/ui/pagination/item.rb +24 -0
- data/app/components/uchi/ui/pagination/link.html.erb +3 -0
- data/app/components/uchi/ui/pagination/link.rb +10 -0
- data/app/components/uchi/ui/pagination/next_link.html.erb +8 -0
- data/app/components/uchi/ui/pagination/next_link.rb +22 -0
- data/app/components/uchi/ui/pagination/pagination.html.erb +15 -0
- data/app/components/uchi/ui/pagination/previous_link.html.erb +8 -0
- data/app/components/uchi/ui/pagination/previous_link.rb +22 -0
- data/app/components/uchi/ui/pagination.rb +48 -0
- data/app/components/uchi/ui/show/attribute_fields/attribute_fields.html.erb +14 -0
- data/app/components/uchi/ui/show/attribute_fields.rb +18 -0
- data/app/components/uchi/ui/spinner/spinner.html.erb +7 -0
- data/app/components/uchi/ui/spinner.rb +15 -0
- data/app/controllers/uchi/application_controller.rb +4 -0
- data/app/controllers/uchi/controller.rb +13 -0
- data/app/controllers/uchi/repository_controller.rb +166 -0
- data/app/helpers/uchi/application_helper.rb +17 -0
- data/app/jobs/uchi/application_job.rb +4 -0
- data/app/mailers/uchi/application_mailer.rb +6 -0
- data/app/views/layouts/uchi/_flash_messages.html.erb +10 -0
- data/app/views/layouts/uchi/application.html.erb +33 -0
- data/app/views/uchi/repository/edit.html.erb +40 -0
- data/app/views/uchi/repository/index.html.erb +49 -0
- data/app/views/uchi/repository/new.html.erb +37 -0
- data/app/views/uchi/repository/show.html.erb +41 -0
- data/lib/generators/uchi/controller/controller_generator.rb +16 -0
- data/lib/generators/uchi/controller/templates/controller.rb.tt +11 -0
- data/lib/generators/uchi/install/install_generator.rb +13 -0
- data/lib/generators/uchi/repository/repository_generator.rb +16 -0
- data/lib/generators/uchi/repository/templates/repository.rb.tt +11 -0
- data/lib/tasks/uchi_tasks.rake +4 -0
- data/lib/uchi/application_record.rb +5 -0
- data/lib/uchi/engine.rb +24 -0
- data/lib/uchi/field/configuration.rb +142 -0
- data/lib/uchi/field.rb +80 -0
- data/lib/uchi/i18n.rb +13 -0
- data/lib/uchi/pagination/controller.rb +26 -0
- data/lib/uchi/pagination/page.rb +20 -0
- data/lib/uchi/pagy/LICENSE.txt +21 -0
- data/lib/uchi/pagy/classes/exceptions.rb +35 -0
- data/lib/uchi/pagy/classes/offset/offset.rb +56 -0
- data/lib/uchi/pagy/classes/request.rb +38 -0
- data/lib/uchi/pagy/modules/abilities/configurable.rb +38 -0
- data/lib/uchi/pagy/modules/abilities/linkable.rb +62 -0
- data/lib/uchi/pagy/modules/abilities/rangeable.rb +17 -0
- data/lib/uchi/pagy/modules/abilities/shiftable.rb +14 -0
- data/lib/uchi/pagy/modules/console.rb +40 -0
- data/lib/uchi/pagy/toolbox/helpers/loader.rb +19 -0
- data/lib/uchi/pagy/toolbox/helpers/page_url.rb +25 -0
- data/lib/uchi/pagy/toolbox/paginators/method.rb +21 -0
- data/lib/uchi/pagy/toolbox/paginators/offset.rb +35 -0
- data/lib/uchi/pagy.rb +60 -0
- data/lib/uchi/repository/routes.rb +62 -0
- data/lib/uchi/repository/translate.rb +284 -0
- data/lib/uchi/repository.rb +156 -0
- data/lib/uchi/sort_order.rb +35 -0
- data/lib/uchi/version.rb +5 -0
- data/lib/uchi.rb +18 -0
- data/uchi.gemspec +35 -0
- metadata +197 -107
- data/.github/dependabot.yml +0 -17
- data/.github/workflows/build.yml +0 -23
- data/.github/workflows/lint.yml +0 -30
- data/package.json +0 -31
- data/sig/uchi.rbs +0 -4
- data/test/components/uchi/field/belongs_to_test.rb +0 -134
- data/test/components/uchi/field/blank_test.rb +0 -119
- data/test/components/uchi/field/boolean_test.rb +0 -163
- data/test/components/uchi/field/date_test.rb +0 -163
- data/test/components/uchi/field/date_time_test.rb +0 -152
- data/test/components/uchi/field/has_many_test.rb +0 -138
- data/test/components/uchi/field/id_test.rb +0 -113
- data/test/components/uchi/field/number_test.rb +0 -163
- data/test/components/uchi/field/string_test.rb +0 -159
- data/test/controllers/uchi/authors_controller_test.rb +0 -119
- data/test/controllers/uchi/repository_controller_test.rb +0 -93
- data/test/controllers/uchi/scoped_repository_controller_test.rb +0 -73
- data/test/dummy/Rakefile +0 -6
- data/test/dummy/app/assets/images/.keep +0 -0
- data/test/dummy/app/assets/stylesheets/application.css +0 -15
- data/test/dummy/app/controllers/application_controller.rb +0 -4
- data/test/dummy/app/controllers/concerns/.keep +0 -0
- data/test/dummy/app/controllers/uchi/authors_controller.rb +0 -7
- data/test/dummy/app/controllers/uchi/books_controller.rb +0 -7
- data/test/dummy/app/controllers/uchi/titles_controller.rb +0 -7
- data/test/dummy/app/helpers/application_helper.rb +0 -2
- data/test/dummy/app/jobs/application_job.rb +0 -7
- data/test/dummy/app/mailers/application_mailer.rb +0 -4
- data/test/dummy/app/models/application_record.rb +0 -3
- data/test/dummy/app/models/author.rb +0 -3
- data/test/dummy/app/models/book.rb +0 -3
- data/test/dummy/app/models/concerns/.keep +0 -0
- data/test/dummy/app/models/title.rb +0 -3
- data/test/dummy/app/uchi/repositories/author.rb +0 -20
- data/test/dummy/app/uchi/repositories/book.rb +0 -16
- data/test/dummy/app/uchi/repositories/title.rb +0 -17
- data/test/dummy/app/views/layouts/application.html.erb +0 -27
- data/test/dummy/app/views/layouts/mailer.html.erb +0 -13
- data/test/dummy/app/views/layouts/mailer.text.erb +0 -1
- data/test/dummy/app/views/pwa/manifest.json.erb +0 -22
- data/test/dummy/app/views/pwa/service-worker.js +0 -26
- data/test/dummy/bin/dev +0 -2
- data/test/dummy/bin/rails +0 -4
- data/test/dummy/bin/rake +0 -4
- data/test/dummy/bin/setup +0 -34
- data/test/dummy/config/application.rb +0 -29
- data/test/dummy/config/boot.rb +0 -5
- data/test/dummy/config/cable.yml +0 -10
- data/test/dummy/config/database.yml +0 -32
- data/test/dummy/config/environment.rb +0 -5
- data/test/dummy/config/environments/development.rb +0 -69
- data/test/dummy/config/environments/production.rb +0 -89
- data/test/dummy/config/environments/test.rb +0 -53
- data/test/dummy/config/initializers/content_security_policy.rb +0 -25
- data/test/dummy/config/initializers/filter_parameter_logging.rb +0 -8
- data/test/dummy/config/initializers/inflections.rb +0 -16
- data/test/dummy/config/locales/da.yml +0 -51
- data/test/dummy/config/locales/en.yml +0 -31
- data/test/dummy/config/puma.rb +0 -38
- data/test/dummy/config/routes.rb +0 -9
- data/test/dummy/config/storage.yml +0 -34
- data/test/dummy/config.ru +0 -6
- data/test/dummy/db/migrate/20251002183635_create_authors.rb +0 -11
- data/test/dummy/db/migrate/20251005131726_create_books.rb +0 -9
- data/test/dummy/db/migrate/20251005131811_create_titles.rb +0 -11
- data/test/dummy/db/schema.rb +0 -38
- data/test/dummy/log/.keep +0 -0
- data/test/dummy/public/400.html +0 -114
- data/test/dummy/public/404.html +0 -114
- data/test/dummy/public/406-unsupported-browser.html +0 -114
- data/test/dummy/public/422.html +0 -114
- data/test/dummy/public/500.html +0 -114
- data/test/dummy/public/icon.png +0 -0
- data/test/dummy/public/icon.svg +0 -3
- data/test/dummy/storage/.keep +0 -0
- data/test/dummy/test/fixtures/authors.yml +0 -11
- data/test/dummy/test/models/author_test.rb +0 -7
- data/test/dummy/tmp/.keep +0 -0
- data/test/dummy/tmp/pids/.keep +0 -0
- data/test/dummy/tmp/storage/.keep +0 -0
- data/test/test_helper.rb +0 -15
- data/test/uchi/field_test.rb +0 -63
- data/test/uchi/i18n_test.rb +0 -18
- data/test/uchi/repository/routes_test.rb +0 -49
- data/test/uchi/repository/translate_test.rb +0 -263
- data/test/uchi/repository_test.rb +0 -137
- data/test/uchi/sort_order_test.rb +0 -47
- data/test/uchi_test.rb +0 -7
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Uchi
|
|
4
|
+
module Ui
|
|
5
|
+
class Pagination
|
|
6
|
+
class NextLink < Item
|
|
7
|
+
# Returns true if there is a next page
|
|
8
|
+
def next?
|
|
9
|
+
paginator.next.present?
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def url
|
|
13
|
+
if next?
|
|
14
|
+
page_url(:next)
|
|
15
|
+
else
|
|
16
|
+
page_url(:last)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<nav aria-label="<%= aria_label %>">
|
|
2
|
+
<ul class="flex items-center -space-x-px h-8 text-sm">
|
|
3
|
+
<%= render(Uchi::Ui::Pagination::PreviousLink.new(paginator: @paginator)) %>
|
|
4
|
+
<% pages.each do |page_number| %>
|
|
5
|
+
<% if page_number.nil? %>
|
|
6
|
+
<%= render(Uchi::Ui::Pagination::Gap.new(page_number: page_number, paginator: @paginator)) %>
|
|
7
|
+
<% elsif page_number == @paginator.page %>
|
|
8
|
+
<%= render(Uchi::Ui::Pagination::CurrentLink.new(page_number: page_number, paginator: @paginator)) %>
|
|
9
|
+
<% else %>
|
|
10
|
+
<%= render(Uchi::Ui::Pagination::Link.new(page_number: page_number, paginator: @paginator)) %>
|
|
11
|
+
<% end %>
|
|
12
|
+
<% end %>
|
|
13
|
+
<%= render(Uchi::Ui::Pagination::NextLink.new(paginator: @paginator)) %>
|
|
14
|
+
</ul>
|
|
15
|
+
</nav>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<li>
|
|
2
|
+
<%= link_to(url, class: "flex items-center justify-center px-3 h-8 ms-0 leading-tight text-gray-500 bg-white border border-e-0 border-gray-300 rounded-s-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white") do %>
|
|
3
|
+
<span class="sr-only">Previous</span>
|
|
4
|
+
<svg class="w-3 h-3 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
|
|
5
|
+
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 1 1 5l4 4"/>
|
|
6
|
+
</svg>
|
|
7
|
+
<% end %>
|
|
8
|
+
</li>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Uchi
|
|
4
|
+
module Ui
|
|
5
|
+
class Pagination
|
|
6
|
+
class PreviousLink < Item
|
|
7
|
+
# Returns true if there is a previous page
|
|
8
|
+
def previous?
|
|
9
|
+
paginator.page > 1
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def url
|
|
13
|
+
if previous?
|
|
14
|
+
page_url(:previous)
|
|
15
|
+
else
|
|
16
|
+
page_url(:first)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Uchi
|
|
4
|
+
module Ui
|
|
5
|
+
class Pagination < ViewComponent::Base
|
|
6
|
+
attr_reader :paginator
|
|
7
|
+
|
|
8
|
+
def aria_label
|
|
9
|
+
"Page navigation"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# @param paginator [Pagy::Pagy] The Pagy object
|
|
13
|
+
def initialize(paginator:)
|
|
14
|
+
super()
|
|
15
|
+
@paginator = paginator
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Returns the URL for a given page. page can be a number, of :first,
|
|
19
|
+
# :last, :previous, :next, :current.
|
|
20
|
+
def page_url(page)
|
|
21
|
+
paginator.page_url(page)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Returns an array of page numbers to display in the pagination component
|
|
25
|
+
def pages
|
|
26
|
+
pages = []
|
|
27
|
+
pages += [1]
|
|
28
|
+
pages += (paginator.page - 2..paginator.page + 2).to_a
|
|
29
|
+
pages += [paginator.last]
|
|
30
|
+
pages = pages.select { |page| page.between?(1, paginator.last) }.uniq.sort
|
|
31
|
+
|
|
32
|
+
result = []
|
|
33
|
+
pages.each_with_index do |page, index|
|
|
34
|
+
result << page
|
|
35
|
+
next_page = pages[index + 1]
|
|
36
|
+
if index < pages.size - 1 && next_page - page > 1
|
|
37
|
+
result << nil # Add a gap
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
result
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def render?
|
|
44
|
+
paginator.present?
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<%= render(Uchi::Ui::Frame.new) do %>
|
|
2
|
+
<dl class="divide-y divide-gray-200 dark:divide-white/5">
|
|
3
|
+
<% attribute_fields.each do |field| %>
|
|
4
|
+
<div class="px-4 py-4 sm:grid sm:grid-cols-4 sm:gap-4 sm:px-6">
|
|
5
|
+
<dt class="font-semibold text-gray-900 dark:text-white">
|
|
6
|
+
<%= repository.translate.field_label(field) %>
|
|
7
|
+
</dt>
|
|
8
|
+
<dd class="font-light text-gray-500 dark:text-gray-400 col-span-3">
|
|
9
|
+
<%= render(field.show_component(record: record, repository: repository)) %>
|
|
10
|
+
</dd>
|
|
11
|
+
</div>
|
|
12
|
+
<% end %>
|
|
13
|
+
</dl>
|
|
14
|
+
<% end %>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Uchi
|
|
4
|
+
module Ui
|
|
5
|
+
module Show
|
|
6
|
+
class AttributeFields < ViewComponent::Base
|
|
7
|
+
attr_reader :attribute_fields, :record, :repository
|
|
8
|
+
|
|
9
|
+
def initialize(attribute_fields:, record:, repository:)
|
|
10
|
+
super()
|
|
11
|
+
@attribute_fields = attribute_fields
|
|
12
|
+
@record = record
|
|
13
|
+
@repository = repository
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<div role="status">
|
|
2
|
+
<svg aria-hidden="true" class="w-8 h-8 text-gray-200 animate-spin dark:text-gray-600 fill-blue-600" viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z" fill="currentColor"/>
|
|
4
|
+
<path d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z" fill="currentFill"/>
|
|
5
|
+
</svg>
|
|
6
|
+
<span class="sr-only"><%= message %></span>
|
|
7
|
+
</div>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Uchi
|
|
4
|
+
module Ui
|
|
5
|
+
# https://flowbite.com/docs/components/spinner/
|
|
6
|
+
class Spinner < ViewComponent::Base
|
|
7
|
+
attr_reader :message
|
|
8
|
+
|
|
9
|
+
def initialize(message: "Loading...")
|
|
10
|
+
super()
|
|
11
|
+
@message = message
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "uchi/pagination/controller"
|
|
4
|
+
|
|
5
|
+
module Uchi
|
|
6
|
+
class RepositoryController < Uchi::ApplicationController
|
|
7
|
+
include Uchi::Pagination::Controller
|
|
8
|
+
|
|
9
|
+
before_action :set_repository
|
|
10
|
+
|
|
11
|
+
def create
|
|
12
|
+
@record = build_record
|
|
13
|
+
if @record.save
|
|
14
|
+
flash[:success] = @repository.translate.successful_create
|
|
15
|
+
redirect_to(@repository.routes.path_for(:show, id: @record.id), status: :see_other)
|
|
16
|
+
else
|
|
17
|
+
render :new, status: :unprocessable_entity
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def destroy
|
|
22
|
+
@record = find_record
|
|
23
|
+
if @record.destroy
|
|
24
|
+
flash[:success] = @repository.translate.successful_destroy
|
|
25
|
+
redirect_to(@repository.routes.path_for(:index), status: :see_other)
|
|
26
|
+
else
|
|
27
|
+
flash[:alert] = @repository.translate.failed_destroy
|
|
28
|
+
redirect_to(@repository.routes.path_for(:show, id: @record.id), status: :see_other)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def edit
|
|
33
|
+
@record = find_record
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def index
|
|
37
|
+
if params[:scope]
|
|
38
|
+
# Handle being shown inline in another record's show view
|
|
39
|
+
parent_repository = Uchi::Repository.for_model(params[:scope][:model])&.new
|
|
40
|
+
parent_record = parent_repository.find(params[:scope][:id])
|
|
41
|
+
field_name = params[:scope][:field]
|
|
42
|
+
inverse_of = params[:scope][:inverse_of]&.to_sym
|
|
43
|
+
|
|
44
|
+
@columns = @repository.fields_for_index
|
|
45
|
+
@columns = @columns.reject { |field| field.name == inverse_of } if inverse_of
|
|
46
|
+
@records = find_all_records_from_association(name: field_name, parent_record: parent_record)
|
|
47
|
+
@paginator, @records = paginate(@records, records_per_page: scoped_records_per_page)
|
|
48
|
+
else
|
|
49
|
+
# Handle the normal case
|
|
50
|
+
@columns = @repository.fields_for_index
|
|
51
|
+
@records = find_all_records
|
|
52
|
+
@paginator, @records = paginate(@records, records_per_page: index_records_per_page)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def new
|
|
57
|
+
@record = build_record
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def show
|
|
61
|
+
@record = find_record
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def update
|
|
65
|
+
@record = find_record
|
|
66
|
+
if @record.update(record_params)
|
|
67
|
+
flash[:success] = @repository.translate.successful_update
|
|
68
|
+
redirect_to(@repository.routes.path_for(:show, id: @record.id, uniq: rand), status: :see_other)
|
|
69
|
+
else
|
|
70
|
+
render :edit, status: :unprocessable_entity
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def build_record
|
|
77
|
+
@repository.build(record_params)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Returns the path to use for the cancel link
|
|
81
|
+
helper_method def path_for_cancel(default:)
|
|
82
|
+
return default unless scoped?
|
|
83
|
+
|
|
84
|
+
parent_model_name = scope[:model]
|
|
85
|
+
parent_repository = Uchi::Repository.for_model(parent_model_name)&.new
|
|
86
|
+
raise NameError, "No repository found for scoped model #{parent_model_name}" unless parent_repository
|
|
87
|
+
|
|
88
|
+
parent_model_id = scope[:id]
|
|
89
|
+
parent_repository.routes.path_for(:show, id: parent_model_id)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
helper_method def current_sort_order
|
|
93
|
+
@current_sort_order ||= SortOrder.from_params(params) || @repository.default_sort_order
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def find_all_records(scope: nil)
|
|
97
|
+
@repository
|
|
98
|
+
.find_all(
|
|
99
|
+
scope: scope,
|
|
100
|
+
search: params[:query],
|
|
101
|
+
sort_order: current_sort_order
|
|
102
|
+
)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def find_all_records_from_association(name:, parent_record:)
|
|
106
|
+
association = parent_record.class.reflect_on_association(name.to_sym)
|
|
107
|
+
raise NameError, "No association named #{name} on #{parent_record.class}" unless association
|
|
108
|
+
|
|
109
|
+
source_repository = Uchi::Repository.for_model(association.active_record)&.new
|
|
110
|
+
raise NameError, "No repository found for scoped model #{association.active_record}" unless source_repository
|
|
111
|
+
|
|
112
|
+
associated_repository = Uchi::Repository.for_model(association.klass)&.new
|
|
113
|
+
raise NameError, "No repository found for associated model #{association.klass}" unless associated_repository
|
|
114
|
+
|
|
115
|
+
field = source_repository.fields.find { |f| f.name == name.to_sym }
|
|
116
|
+
raise NameError, "No field named #{name} on #{source_repository.model}" unless field
|
|
117
|
+
|
|
118
|
+
scope = parent_record.association(name.to_sym).scope
|
|
119
|
+
find_all_records(scope: scope)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def find_record
|
|
123
|
+
@record = @repository.find(params[:id])
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Returns the number of records per page to show in index views
|
|
127
|
+
def index_records_per_page
|
|
128
|
+
25
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def record_params
|
|
132
|
+
permitted_params = @repository.fields_for_edit.map(&:permitted_param)
|
|
133
|
+
(params[@repository.model_param_key] || ActionController::Parameters.new)
|
|
134
|
+
.permit(*permitted_params)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def repository_class
|
|
138
|
+
raise NotImplementedError, "Subclasses must implement repository_class"
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
helper_method def scope_params
|
|
142
|
+
if scoped?
|
|
143
|
+
scope.permit(:field, :id, :inverse_of, :model)
|
|
144
|
+
else
|
|
145
|
+
ActionController::Parameters.new
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Returns the scope that we're currently operating within, if any.
|
|
150
|
+
def scope
|
|
151
|
+
params[:scope]
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
helper_method def scoped?
|
|
155
|
+
scope.present?
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def scoped_records_per_page
|
|
159
|
+
5
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def set_repository
|
|
163
|
+
@repository = repository_class.new
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Uchi
|
|
2
|
+
module ApplicationHelper
|
|
3
|
+
# Maps Rails flash types to Flowbite Toast styles
|
|
4
|
+
def flash_style(flash_type)
|
|
5
|
+
case flash_type.to_sym
|
|
6
|
+
when :success
|
|
7
|
+
:success
|
|
8
|
+
when :alert, :error
|
|
9
|
+
:danger
|
|
10
|
+
when :warning
|
|
11
|
+
:warning
|
|
12
|
+
else
|
|
13
|
+
:default
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title><%= content_for?(:page_title) ? yield(:page_title) : "Uchi" %></title>
|
|
5
|
+
<%= csrf_meta_tags %>
|
|
6
|
+
<%= csp_meta_tag %>
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
8
|
+
|
|
9
|
+
<%= javascript_include_tag "uchi/application", "data-turbo-track" => "reload" %>
|
|
10
|
+
<%= stylesheet_link_tag "uchi/application", media: "all", "data-turbo-track": "reload" %>
|
|
11
|
+
</head>
|
|
12
|
+
<body class="antialiased bg-gray-50 dark:bg-gray-900 p-2">
|
|
13
|
+
<div class="md:flex">
|
|
14
|
+
<nav class="w-64 h-full px-3 py-4 overflow-y-auto shrink-0 bg-gray-50 dark:bg-gray-800" aria-label="Main">
|
|
15
|
+
<ul class="space-y-2 font-medium">
|
|
16
|
+
<% Uchi::Repository.all.map { |repository| repository.new }.sort_by { |repository| repository.translate.plural_name.downcase }.each do |repository| %>
|
|
17
|
+
<li>
|
|
18
|
+
<%= link_to(repository.routes.path_for(:index), :class => "flex items-center p-2 text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700 group") do %>
|
|
19
|
+
<span class="ms-3"><%= repository.translate.plural_name.titlecase %></span>
|
|
20
|
+
<% end %>
|
|
21
|
+
</li>
|
|
22
|
+
<% end %>
|
|
23
|
+
</ul>
|
|
24
|
+
</nav>
|
|
25
|
+
|
|
26
|
+
<main class="py-6 overflow-x-hidden grow md:px-6">
|
|
27
|
+
<%= yield %>
|
|
28
|
+
</main>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<%= render "layouts/uchi/flash_messages" %>
|
|
32
|
+
</body>
|
|
33
|
+
</html>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<%- content_for(:page_title) { @repository.translate.title(:edit, record: @record) } %>
|
|
2
|
+
|
|
3
|
+
<%= render(
|
|
4
|
+
Uchi::Ui::PageHeader.new(
|
|
5
|
+
description: @repository.translate.description(:edit),
|
|
6
|
+
title: @repository.translate.title(:edit, record: @record),
|
|
7
|
+
)) do |header| %>
|
|
8
|
+
<% header.with_breadcrumb(items: [
|
|
9
|
+
{href: @repository.routes.root_path, label: Rails.application.name.titlecase },
|
|
10
|
+
{href: @repository.routes.path_for(:index), label: @repository.translate.breadcrumb_label(:index) },
|
|
11
|
+
{href: @repository.routes.path_for(:show, id: @record.id), label: @repository.translate.breadcrumb_label(:show, record: @record) },
|
|
12
|
+
{href: @repository.routes.path_for(:edit, id: @record.id), label: @repository.translate.breadcrumb_label(:edit, record: @record) }
|
|
13
|
+
]) %>
|
|
14
|
+
<% end %>
|
|
15
|
+
|
|
16
|
+
<div class="mx-4 md:mx-0">
|
|
17
|
+
<%= render(Flowbite::Card.new) do %>
|
|
18
|
+
<%= form_with model: @record, url: @repository.routes.path_for(:update, id: @record.id) do |form| %>
|
|
19
|
+
<div class="space-y-6">
|
|
20
|
+
<% @repository.fields_for_edit.each do |field| %>
|
|
21
|
+
<div>
|
|
22
|
+
<%= render(
|
|
23
|
+
field.edit_component(
|
|
24
|
+
form: form,
|
|
25
|
+
repository: @repository,
|
|
26
|
+
label: @repository.translate.field_label(field),
|
|
27
|
+
hint: @repository.translate.field_hint(field)
|
|
28
|
+
)
|
|
29
|
+
) %>
|
|
30
|
+
</div>
|
|
31
|
+
<% end %>
|
|
32
|
+
|
|
33
|
+
<%= render(Uchi::Ui::Form::Footer.new) do |footer| %>
|
|
34
|
+
<%= footer.with_action { render(Flowbite::Button.new) { @repository.translate.submit_button } } %>
|
|
35
|
+
<%= footer.with_action { link_to(@repository.translate.link_to_cancel, path_for_cancel(default: @repository.routes.path_for(:show, id: @record.id))) } %>
|
|
36
|
+
<% end %>
|
|
37
|
+
</div>
|
|
38
|
+
<% end %>
|
|
39
|
+
<% end %>
|
|
40
|
+
</div>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<%- content_for(:page_title) { @repository.translate.title(:index) } %>
|
|
2
|
+
|
|
3
|
+
<%= render(
|
|
4
|
+
Uchi::Ui::PageHeader.new(
|
|
5
|
+
description: @repository.translate.description(:index),
|
|
6
|
+
title: @repository.translate.title(:index),
|
|
7
|
+
)) do |header| %>
|
|
8
|
+
<% header.with_action do %>
|
|
9
|
+
<%= link_to(@repository.translate.link_to_new, @repository.routes.path_for(:new), class: Flowbite::Button.classes) %>
|
|
10
|
+
<% end %>
|
|
11
|
+
<% header.with_breadcrumb(items: [
|
|
12
|
+
{href: @repository.routes.root_path, label: Rails.application.name.titlecase },
|
|
13
|
+
{href: @repository.routes.path_for(:index), label: @repository.translate.breadcrumb_label(:index) }
|
|
14
|
+
]) %>
|
|
15
|
+
<% end %>
|
|
16
|
+
|
|
17
|
+
<div class="mx-0">
|
|
18
|
+
<%= render(Uchi::Ui::Index::TurboFrame.new(
|
|
19
|
+
repository: @repository,
|
|
20
|
+
scope: (scoped? ? scope_params : nil),
|
|
21
|
+
)) do %>
|
|
22
|
+
<div class="relative overflow-x-auto bg-white border border-gray-200 shadow-sm md:rounded-lg dark:bg-gray-800 dark:border-gray-700">
|
|
23
|
+
<% if @repository.searchable? %>
|
|
24
|
+
<div class="px-3 py-3">
|
|
25
|
+
<%= render(Uchi::Ui::Index::RecordsTable::SearchForm.new(params: params, repository: @repository)) %>
|
|
26
|
+
</div>
|
|
27
|
+
<% end %>
|
|
28
|
+
<% if @records.any? %>
|
|
29
|
+
<%= render(Uchi::Ui::Index::RecordsTable.new(
|
|
30
|
+
columns: @columns,
|
|
31
|
+
sort_order: current_sort_order,
|
|
32
|
+
query: params[:query],
|
|
33
|
+
records: @records,
|
|
34
|
+
repository: @repository,
|
|
35
|
+
scope: (scoped? ? scope_params : nil),
|
|
36
|
+
)) %>
|
|
37
|
+
<% else %>
|
|
38
|
+
<div class="p-6 text-center text-gray-500 dark:text-gray-400">
|
|
39
|
+
<%= @repository.translate.no_records_found %>
|
|
40
|
+
</div>
|
|
41
|
+
<% end %>
|
|
42
|
+
</div>
|
|
43
|
+
<% if @records.any? %>
|
|
44
|
+
<div class="my-4 flex justify-center">
|
|
45
|
+
<%= render(Uchi::Ui::Pagination.new(paginator: @paginator)) %>
|
|
46
|
+
</div>
|
|
47
|
+
<% end %>
|
|
48
|
+
<% end %>
|
|
49
|
+
</div>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<%- content_for(:page_title) { @repository.translate.title(:new) } %>
|
|
2
|
+
|
|
3
|
+
<%= render(
|
|
4
|
+
Uchi::Ui::PageHeader.new(
|
|
5
|
+
description: @repository.translate.description(:new),
|
|
6
|
+
title: @repository.translate.title(:new),
|
|
7
|
+
)) do |header| %>
|
|
8
|
+
<% header.with_breadcrumb(items: [
|
|
9
|
+
{href: @repository.routes.root_path, label: Rails.application.name.titlecase },
|
|
10
|
+
{href: @repository.routes.path_for(:index), label: @repository.translate.breadcrumb_label(:index) },
|
|
11
|
+
{href: @repository.routes.path_for(:new), label: @repository.translate.breadcrumb_label(:new) }
|
|
12
|
+
]) %>
|
|
13
|
+
<% end %>
|
|
14
|
+
|
|
15
|
+
<%= render(Flowbite::Card.new) do %>
|
|
16
|
+
<%= form_with model: @record, url: @repository.routes.path_for(:create) do |form| %>
|
|
17
|
+
<div class="space-y-6">
|
|
18
|
+
<% @repository.fields_for_edit.each do |field| %>
|
|
19
|
+
<div>
|
|
20
|
+
<%= render(
|
|
21
|
+
field.edit_component(
|
|
22
|
+
form: form,
|
|
23
|
+
repository: @repository,
|
|
24
|
+
label: @repository.translate.field_label(field),
|
|
25
|
+
hint: @repository.translate.field_hint(field)
|
|
26
|
+
)
|
|
27
|
+
) %>
|
|
28
|
+
</div>
|
|
29
|
+
<% end %>
|
|
30
|
+
|
|
31
|
+
<%= render(Uchi::Ui::Form::Footer.new) do |footer| %>
|
|
32
|
+
<%= footer.with_action { render(Flowbite::Button.new) { @repository.translate.submit_button } } %>
|
|
33
|
+
<%= footer.with_action { link_to(@repository.translate.link_to_cancel, path_for_cancel(default: @repository.routes.path_for(:index))) } %>
|
|
34
|
+
<% end %>
|
|
35
|
+
</div>
|
|
36
|
+
<% end %>
|
|
37
|
+
<% end %>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<%- content_for(:page_title) { @repository.translate.title(:show, record: @record) } %>
|
|
2
|
+
|
|
3
|
+
<%= render(
|
|
4
|
+
Uchi::Ui::PageHeader.new(
|
|
5
|
+
description: @repository.translate.description(:show, record: @record),
|
|
6
|
+
title: @repository.translate.title(:show, record: @record),
|
|
7
|
+
)
|
|
8
|
+
) do |header| %>
|
|
9
|
+
<% header.with_action do %>
|
|
10
|
+
<%= button_to(
|
|
11
|
+
@repository.translate.link_to_destroy(@record),
|
|
12
|
+
@repository.routes.path_for(:destroy, id: @record.id),
|
|
13
|
+
method: :delete,
|
|
14
|
+
class: Flowbite::Button.classes(style: :red),
|
|
15
|
+
data: {
|
|
16
|
+
:"turbo-confirm" => @repository.translate.destroy_dialog_title(@record)
|
|
17
|
+
}
|
|
18
|
+
) %>
|
|
19
|
+
<% end %>
|
|
20
|
+
|
|
21
|
+
<% header.with_action do %>
|
|
22
|
+
<%= link_to(@repository.translate.link_to_edit(@record), @repository.routes.path_for(:edit, id: @record.id), class: Flowbite::Button.classes) %>
|
|
23
|
+
<% end %>
|
|
24
|
+
|
|
25
|
+
<% header.with_breadcrumb(items: [
|
|
26
|
+
{href: @repository.routes.root_path, label: Rails.application.name.titlecase },
|
|
27
|
+
{href: @repository.routes.path_for(:index), label: @repository.translate.breadcrumb_label(:index) },
|
|
28
|
+
{href: @repository.routes.path_for(:show, id: @record.id), label: @repository.translate.breadcrumb_label(:show, record: @record) }
|
|
29
|
+
]) %>
|
|
30
|
+
<% end %>
|
|
31
|
+
|
|
32
|
+
<%= render(Uchi::Ui::Show::AttributeFields.new(
|
|
33
|
+
attribute_fields: @repository.fields_for_show.select { |field| field.group_as(:show) == :attributes },
|
|
34
|
+
record: @record,
|
|
35
|
+
repository: @repository
|
|
36
|
+
)) %>
|
|
37
|
+
|
|
38
|
+
<% association_fields = @repository.fields_for_show.select{ |field| field.group_as(:show) == :associations } %>
|
|
39
|
+
<% association_fields.each do |field| %>
|
|
40
|
+
<%= render(field.show_component(record: @record, repository: @repository)) %>
|
|
41
|
+
<% end %>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Uchi
|
|
4
|
+
class ControllerGenerator < Rails::Generators::NamedBase
|
|
5
|
+
source_root File.expand_path("templates", __dir__)
|
|
6
|
+
|
|
7
|
+
def create_controller_file
|
|
8
|
+
destination = File.join("app/controllers/uchi")
|
|
9
|
+
template "controller.rb", File.join(destination, "#{plural_file_name}_controller.rb")
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def add_route
|
|
13
|
+
route "resources :#{plural_file_name}", namespace: :uchi
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Uchi
|
|
4
|
+
class InstallGenerator < Rails::Generators::Base
|
|
5
|
+
def create_namespace_in_routes
|
|
6
|
+
route "namespace :uchi do\nend"
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def mount_engine
|
|
10
|
+
route "mount Uchi::Engine, at: \"/uchi\""
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|