goodmin 0.0.1

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 (147) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +1359 -0
  4. data/Rakefile +56 -0
  5. data/app/assets/stylesheets/goodmin/application.css +75 -0
  6. data/app/controllers/goodmin/application_controller.rb +43 -0
  7. data/app/controllers/goodmin/resource_controller.rb +235 -0
  8. data/app/helpers/goodmin/application_helper.rb +45 -0
  9. data/app/javascript/goodmin/application.js +8 -0
  10. data/app/javascript/goodmin/controllers/batch_actions_controller.js +101 -0
  11. data/app/javascript/goodmin/controllers/datetimepicker_controller.js +24 -0
  12. data/app/javascript/goodmin/controllers/navigation_controller.js +30 -0
  13. data/app/jobs/goodmin/application_job.rb +4 -0
  14. data/app/mailers/goodmin/application_mailer.rb +6 -0
  15. data/app/models/goodmin/application_record.rb +5 -0
  16. data/app/views/goodmin/application/welcome.html.erb +17 -0
  17. data/app/views/goodmin/fields/association/_form.html.erb +19 -0
  18. data/app/views/goodmin/fields/association/_index.html.erb +6 -0
  19. data/app/views/goodmin/fields/association/_show.html.erb +6 -0
  20. data/app/views/goodmin/fields/boolean/_form.html.erb +7 -0
  21. data/app/views/goodmin/fields/boolean/_index.html.erb +1 -0
  22. data/app/views/goodmin/fields/boolean/_show.html.erb +1 -0
  23. data/app/views/goodmin/fields/date/_form.html.erb +6 -0
  24. data/app/views/goodmin/fields/date/_index.html.erb +1 -0
  25. data/app/views/goodmin/fields/date/_show.html.erb +1 -0
  26. data/app/views/goodmin/fields/date_time/_form.html.erb +6 -0
  27. data/app/views/goodmin/fields/date_time/_index.html.erb +1 -0
  28. data/app/views/goodmin/fields/date_time/_show.html.erb +1 -0
  29. data/app/views/goodmin/fields/enum/_index.html.erb +1 -0
  30. data/app/views/goodmin/fields/enum/_show.html.erb +1 -0
  31. data/app/views/goodmin/fields/nested_has_one/_form.html.erb +6 -0
  32. data/app/views/goodmin/fields/nested_has_one/_index.html.erb +1 -0
  33. data/app/views/goodmin/fields/nested_has_one/_show.html.erb +1 -0
  34. data/app/views/goodmin/fields/number/_form.html.erb +5 -0
  35. data/app/views/goodmin/fields/number/_index.html.erb +1 -0
  36. data/app/views/goodmin/fields/number/_show.html.erb +1 -0
  37. data/app/views/goodmin/fields/password/_form.html.erb +5 -0
  38. data/app/views/goodmin/fields/password/_index.html.erb +1 -0
  39. data/app/views/goodmin/fields/password/_show.html.erb +1 -0
  40. data/app/views/goodmin/fields/select/_form.html.erb +5 -0
  41. data/app/views/goodmin/fields/select/_index.html.erb +1 -0
  42. data/app/views/goodmin/fields/select/_show.html.erb +1 -0
  43. data/app/views/goodmin/fields/string/_form.html.erb +5 -0
  44. data/app/views/goodmin/fields/string/_index.html.erb +1 -0
  45. data/app/views/goodmin/fields/string/_show.html.erb +1 -0
  46. data/app/views/goodmin/fields/text/_form.html.erb +5 -0
  47. data/app/views/goodmin/fields/text/_index.html.erb +1 -0
  48. data/app/views/goodmin/fields/text/_show.html.erb +1 -0
  49. data/app/views/goodmin/resource/_actions.html.erb +9 -0
  50. data/app/views/goodmin/resource/_batch_actions.html.erb +12 -0
  51. data/app/views/goodmin/resource/_breadcrumb.html.erb +33 -0
  52. data/app/views/goodmin/resource/_breadcrumb_actions.html.erb +41 -0
  53. data/app/views/goodmin/resource/_button_actions.html.erb +3 -0
  54. data/app/views/goodmin/resource/_errors.html.erb +9 -0
  55. data/app/views/goodmin/resource/_export_actions.html.erb +15 -0
  56. data/app/views/goodmin/resource/_filters.html.erb +22 -0
  57. data/app/views/goodmin/resource/_form.html.erb +26 -0
  58. data/app/views/goodmin/resource/_pagination.html.erb +40 -0
  59. data/app/views/goodmin/resource/_scopes.html.erb +14 -0
  60. data/app/views/goodmin/resource/_table.html.erb +45 -0
  61. data/app/views/goodmin/resource/columns/_actions.html.erb +28 -0
  62. data/app/views/goodmin/resource/edit.html.erb +5 -0
  63. data/app/views/goodmin/resource/index.csv.csvbuilder +5 -0
  64. data/app/views/goodmin/resource/index.html.erb +10 -0
  65. data/app/views/goodmin/resource/index.json.jbuilder +3 -0
  66. data/app/views/goodmin/resource/new.html.erb +5 -0
  67. data/app/views/goodmin/resource/show.html.erb +11 -0
  68. data/app/views/goodmin/resource/show.json.jbuilder +1 -0
  69. data/app/views/goodmin/sessions/new.html.erb +11 -0
  70. data/app/views/goodmin/shared/_navigation.html.erb +0 -0
  71. data/app/views/goodmin/shared/_navigation_aside.html.erb +7 -0
  72. data/app/views/layouts/goodmin/_content.html.erb +13 -0
  73. data/app/views/layouts/goodmin/_layout.html.erb +22 -0
  74. data/app/views/layouts/goodmin/application.html.erb +28 -0
  75. data/app/views/layouts/goodmin/login.html.erb +18 -0
  76. data/config/importmap.rb +5 -0
  77. data/config/locales/en.yml +49 -0
  78. data/config/locales/pl-BR.yml +49 -0
  79. data/config/locales/pt-BR.yml +49 -0
  80. data/config/locales/sv.yml +49 -0
  81. data/config/routes.rb +3 -0
  82. data/lib/generators/goodmin/authentication/authentication_generator.rb +41 -0
  83. data/lib/generators/goodmin/authentication/templates/sessions_controller.rb +9 -0
  84. data/lib/generators/goodmin/install/install_generator.rb +41 -0
  85. data/lib/generators/goodmin/policy/policy_generator.rb +7 -0
  86. data/lib/generators/goodmin/policy/templates/policy.rb +23 -0
  87. data/lib/generators/goodmin/resource/resource_generator.rb +31 -0
  88. data/lib/generators/goodmin/resource/templates/resource.rb +25 -0
  89. data/lib/generators/goodmin/resource/templates/resource_controller.rb +9 -0
  90. data/lib/generators/goodmin/resource/templates/resource_model.rb +4 -0
  91. data/lib/generators/goodmin/resource/templates/resource_service.rb +23 -0
  92. data/lib/goodmin/authentication/sessions_controller.rb +46 -0
  93. data/lib/goodmin/authentication/user.rb +27 -0
  94. data/lib/goodmin/authentication.rb +35 -0
  95. data/lib/goodmin/authorization/policy.rb +41 -0
  96. data/lib/goodmin/authorization.rb +69 -0
  97. data/lib/goodmin/engine.rb +30 -0
  98. data/lib/goodmin/fields/association.rb +62 -0
  99. data/lib/goodmin/fields/base.rb +57 -0
  100. data/lib/goodmin/fields/boolean.rb +6 -0
  101. data/lib/goodmin/fields/date.rb +6 -0
  102. data/lib/goodmin/fields/date_time.rb +6 -0
  103. data/lib/goodmin/fields/enum.rb +15 -0
  104. data/lib/goodmin/fields/nested_has_one.rb +41 -0
  105. data/lib/goodmin/fields/number.rb +6 -0
  106. data/lib/goodmin/fields/password.rb +6 -0
  107. data/lib/goodmin/fields/select.rb +19 -0
  108. data/lib/goodmin/fields/string.rb +6 -0
  109. data/lib/goodmin/fields/text.rb +6 -0
  110. data/lib/goodmin/generators/base.rb +49 -0
  111. data/lib/goodmin/generators/named_base.rb +31 -0
  112. data/lib/goodmin/helpers/application.rb +47 -0
  113. data/lib/goodmin/helpers/batch_actions.rb +21 -0
  114. data/lib/goodmin/helpers/filters.rb +123 -0
  115. data/lib/goodmin/helpers/forms.rb +42 -0
  116. data/lib/goodmin/helpers/navigation.rb +52 -0
  117. data/lib/goodmin/helpers/tables.rb +25 -0
  118. data/lib/goodmin/helpers/translations.rb +19 -0
  119. data/lib/goodmin/paginator.rb +55 -0
  120. data/lib/goodmin/resolver.rb +141 -0
  121. data/lib/goodmin/resources/attribute.rb +46 -0
  122. data/lib/goodmin/resources/form_builder.rb +96 -0
  123. data/lib/goodmin/resources/form_component.rb +65 -0
  124. data/lib/goodmin/resources/form_components/col.rb +33 -0
  125. data/lib/goodmin/resources/form_components/row.rb +25 -0
  126. data/lib/goodmin/resources/form_components/section.rb +51 -0
  127. data/lib/goodmin/resources/form_components/tab.rb +49 -0
  128. data/lib/goodmin/resources/resource/associations.rb +23 -0
  129. data/lib/goodmin/resources/resource/batch_actions.rb +56 -0
  130. data/lib/goodmin/resources/resource/filters.rb +44 -0
  131. data/lib/goodmin/resources/resource/ordering.rb +41 -0
  132. data/lib/goodmin/resources/resource/pagination.rb +22 -0
  133. data/lib/goodmin/resources/resource/scopes.rb +61 -0
  134. data/lib/goodmin/resources/resource.rb +199 -0
  135. data/lib/goodmin/resources/resource_controller/batch_actions.rb +49 -0
  136. data/lib/goodmin/resources/resource_service/associations.rb +23 -0
  137. data/lib/goodmin/resources/resource_service/batch_actions.rb +52 -0
  138. data/lib/goodmin/resources/resource_service/filters.rb +44 -0
  139. data/lib/goodmin/resources/resource_service/ordering.rb +41 -0
  140. data/lib/goodmin/resources/resource_service/pagination.rb +22 -0
  141. data/lib/goodmin/resources/resource_service/scopes.rb +61 -0
  142. data/lib/goodmin/resources/resource_service.rb +199 -0
  143. data/lib/goodmin/service_locator.rb +25 -0
  144. data/lib/goodmin/version.rb +3 -0
  145. data/lib/goodmin.rb +44 -0
  146. data/lib/tasks/goodmin_tasks.rake +4 -0
  147. metadata +461 -0
