frontpack 0.1.0

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 (70) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +51 -0
  4. data/Rakefile +5 -0
  5. data/app/assets/config/frontpack_manifest.js +1 -0
  6. data/app/assets/images/logo.svg +141 -0
  7. data/app/assets/javascripts/frontpack/auto-complete.js +173 -0
  8. data/app/assets/javascripts/frontpack/base-webcomponent.js +160 -0
  9. data/app/assets/javascripts/frontpack/expandable-list.js +99 -0
  10. data/app/assets/javascripts/frontpack/image-preview.js +160 -0
  11. data/app/assets/javascripts/frontpack/image-uploader.js +34 -0
  12. data/app/assets/javascripts/frontpack/localized-time.js +17 -0
  13. data/app/assets/javascripts/frontpack/modal-dialog.js +206 -0
  14. data/app/assets/javascripts/frontpack/shortcuts.js +63 -0
  15. data/app/assets/javascripts/frontpack/tab-control.js +77 -0
  16. data/app/assets/javascripts/frontpack/text-box.js +70 -0
  17. data/app/assets/javascripts/frontpack/toggle-button.js +73 -0
  18. data/app/assets/stylesheets/frontpack/000-reset.scss +15 -0
  19. data/app/assets/stylesheets/frontpack/010-config.scss +148 -0
  20. data/app/assets/stylesheets/frontpack/020-mixins.scss +218 -0
  21. data/app/assets/stylesheets/frontpack/030-consts.scss +13 -0
  22. data/app/assets/stylesheets/frontpack/031-margins.scss +5 -0
  23. data/app/assets/stylesheets/frontpack/100-layout.scss +113 -0
  24. data/app/assets/stylesheets/frontpack/101-container.scss +131 -0
  25. data/app/assets/stylesheets/frontpack/200-design.scss +75 -0
  26. data/app/assets/stylesheets/frontpack/201-box.scss +6 -0
  27. data/app/assets/stylesheets/frontpack/202-borders.scss +5 -0
  28. data/app/assets/stylesheets/frontpack/300-typography.scss +128 -0
  29. data/app/assets/stylesheets/frontpack/800-components.scss +85 -0
  30. data/app/assets/stylesheets/frontpack/801-card.scss +53 -0
  31. data/app/assets/stylesheets/frontpack/802-buttons.scss +58 -0
  32. data/app/assets/stylesheets/frontpack/803-form-controls.scss +161 -0
  33. data/app/assets/stylesheets/frontpack/804-table.scss +60 -0
  34. data/app/assets/stylesheets/frontpack/805-switch-toggle.scss +43 -0
  35. data/app/assets/stylesheets/frontpack/frontpack.scss +18 -0
  36. data/app/controllers/concerns/frontpack/searchable.rb +33 -0
  37. data/app/controllers/frontpack/autocomplete_controller.rb +33 -0
  38. data/app/helpers/frontpack/application_helper.rb +7 -0
  39. data/app/helpers/frontpack/form_builder.rb +130 -0
  40. data/app/models/concerns/frontpack/auto_completable.rb +35 -0
  41. data/config/importmap.rb +1 -0
  42. data/config/routes.rb +3 -0
  43. data/lib/frontpack/button_to_patch.rb +64 -0
  44. data/lib/frontpack/engine.rb +28 -0
  45. data/lib/frontpack/extended_model_translations.rb +31 -0
  46. data/lib/frontpack/form_builder_options.rb +5 -0
  47. data/lib/frontpack/version.rb +5 -0
  48. data/lib/frontpack.rb +9 -0
  49. data/lib/generators/frontpack/install_generator.rb +37 -0
  50. data/lib/generators/frontpack/locale_generator.rb +11 -0
  51. data/lib/generators/templates/initializers/customize_form_with_errors.rb +31 -0
  52. data/lib/generators/templates/locales/frontpack.en.yml +43 -0
  53. data/lib/generators/templates/views/layouts/_form-errors.html.slim +3 -0
  54. data/lib/generators/templates/views/layouts/_navigation.html.slim +1 -0
  55. data/lib/generators/templates/views/layouts/application.html.slim +37 -0
  56. data/lib/generators/templates/views/layouts/errors.html.slim +19 -0
  57. data/lib/generators/templates/views/layouts/mailer.html.slim +6 -0
  58. data/lib/generators/templates/views/layouts/mailer.text.slim +1 -0
  59. data/lib/tasks/frontpack_tasks.rake +6 -0
  60. data/lib/templates/rails/file_utils/searchable.rb +30 -0
  61. data/lib/templates/rails/scaffold_controller/controller.rb.tt +93 -0
  62. data/lib/templates/slim/scaffold/_form.html.slim.tt +10 -0
  63. data/lib/templates/slim/scaffold/edit.html.slim.tt +10 -0
  64. data/lib/templates/slim/scaffold/index.html.slim.tt +20 -0
  65. data/lib/templates/slim/scaffold/new.html.slim.tt +8 -0
  66. data/lib/templates/slim/scaffold/partial.html.slim.tt +6 -0
  67. data/lib/templates/slim/scaffold/show.html.slim.tt +12 -0
  68. data/lib/templates/test_unit/model/fixtures.yml.tt +18 -0
  69. data/lib/templates/test_unit/model/unit_test.rb.tt +41 -0
  70. metadata +143 -0
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+ <%
3
+ unless File.exist? Rails.root.join('app/models/concerns/searchable.rb')
4
+ FileUtils.cp 'lib/templates/rails/file_utils/searchable.rb', 'app/models/concerns/searchable.rb'
5
+ end
6
+ attr_names = []
7
+ attributes.each do |attribute|
8
+ attr_names.push attribute.name.to_sym
9
+ end
10
+ %>
11
+ <% if namespaced? -%>
12
+ require_dependency "<%= namespaced_path %>/application_controller"
13
+
14
+ <% end -%>
15
+ <% module_namespacing do -%>
16
+ # <%= controller_class_name%>Controller class
17
+ class <%= controller_class_name %>Controller < ApplicationController
18
+ include Searchable
19
+ before_action :set_<%= singular_table_name %>, only: %i[show edit update destroy]
20
+
21
+ # GET <%= route_url %>
22
+ # GET <%= route_url %>.json
23
+ def index
24
+ @<%= plural_table_name %> = basic_search <%= class_name %>, <%=attr_names.to_s.gsub(/(:(\w+),?)/, "\\2").gsub(/\[/, "%i[") %>
25
+ end
26
+
27
+ # GET <%= route_url %>/1
28
+ # GET <%= route_url %>/1.json
29
+ def show; end
30
+
31
+ # GET <%= route_url %>/new
32
+ def new
33
+ @<%= singular_table_name %> = <%= orm_class.build(class_name) %>
34
+ end
35
+
36
+ # GET <%= route_url %>/1/edit
37
+ def edit; end
38
+
39
+ # POST <%= route_url %>
40
+ def create
41
+ @<%= singular_table_name %> = <%= orm_class.build(class_name, "#{singular_table_name}_params") %>
42
+ respond_to do |format|
43
+ if @<%= orm_instance.save %>
44
+ format.html { redirect_to @<%= singular_table_name %>, flash: { success: t(:created_successfully, resource_name: @<%= singular_table_name %>.model_name.human) } }
45
+ format.json { render :show, status: :created, location: @<%= singular_table_name %> }
46
+ else
47
+ format.html { render :new, status: :unprocessable_entity }
48
+ format.json { render json: @<%= singular_table_name %>.errors, status: :unprocessable_entity }
49
+ end
50
+ end
51
+ end
52
+
53
+ # PATCH/PUT <%= route_url %>/1
54
+ # PATCH/PUT <%= route_url %>/1.json
55
+ def update
56
+ respond_to do |format|
57
+ if @<%= orm_instance.update("#{singular_table_name}_params") %>
58
+ format.html { redirect_to <%= redirect_resource_name %>, flash: { success: t(:updated_successfully, resource_name: @<%= singular_table_name %>.model_name.human) } }
59
+ format.json { render :show, status: :ok, location: @<%= singular_table_name %> }
60
+ else
61
+ format.html { render :edit, status: :unprocessable_entity }
62
+ format.json { render json: @<%= singular_table_name %>.errors, status: :unprocessable_entity }
63
+ end
64
+ end
65
+ end
66
+
67
+ # DELETE <%= route_url %>/1
68
+ # DELETE <%= route_url %>/1.json
69
+ def destroy
70
+ @<%= orm_instance.destroy %>
71
+ respond_to do |format|
72
+ format.html { redirect_to <%= index_helper %>_url, flash: { danger: t(:deleted_successfully, resource_name: @<%= singular_table_name %>.model_name.human) } }
73
+ format.json { head :no_content }
74
+ end
75
+ end
76
+
77
+ private
78
+
79
+ # Use callbacks to share common setup or constraints between actions.
80
+ def set_<%= singular_table_name %>
81
+ @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
82
+ end
83
+
84
+ # Only allow a trusted parameter "white list" through.
85
+ def <%= "#{singular_table_name}_params" %>
86
+ <%- if attributes_names.empty? -%>
87
+ params.fetch(:<%= singular_table_name %>, {})
88
+ <%- else -%>
89
+ params.require(:<%= singular_table_name %>).permit(<%= attributes_names.map { |name| ":#{name}" }.join(', ') %>)
90
+ <%- end -%>
91
+ end
92
+ end
93
+ <% end -%>
@@ -0,0 +1,10 @@
1
+ = form_with model: <%= singular_table_name %>, html: { class: 'grid gap-2' } do |f|
2
+ = render 'layouts/form-errors', instance: @<%= singular_table_name %>
3
+ <% for attribute in attributes -%>
4
+ .field.col-6.sm-col-12
5
+ = f.label :<%= attribute.name %>
6
+ = f.<%= attribute.field_type %> :<%= attribute.name %>
7
+ <% end -%>
8
+ .actions
9
+ button.success( type = :submit )=t :save
10
+ = link_to t(:back), _back_url, class: 'button'
@@ -0,0 +1,10 @@
1
+ - content_for :breadcrumbs do
2
+ = link_to (@<%= singular_table_name %>.model_name.human count: 2), <%= plural_table_name %>_path, class: 'no-underscore'
3
+ | /
4
+ = link_to @<%= singular_table_name %>.<%= %w[name first_name title].intersection(attributes.map(&:name)).first || 'id' %>, <%= singular_table_name %>_path(@<%= singular_table_name %>), class: 'no-underscore'
5
+ | /
6
+ strong = t(:edit)
7
+
8
+ .container.fixed-width
9
+ h1= "#{t(:edit)} #{@<%= singular_table_name %>.model_name.human.downcase}"
10
+ = render 'form', <%= singular_table_name %>: @<%= singular_table_name %>
@@ -0,0 +1,20 @@
1
+ - content_for :breadcrumbs do
2
+ strong = @<%= plural_table_name %>.model_name.human count: 2
3
+
4
+ - content_for :actions do
5
+ .left = link_to t('.new'), new_<%= singular_table_name %>_path, class: 'button success'
6
+
7
+ - if @<%= plural_table_name %>.count.zero?
8
+ .container
9
+ h2.ta-c = t '.title'
10
+ p.ta-c = t '.text'
11
+ p.ta-c = t '.description'
12
+ .ta-c.mt-4
13
+ = link_to "#{t(:new)} #{@<%= plural_table_name %>.model_name.human.downcase}", new_<%= singular_table_name %>_path, class: 'button success'
14
+ - else
15
+ .container.fixed-width
16
+ h1 = @<%= plural_table_name %>.model_name.human count: 2
17
+ text-box#info.outline-secondary( icon = 'info', persistent = true ) = t '.description'
18
+ - @<%= plural_table_name %>.each do |<%= singular_table_name %>|
19
+ = render <%= singular_table_name %>
20
+ = paginate @<%= plural_table_name %>
@@ -0,0 +1,8 @@
1
+ - content_for :breadcrumbs do
2
+ = link_to (@<%= singular_table_name %>.model_name.human count: 2), <%= plural_table_name %>_path, class: 'no-underscore'
3
+ | /
4
+ strong = t(:new)
5
+
6
+ .container.fixed-width
7
+ h1= "#{t(:new)} #{@<%= singular_table_name %>.model_name.human.downcase}"
8
+ = render 'form', <%= singular_table_name %>: @<%= singular_table_name %>
@@ -0,0 +1,6 @@
1
+ .bb-1.p-4
2
+ = link_to <%= singular_name %>.<%= %w[name first_name title].intersection(attributes.map(&:name)).first || 'id' %>, <%= singular_table_name %>_path(<%= singular_name %>), class: 'bold large-1'
3
+ p.mv-2.text-secondary= <%= singular_name %>.<%= %w[description].intersection(attributes.map(&:name)).first || 'id' %>
4
+ p.mv-2
5
+ = link_to t(:edit), edit_<%= singular_table_name %>_path(<%= singular_name %>), class: 'button small warning'
6
+ = link_to t(:delete), <%= singular_table_name %>_path(<%= singular_name %>), data: { 'turbo-method': :delete }, class: 'button small danger ml-2'
@@ -0,0 +1,12 @@
1
+ - content_for :breadcrumbs do
2
+ = link_to (@<%= singular_table_name %>.model_name.human count: 2), <%= plural_table_name %>_path, class: 'no-underscore'
3
+ | /
4
+ strong = @<%= singular_table_name %>.<%= %w[name first_name title].intersection(attributes.map(&:name)).first || 'id' %>
5
+
6
+ - content_for :actions do
7
+ .left
8
+ = link_to t(:edit), edit_<%= singular_table_name %>_path(@<%= singular_table_name %>), class: 'button primary', shortcut: 'F2'
9
+ = link_to t(:new), new_<%= singular_table_name %>_path, class: 'button success responsive', shortcut: 'Insert'
10
+
11
+ .container.fixed-width
12
+ h1= @<%= singular_table_name %>.id
@@ -0,0 +1,18 @@
1
+ <% unless attributes.empty? -%>
2
+ <% %w(one two deletable).each do |name| %>
3
+ <%= name %>:
4
+ <% attributes.each do |attribute| -%>
5
+ <%- if attribute.password_digest? -%>
6
+ password_digest: <%%= BCrypt::Password.create("secret") %>
7
+ <%- elsif attribute.reference? -%>
8
+ <%= yaml_key_value(attribute.column_name.delete_suffix("_id"), attribute.default || name) %>
9
+ <%- elsif !attribute.virtual? -%>
10
+ <%= yaml_key_value(attribute.column_name, attribute.default) %>
11
+ <%- end -%>
12
+ <%- if attribute.polymorphic? -%>
13
+ <%= yaml_key_value("#{attribute.name}_type", attribute.human_name) %>
14
+ <%- end -%>
15
+ <% end -%>
16
+ <% end -%>
17
+ <% else -%>
18
+ <% end -%>
@@ -0,0 +1,41 @@
1
+ require "test_helper"
2
+ <% module_namespacing do -%>
3
+ class <%= class_name %>Test < ActiveSupport::TestCase
4
+ setup do
5
+ @data = <%= table_name %>(:one).as_json.except 'id'
6
+ end
7
+
8
+ test 'should create <%= singular_table_name %>' do
9
+ <%= singular_table_name %> = <%= class_name %>.new @data
10
+ assert <%= singular_table_name %>.save, "Failed to create a new <%= singular_table_name %>: #{<%= singular_table_name %>.errors.as_json}"
11
+ end
12
+
13
+ test 'should not create <%= singular_table_name %> with missing fields' do
14
+ %w[<%= attributes&.map(&:name).join(' ') %>].each do |field|
15
+ <%= singular_table_name %> = <%= class_name %>.new @data.except field
16
+ assert_not <%= singular_table_name %>.save, "Not null validation failed for field #{field}"
17
+ end
18
+ end
19
+
20
+ test 'should update <%= singular_table_name %>' do
21
+ <%= singular_table_name %> = <%= table_name %>(:one)
22
+ <%- if attributes.count.positive? %>
23
+ <%= singular_table_name %>.<%= attributes[0].name %> = 'Modified'
24
+ <% end -%>
25
+ assert <%= singular_table_name %>.save, 'Failed to update <%= singular_table_name %>'
26
+ end
27
+
28
+ test 'should not update <%= singular_table_name %> with missing fields' do
29
+ %w[<%= attributes&.map(&:name).join(' ') %>].each do |field|
30
+ <%= singular_table_name %> = <%= table_name %>(:one)
31
+ <%= singular_table_name %>.send("#{field}=", nil)
32
+ assert_not <%= singular_table_name %>.save, "Not null validation failed for field #{field}"
33
+ end
34
+ end
35
+
36
+ test 'should delete <%= singular_table_name %>' do
37
+ <%= singular_table_name %> = <%= table_name %>(:deletable)
38
+ assert <%= singular_table_name %>.destroy, 'Failed to delete <%= singular_table_name %>'
39
+ end
40
+ end
41
+ <% end -%>
metadata ADDED
@@ -0,0 +1,143 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: frontpack
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Francis Schiavo
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-12-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: importmap-rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 7.1.3.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 7.1.3.2
41
+ description: A pack containing useful front-end features.
42
+ email:
43
+ - francischiavo@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - MIT-LICENSE
49
+ - README.md
50
+ - Rakefile
51
+ - app/assets/config/frontpack_manifest.js
52
+ - app/assets/images/logo.svg
53
+ - app/assets/javascripts/frontpack/auto-complete.js
54
+ - app/assets/javascripts/frontpack/base-webcomponent.js
55
+ - app/assets/javascripts/frontpack/expandable-list.js
56
+ - app/assets/javascripts/frontpack/image-preview.js
57
+ - app/assets/javascripts/frontpack/image-uploader.js
58
+ - app/assets/javascripts/frontpack/localized-time.js
59
+ - app/assets/javascripts/frontpack/modal-dialog.js
60
+ - app/assets/javascripts/frontpack/shortcuts.js
61
+ - app/assets/javascripts/frontpack/tab-control.js
62
+ - app/assets/javascripts/frontpack/text-box.js
63
+ - app/assets/javascripts/frontpack/toggle-button.js
64
+ - app/assets/stylesheets/frontpack/000-reset.scss
65
+ - app/assets/stylesheets/frontpack/010-config.scss
66
+ - app/assets/stylesheets/frontpack/020-mixins.scss
67
+ - app/assets/stylesheets/frontpack/030-consts.scss
68
+ - app/assets/stylesheets/frontpack/031-margins.scss
69
+ - app/assets/stylesheets/frontpack/100-layout.scss
70
+ - app/assets/stylesheets/frontpack/101-container.scss
71
+ - app/assets/stylesheets/frontpack/200-design.scss
72
+ - app/assets/stylesheets/frontpack/201-box.scss
73
+ - app/assets/stylesheets/frontpack/202-borders.scss
74
+ - app/assets/stylesheets/frontpack/300-typography.scss
75
+ - app/assets/stylesheets/frontpack/800-components.scss
76
+ - app/assets/stylesheets/frontpack/801-card.scss
77
+ - app/assets/stylesheets/frontpack/802-buttons.scss
78
+ - app/assets/stylesheets/frontpack/803-form-controls.scss
79
+ - app/assets/stylesheets/frontpack/804-table.scss
80
+ - app/assets/stylesheets/frontpack/805-switch-toggle.scss
81
+ - app/assets/stylesheets/frontpack/frontpack.scss
82
+ - app/controllers/concerns/frontpack/searchable.rb
83
+ - app/controllers/frontpack/autocomplete_controller.rb
84
+ - app/helpers/frontpack/application_helper.rb
85
+ - app/helpers/frontpack/form_builder.rb
86
+ - app/models/concerns/frontpack/auto_completable.rb
87
+ - config/importmap.rb
88
+ - config/routes.rb
89
+ - lib/frontpack.rb
90
+ - lib/frontpack/button_to_patch.rb
91
+ - lib/frontpack/engine.rb
92
+ - lib/frontpack/extended_model_translations.rb
93
+ - lib/frontpack/form_builder_options.rb
94
+ - lib/frontpack/version.rb
95
+ - lib/generators/frontpack/install_generator.rb
96
+ - lib/generators/frontpack/locale_generator.rb
97
+ - lib/generators/templates/initializers/customize_form_with_errors.rb
98
+ - lib/generators/templates/locales/frontpack.en.yml
99
+ - lib/generators/templates/views/layouts/_form-errors.html.slim
100
+ - lib/generators/templates/views/layouts/_navigation.html.slim
101
+ - lib/generators/templates/views/layouts/application.html.slim
102
+ - lib/generators/templates/views/layouts/errors.html.slim
103
+ - lib/generators/templates/views/layouts/mailer.html.slim
104
+ - lib/generators/templates/views/layouts/mailer.text.slim
105
+ - lib/tasks/frontpack_tasks.rake
106
+ - lib/templates/rails/file_utils/searchable.rb
107
+ - lib/templates/rails/scaffold_controller/controller.rb.tt
108
+ - lib/templates/slim/scaffold/_form.html.slim.tt
109
+ - lib/templates/slim/scaffold/edit.html.slim.tt
110
+ - lib/templates/slim/scaffold/index.html.slim.tt
111
+ - lib/templates/slim/scaffold/new.html.slim.tt
112
+ - lib/templates/slim/scaffold/partial.html.slim.tt
113
+ - lib/templates/slim/scaffold/show.html.slim.tt
114
+ - lib/templates/test_unit/model/fixtures.yml.tt
115
+ - lib/templates/test_unit/model/unit_test.rb.tt
116
+ homepage: https://github.com/francis-schiavo/frontpack
117
+ licenses:
118
+ - MIT
119
+ metadata:
120
+ homepage_uri: https://github.com/francis-schiavo/frontpack
121
+ source_code_uri: https://github.com/francis-schiavo/frontpack
122
+ changelog_uri: https://github.com/francis-schiavo/frontpack/blob/main/CHANGELOG.md
123
+ rubygems_mfa_required: 'true'
124
+ post_install_message:
125
+ rdoc_options: []
126
+ require_paths:
127
+ - lib
128
+ required_ruby_version: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ required_rubygems_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ requirements: []
139
+ rubygems_version: 3.5.3
140
+ signing_key:
141
+ specification_version: 4
142
+ summary: A pack containing useful front-end features.
143
+ test_files: []