@@ -0,0 +1,199 @@
1
+ require "goodmin/resources/attribute"
2
+ require "goodmin/resources/form_builder"
3
+ require "goodmin/resources/resource_service/associations"
4
+ require "goodmin/resources/resource_service/batch_actions"
5
+ require "goodmin/resources/resource_service/filters"
6
+ require "goodmin/resources/resource_service/ordering"
7
+ require "goodmin/resources/resource_service/pagination"
8
+ require "goodmin/resources/resource_service/scopes"
9
+
10
+ module Goodmin
11
+ module Resources
12
+ module ResourceService
13
+ extend ActiveSupport::Concern
14
+
15
+ class AttributeBuilder
16
+ attr_reader :attributes
17
+
18
+ def initialize
19
+ @attributes = []
20
+ end
21
+
22
+ def attribute(name, field: nil)
23
+ @attributes << Attribute.new(name, field_class: field)
24
+ end
25
+ end
26
+
27
+ include Associations
28
+ include BatchActions
29
+ include Filters
30
+ include Ordering
31
+ include Pagination
32
+ include Scopes
33
+
34
+ attr_reader :options
35
+
36
+ def initialize(options = {})
37
+ @options = options
38
+ end
39
+
40
+ def resource_class
41
+ self.class.name.chomp("Service").constantize
42
+ end
43
+
44
+ def resources_relation
45
+ if options[:resource_parent].present?
46
+ parent = options[:resource_parent]
47
+ association_name = resource_class.name.underscore.pluralize.to_sym
48
+ reflection = parent.class.reflect_on_association(association_name)
49
+
50
+ if reflection && (reflection.macro == :has_and_belongs_to_many ||
51
+ (reflection.macro == :has_many && reflection.options[:through].present?))
52
+ parent.send(association_name)
53
+ else
54
+ resource_class.where(parent.class.name.underscore => parent)
55
+ end
56
+ else
57
+ resource_class.all
58
+ end
59
+ end
60
+
61
+ def resources(params)
62
+ apply_pagination(
63
+ params[:page], apply_order(
64
+ params[:order], apply_filters(
65
+ params[:filter], apply_scope(
66
+ params[:scope], resources_relation
67
+ )
68
+ )
69
+ )
70
+ )
71
+ end
72
+
73
+ def find_resource(id)
74
+ resources_relation.find(id)
75
+ end
76
+
77
+ def build_resource(params)
78
+ resources_relation.new(params)
79
+ end
80
+
81
+ def create_resource(resource)
82
+ resource.save
83
+ end
84
+
85
+ def update_resource(resource, params)
86
+ resource.update(params)
87
+ end
88
+
89
+ def destroy_resource(resource)
90
+ resource.destroy
91
+ end
92
+
93
+ def attrs_for_index
94
+ self.class.attrs_for_index
95
+ end
96
+
97
+ def attrs_for_show
98
+ self.class.attrs_for_show
99
+ end
100
+
101
+ def attrs_for_form
102
+ self.class.attrs_for_form
103
+ end
104
+
105
+ def form_nodes
106
+ self.class.form_nodes
107
+ end
108
+
109
+ def form_tabs
110
+ self.class.form_tabs
111
+ end
112
+
113
+ def attrs_for_export
114
+ self.class.attrs_for_export
115
+ end
116
+
117
+ def display_name(record)
118
+ record.to_s
119
+ end
120
+
121
+ def option_text_for_association(attribute)
122
+ self.class.association_option_texts[attribute] || :to_s
123
+ end
124
+
125
+ module ClassMethods
126
+ def index(&block)
127
+ if block_given?
128
+ builder = AttributeBuilder.new
129
+ builder.instance_eval(&block)
130
+ @attrs_for_index = builder.attributes
131
+ end
132
+ @attrs_for_index || []
133
+ end
134
+
135
+ def show(&block)
136
+ if block_given?
137
+ builder = AttributeBuilder.new
138
+ builder.instance_eval(&block)
139
+ @attrs_for_show = builder.attributes
140
+ end
141
+ @attrs_for_show || []
142
+ end
143
+
144
+ def form(&block)
145
+ if block_given?
146
+ builder = FormBuilder.new
147
+ builder.instance_eval(&block)
148
+ @form_nodes = builder.nodes
149
+ @attrs_for_form = builder.attributes
150
+ @form_tabs = builder.tabs
151
+ end
152
+ @attrs_for_form || []
153
+ end
154
+
155
+ def export(&block)
156
+ if block_given?
157
+ builder = AttributeBuilder.new
158
+ builder.instance_eval(&block)
159
+ @attrs_for_export = builder.attributes
160
+ end
161
+ @attrs_for_export || []
162
+ end
163
+
164
+ def attrs_for_index
165
+ @attrs_for_index || []
166
+ end
167
+
168
+ def attrs_for_show
169
+ @attrs_for_show || []
170
+ end
171
+
172
+ def attrs_for_form
173
+ @attrs_for_form || []
174
+ end
175
+
176
+ def form_nodes
177
+ @form_nodes || attrs_for_form.map { |attr| AttributeNode.new(attr) }
178
+ end
179
+
180
+ def form_tabs
181
+ @form_tabs || []
182
+ end
183
+
184
+ def attrs_for_export
185
+ @attrs_for_export || []
186
+ end
187
+
188
+ def association_option_text(attribute, method_name)
189
+ @association_option_texts ||= {}
190
+ @association_option_texts[attribute] = method_name
191
+ end
192
+
193
+ def association_option_texts
194
+ @association_option_texts || {}
195
+ end
196
+ end
197
+ end
198
+ end
199
+ end
@@ -0,0 +1,25 @@
1
+ module Goodmin
2
+ module ServiceLocator
3
+ # Find the resource class for a given model class. Uses only the simple class
4
+ # name (the last segment after "::") to build the resource class name, then
5
+ # checks the namespace of +context_service_class+ first (e.g.
6
+ # Goodmin::Resources::MuseumResource when context is
7
+ # Goodmin::Resources::UserResource), then falls back to Goodmin::Resources.
8
+ def self.find_service_class_for(klass, context_service_class:)
9
+ return nil unless klass
10
+
11
+ klass_name = klass.is_a?(String) ? klass : klass.name
12
+ return nil unless klass_name
13
+
14
+ simple_name = klass_name.split("::").last
15
+ resource_name = "#{simple_name}Resource"
16
+ namespace = context_service_class&.name&.deconstantize
17
+
18
+ if namespace.present?
19
+ "#{namespace}::#{resource_name}".safe_constantize || "Goodmin::Resources::#{resource_name}".safe_constantize
20
+ else
21
+ "Goodmin::Resources::#{resource_name}".safe_constantize
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,3 @@
1
+ module Goodmin
2
+ VERSION = "0.0.1"
3
+ end
data/lib/goodmin.rb ADDED
@@ -0,0 +1,44 @@
1
+ require "importmap-rails"
2
+ require "stimulus-rails"
3
+ require "csv_builder"
4
+ require "goodmin/authentication"
5
+ require "goodmin/authorization"
6
+ require "goodmin/engine"
7
+ require "goodmin/service_locator"
8
+ require "goodmin/fields/base"
9
+ require "goodmin/fields/string"
10
+ require "goodmin/fields/password"
11
+ require "goodmin/fields/text"
12
+ require "goodmin/fields/boolean"
13
+ require "goodmin/fields/date"
14
+ require "goodmin/fields/date_time"
15
+ require "goodmin/fields/number"
16
+ require "goodmin/fields/association"
17
+ require "goodmin/fields/select"
18
+ require "goodmin/fields/enum"
19
+ require "goodmin/fields/nested_has_one"
20
+ require "goodmin/paginator"
21
+ require "goodmin/resolver"
22
+ require "goodmin/helpers/application"
23
+ require "goodmin/helpers/forms"
24
+ require "goodmin/helpers/navigation"
25
+ require "goodmin/helpers/translations"
26
+ require "goodmin/helpers/filters"
27
+ require "goodmin/helpers/tables"
28
+ require "goodmin/resources/resource"
29
+ require "goodmin/resources/resource_service"
30
+ require "goodmin/resources/form_component"
31
+ require "goodmin/resources/form_components/row"
32
+ require "goodmin/resources/form_components/col"
33
+ require "goodmin/resources/form_components/section"
34
+ require "goodmin/resources/form_components/tab"
35
+ require "goodmin/version"
36
+
37
+ module Goodmin
38
+ mattr_accessor :importmap, default: Importmap::Map.new
39
+ end
40
+
41
+ Goodmin::Resources::FormBuilder.register_component(:row, Goodmin::Resources::FormComponents::Row)
42
+ Goodmin::Resources::FormBuilder.register_component(:col, Goodmin::Resources::FormComponents::Col)
43
+ Goodmin::Resources::FormBuilder.register_component(:section, Goodmin::Resources::FormComponents::Section)
44
+ Goodmin::Resources::FormBuilder.register_component(:tab, Goodmin::Resources::FormComponents::Tab)
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :goodmin do
3
+ # # Task goes here
4
+ # end