oversee 0.2.0 → 0.3.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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -3
  3. data/app/assets/config/oversee_manifest.js +2 -0
  4. data/app/components/oversee/dashboard/actions.rb +58 -0
  5. data/app/components/oversee/dashboard/filter.rb +12 -0
  6. data/app/components/oversee/dashboard/filters.rb +5 -51
  7. data/app/components/oversee/dashboard/header.rb +34 -18
  8. data/app/components/oversee/dashboard/index.rb +23 -11
  9. data/app/components/oversee/dashboard/javascript.rb +4 -4
  10. data/app/components/oversee/dashboard/pagination.rb +1 -1
  11. data/app/components/oversee/dashboard/sidebar.rb +38 -1
  12. data/app/components/oversee/dashboard/tailwind.rb +30 -1
  13. data/app/components/oversee/field/display.rb +12 -21
  14. data/app/components/oversee/field/form.rb +5 -37
  15. data/app/components/oversee/field/input/belongs_to.rb +5 -0
  16. data/app/components/oversee/field/input/boolean.rb +3 -18
  17. data/app/components/oversee/field/input/date.rb +5 -0
  18. data/app/components/oversee/field/input/datetime.rb +2 -17
  19. data/app/components/oversee/field/input/integer.rb +2 -17
  20. data/app/components/oversee/field/input/json.rb +5 -0
  21. data/app/components/oversee/field/input/rich_text.rb +10 -0
  22. data/app/components/oversee/field/input/string.rb +2 -17
  23. data/app/components/oversee/field/input.rb +13 -11
  24. data/app/components/oversee/field/label.rb +16 -15
  25. data/app/components/oversee/field/set.rb +36 -0
  26. data/app/components/oversee/field/value/belongs_to.rb +15 -0
  27. data/app/components/oversee/field/value/boolean.rb +2 -47
  28. data/app/components/oversee/field/value/date.rb +5 -0
  29. data/app/components/oversee/field/value/datetime.rb +2 -6
  30. data/app/components/oversee/field/value/enum.rb +2 -6
  31. data/app/components/oversee/field/value/integer.rb +2 -6
  32. data/app/components/oversee/field/value/json.rb +6 -0
  33. data/app/components/oversee/field/value/rich_text.rb +5 -0
  34. data/app/components/oversee/field/value/string.rb +3 -10
  35. data/app/components/oversee/field/value/text.rb +2 -6
  36. data/app/components/oversee/field/value.rb +14 -5
  37. data/app/components/oversee/field.rb +42 -0
  38. data/app/components/oversee/flash.rb +39 -0
  39. data/app/components/oversee/layout/application.rb +46 -0
  40. data/app/components/oversee/resources/index.rb +22 -3
  41. data/app/components/oversee/resources/new.rb +7 -3
  42. data/app/components/oversee/resources/show.rb +139 -68
  43. data/app/components/oversee/resources/table.rb +8 -2
  44. data/app/controllers/oversee/dashboard_controller.rb +1 -1
  45. data/app/controllers/oversee/resources/fields_controller.rb +24 -36
  46. data/app/controllers/oversee/resources_controller.rb +29 -24
  47. data/app/javascript/oversee/application.js +3 -0
  48. data/app/javascript/oversee/controllers/clipboard_controller.js +21 -0
  49. data/app/javascript/oversee/controllers/index.js +9 -0
  50. data/app/javascript/oversee/controllers/notification_controller.js +17 -0
  51. data/app/javascript/oversee/controllers/reveal_controller.js +19 -0
  52. data/app/javascript/oversee/controllers/sidebar/state_controller.js +21 -0
  53. data/app/models/oversee/resource.rb +49 -20
  54. data/app/{oversee → service/oversee}/filter.rb +2 -2
  55. data/app/{oversee → service/oversee}/search.rb +1 -1
  56. data/app/views/oversee/base.rb +5 -0
  57. data/config/importmap.rb +14 -0
  58. data/config/routes.rb +16 -10
  59. data/lib/generators/oversee/install_generator.rb +7 -0
  60. data/lib/oversee/engine.rb +19 -0
  61. data/lib/oversee/version.rb +1 -1
  62. data/lib/oversee.rb +13 -0
  63. data/lib/tasks/oversee_tasks.rake +6 -4
  64. metadata +71 -9
  65. data/app/jobs/oversee/application_job.rb +0 -4
  66. data/app/oversee/cards.rb +0 -2
  67. data/app/oversee/resource.rb +0 -10
  68. data/app/views/layouts/oversee/application.html.erb +0 -26
@@ -1,36 +1,65 @@
1
1
  class Oversee::Resource
2
- def initialize(resource_class:, resource: nil)
2
+ attr_reader :resource_class
3
+ attr_reader :resource_class_name
4
+ attr_reader :instance
5
+ attr_reader :associations
6
+
7
+ def initialize(resource_class:, instance: nil)
3
8
  @resource_class = resource_class
4
- @resource = resource
5
- @resource_class_name = resource_class.to_s
9
+ @instance = instance
6
10
  end
7
11
 
8
12
  # Route helpers
9
- def resources_path
13
+ def index_path
14
+ "/resources/#{resource_class_name}"
15
+ end
16
+
17
+ def show_path
18
+ # Rails.application.routes.url_helpers.resource_path(instance || object, resource_class_name:)
19
+ "/resources/#{resource_class_name}/#{instance.to_param}"
20
+ end
10
21
 
22
+ # Columns
23
+ def columns_for_create
24
+ excluded_columns = [resource_class.primary_key, "created_at", "updated_at"]
25
+ resource_class.columns_hash.except(*excluded_columns)
11
26
  end
12
27
 
13
- def resource_path
28
+ def columns_for_show
29
+
14
30
  end
15
31
 
16
32
  # Associations
33
+ # Structured by association macro
17
34
  def associations
18
- map = {
19
- belongs_to: [],
20
- has_many: [],
21
- has_one: [],
22
- has_and_belongs_to_many: []
23
- }
24
-
25
- @resource_class.reflect_on_all_associations.each do |association|
26
- map[association.macro] << {
27
- name: association.name,
28
- class_name: association.class_name,
29
- foreign_key: association.foreign_key,
30
- optional: association.macro == :belongs_to ? !!association.options[:optional] : true
31
- }
35
+ @associations ||= begin
36
+ map = Hash.new { |hash, key| hash[key] = [] }
37
+
38
+ @resource_class.reflect_on_all_associations.each do |association|
39
+ map[association.macro] << {
40
+ name: association.name,
41
+ class_name: association.class_name,
42
+ foreign_key: association.foreign_key,
43
+ optional: association.macro == :belongs_to ? !!association.options[:optional] : true,
44
+ through: association.options[:through],
45
+ rich_text: association.name.to_s.start_with?("rich_text_"),
46
+ }
47
+ end
48
+ map
32
49
  end
50
+ end
51
+
52
+ def foreign_keys
53
+ resource_class.reflections.map do |name, reflection|
54
+ reflection.foreign_key if reflection.belongs_to?
55
+ end.compact
56
+ end
57
+
58
+ def rich_text_associations
59
+ @rich_text_associations ||= associations[:has_one].select { |association| association[:rich_text] }
60
+ end
33
61
 
34
- return map
62
+ def resource_class_name
63
+ @resource_class_name ||= resource_class.to_s
35
64
  end
36
65
  end
@@ -1,4 +1,4 @@
1
- class Filter
1
+ class Oversee::Filter
2
2
  ALLOWED_OPERATORS = %w[eq in gt gte lt lte].freeze
3
3
 
4
4
  def initialize(collection:, params: nil)
@@ -23,7 +23,7 @@ class Filter
23
23
  private
24
24
 
25
25
  # Example params hash:
26
- # filters[kind][is][]=get => {"kind"=>{"is"=>["get"]}}
26
+ # filters[kind][eq][]=get => {"kind"=>{"is"=>["get"]}}
27
27
  def filters
28
28
  @filters ||= @params[:filters]
29
29
  end
@@ -1,4 +1,4 @@
1
- class Search
1
+ class Oversee::Search
2
2
  DEFAULT_SEARCHABLE_ATTRIBUTES = %w[name title email email_address]
3
3
 
4
4
  def initialize(collection:, resource_class:, query: nil)
@@ -0,0 +1,5 @@
1
+ class Oversee::Views::Base < Phlex::HTML
2
+ def around_template
3
+ render Oversee::Layout::Application.new { super }
4
+ end
5
+ end
@@ -0,0 +1,14 @@
1
+ # Application
2
+ pin "application", to: "oversee/application.js", preload: true
3
+
4
+ # Rich text editor
5
+ pin "trix", to: "https://unpkg.com/trix@2.1.8"
6
+ pin "@rails/actiontext", to: "https://unpkg.com/@rails/actiontext@8.0.0"
7
+
8
+ # Turbo
9
+ pin "@hotwired/turbo-rails", to: "https://unpkg.com/@hotwired/turbo-rails"
10
+
11
+ # Stimulus
12
+ pin "@hotwired/stimulus", to: "https://unpkg.com/@hotwired/stimulus/dist/stimulus.js"
13
+ pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
14
+ pin_all_from Oversee::Engine.root.join("app/javascript/oversee/controllers"), under: "controllers", to: "oversee/controllers"
data/config/routes.rb CHANGED
@@ -1,15 +1,21 @@
1
1
  Oversee::Engine.routes.draw do
2
2
  # Resources
3
- scope :resources, controller: "resources" do
4
- get ":resource_class_name/", action: :index, as: :resources
5
- get ":resource_class_name/table", action: :table, as: :resources_table
6
- get ":resource_class_name/new", action: :new, as: :new_resource
7
- post ":resource_class_name/", action: :create, as: :create_resource
8
- get ":resource_class_name/:id", action: :show, as: :resource
9
- get ":resource_class_name/:id/edit", action: :edit, as: :edit_resource
10
- patch ":resource_class_name/:id", action: :update, as: :update_resource
11
- delete ":resource_class_name/:id", action: :destroy, as: :destroy_resource
12
- get ":resource_class_name/:id/input_field", action: :input_field, as: :resource_input_field
3
+ scope ":resource_class_name", controller: "resources" do
4
+ get "/", action: :index, as: :resources
5
+ post "/", action: :create, as: :create_resource
6
+ get "/new", action: :new, as: :new_resource
7
+ get "/:id", action: :show, as: :resource
8
+ get "/:id/edit", action: :edit, as: :edit_resource
9
+ patch "/:id", action: :update, as: :update_resource
10
+ delete "/:id", action: :destroy, as: :destroy_resource
11
+ get "/table", action: :table, as: :resources_table
12
+
13
+ get "/:id/input_field", action: :input_field, as: :resource_input_field
14
+ get "/:id/association", action: :association, as: :resource_association
15
+
16
+
17
+ # To reach this route using Rails' route helpers, use resource_input_path(:resource_class_name, :id)
18
+ get "/:id/input", controller: "resources/fields", action: :input, as: :resource_input
13
19
  end
14
20
 
15
21
  root to: "dashboard#index"
@@ -0,0 +1,7 @@
1
+ class Oversee::InstallGenerator < Rails::Generators::Base
2
+ source_root File.expand_path('templates', __dir__)
3
+
4
+ def add_routes
5
+ route 'mount Oversee::Engine => "/oversee"'
6
+ end
7
+ end
@@ -1,3 +1,5 @@
1
+ require "importmap-rails"
2
+
1
3
  module Oversee
2
4
  class Engine < ::Rails::Engine
3
5
  isolate_namespace Oversee
@@ -6,5 +8,22 @@ module Oversee
6
8
  # Eager-loading to fetch all resources
7
9
  Rails.application.eager_load!
8
10
  end
11
+
12
+ initializer "oversee.assets" do |app|
13
+ if app.config.respond_to?(:assets)
14
+ app.config.assets.paths << root.join("app/assets/stylesheets")
15
+ app.config.assets.paths << root.join("app/javascript")
16
+ app.config.assets.precompile += %w[oversee_manifest]
17
+ end
18
+ end
19
+
20
+ initializer "oversee.importmap", before: "importmap" do |app|
21
+ Oversee.importmap.draw(root.join("config/importmap.rb"))
22
+ Oversee.importmap.cache_sweeper(watches: root.join("app/javascript"))
23
+
24
+ ActiveSupport.on_load(:action_controller_base) do
25
+ before_action { Oversee.importmap.cache_sweeper.execute_if_updated }
26
+ end
27
+ end
9
28
  end
10
29
  end
@@ -1,3 +1,3 @@
1
1
  module Oversee
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.1"
3
3
  end
data/lib/oversee.rb CHANGED
@@ -11,6 +11,7 @@ require "phlex-rails"
11
11
 
12
12
  # Pagy
13
13
  require "pagy"
14
+ require "pagy/extras/i18n"
14
15
 
15
16
  # Zeitwerk
16
17
  loader = Zeitwerk::Loader.for_gem
@@ -18,6 +19,9 @@ loader.ignore("#{__dir__}/generators")
18
19
  loader.setup
19
20
 
20
21
  module Oversee
22
+
23
+ mattr_accessor :importmap, default: Importmap::Map.new
24
+
21
25
  class << self
22
26
 
23
27
  def application_name
@@ -41,4 +45,13 @@ module Oversee
41
45
  files.map! { |f| f.split(root.to_s).last.delete_suffix(".rb").classify.prepend("Cards::") }
42
46
  end
43
47
  end
48
+
49
+ # VIEWS
50
+ module Views
51
+ end
52
+
53
+ # COMPONENTS
54
+ module Components
55
+ extend Phlex::Kit
56
+ end
44
57
  end
@@ -1,4 +1,6 @@
1
- # desc "Explaining what the task does"
2
- # task :oversee do
3
- # # Task goes here
4
- # end
1
+ namespace :oversee do
2
+ desc "Installs Oversee into your application"
3
+ task :install do
4
+ # TODO Add route mounting
5
+ end
6
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oversee
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elvinas Predkelis
@@ -9,10 +9,10 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-10-18 00:00:00.000000000 Z
12
+ date: 2024-12-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: rails
15
+ name: activerecord
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
18
  - - ">="
@@ -25,6 +25,48 @@ dependencies:
25
25
  - - ">="
26
26
  - !ruby/object:Gem::Version
27
27
  version: 7.0.0
28
+ - !ruby/object:Gem::Dependency
29
+ name: activesupport
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: 7.0.0
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: 7.0.0
42
+ - !ruby/object:Gem::Dependency
43
+ name: activestorage
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: 7.0.0
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: 7.0.0
56
+ - !ruby/object:Gem::Dependency
57
+ name: importmap-rails
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
28
70
  - !ruby/object:Gem::Dependency
29
71
  name: pagy
30
72
  requirement: !ruby/object:Gem::Requirement
@@ -105,8 +147,11 @@ files:
105
147
  - LICENCE
106
148
  - README.md
107
149
  - Rakefile
150
+ - app/assets/config/oversee_manifest.js
108
151
  - app/components/oversee/base.rb
109
152
  - app/components/oversee/card.rb
153
+ - app/components/oversee/dashboard/actions.rb
154
+ - app/components/oversee/dashboard/filter.rb
110
155
  - app/components/oversee/dashboard/filters.rb
111
156
  - app/components/oversee/dashboard/header.rb
112
157
  - app/components/oversee/dashboard/index.rb
@@ -114,21 +159,33 @@ files:
114
159
  - app/components/oversee/dashboard/pagination.rb
115
160
  - app/components/oversee/dashboard/sidebar.rb
116
161
  - app/components/oversee/dashboard/tailwind.rb
162
+ - app/components/oversee/field.rb
117
163
  - app/components/oversee/field/display.rb
118
164
  - app/components/oversee/field/form.rb
119
165
  - app/components/oversee/field/input.rb
166
+ - app/components/oversee/field/input/belongs_to.rb
120
167
  - app/components/oversee/field/input/boolean.rb
168
+ - app/components/oversee/field/input/date.rb
121
169
  - app/components/oversee/field/input/datetime.rb
122
170
  - app/components/oversee/field/input/integer.rb
171
+ - app/components/oversee/field/input/json.rb
172
+ - app/components/oversee/field/input/rich_text.rb
123
173
  - app/components/oversee/field/input/string.rb
124
174
  - app/components/oversee/field/label.rb
175
+ - app/components/oversee/field/set.rb
125
176
  - app/components/oversee/field/value.rb
177
+ - app/components/oversee/field/value/belongs_to.rb
126
178
  - app/components/oversee/field/value/boolean.rb
179
+ - app/components/oversee/field/value/date.rb
127
180
  - app/components/oversee/field/value/datetime.rb
128
181
  - app/components/oversee/field/value/enum.rb
129
182
  - app/components/oversee/field/value/integer.rb
183
+ - app/components/oversee/field/value/json.rb
184
+ - app/components/oversee/field/value/rich_text.rb
130
185
  - app/components/oversee/field/value/string.rb
131
186
  - app/components/oversee/field/value/text.rb
187
+ - app/components/oversee/flash.rb
188
+ - app/components/oversee/layout/application.rb
132
189
  - app/components/oversee/resources/base.rb
133
190
  - app/components/oversee/resources/errors.rb
134
191
  - app/components/oversee/resources/form.rb
@@ -146,17 +203,22 @@ files:
146
203
  - app/controllers/oversee/dashboard_controller.rb
147
204
  - app/controllers/oversee/resources/fields_controller.rb
148
205
  - app/controllers/oversee/resources_controller.rb
149
- - app/jobs/oversee/application_job.rb
206
+ - app/javascript/oversee/application.js
207
+ - app/javascript/oversee/controllers/clipboard_controller.js
208
+ - app/javascript/oversee/controllers/index.js
209
+ - app/javascript/oversee/controllers/notification_controller.js
210
+ - app/javascript/oversee/controllers/reveal_controller.js
211
+ - app/javascript/oversee/controllers/sidebar/state_controller.js
150
212
  - app/models/oversee/application_record.rb
151
213
  - app/models/oversee/resource.rb
152
- - app/oversee/cards.rb
153
- - app/oversee/filter.rb
154
- - app/oversee/resource.rb
155
- - app/oversee/search.rb
156
- - app/views/layouts/oversee/application.html.erb
214
+ - app/service/oversee/filter.rb
215
+ - app/service/oversee/search.rb
216
+ - app/views/oversee/base.rb
217
+ - config/importmap.rb
157
218
  - config/locales/en.yml
158
219
  - config/locales/oversee.en.yml
159
220
  - config/routes.rb
221
+ - lib/generators/oversee/install_generator.rb
160
222
  - lib/oversee.rb
161
223
  - lib/oversee/configuration.rb
162
224
  - lib/oversee/engine.rb
@@ -1,4 +0,0 @@
1
- module Oversee
2
- class ApplicationJob < ActiveJob::Base
3
- end
4
- end
data/app/oversee/cards.rb DELETED
@@ -1,2 +0,0 @@
1
- class Cards
2
- end
@@ -1,10 +0,0 @@
1
- class Resource
2
- def initialize(resource)
3
- @resource = resource
4
- end
5
-
6
- def columns_for_create
7
- excluded_columns = [@resource.class.primary_key, "created_at", "updated_at"]
8
- @resource.columns_hash.except(*excluded_columns)
9
- end
10
- end
@@ -1,26 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
5
- <meta name="ROBOTS" content="NOODP">
6
-
7
- <title>Oversee | <%= Oversee.application_name %></title>
8
- <%= csrf_meta_tags %>
9
- <%= csp_meta_tag %>
10
- <%= render Oversee::Dashboard::Javascript.new %>
11
- <%= render Oversee::Dashboard::Tailwind.new %>
12
- </head>
13
- <body class="min-h-screen bg-gray-100 p-8">
14
- <pre><%#= Oversee.filtered_resources.to_yaml %></pre>
15
- <div class="flex gap-4 w-full">
16
- <div class="w-72 shrink-0">
17
- <%= render Oversee::Dashboard::Sidebar.new %>
18
- </div>
19
- <div class="w-full overflow-scroll">
20
- <div class="bg-white rounded-lg overflow-clip">
21
- <%= yield %>
22
- </div>
23
- </div>
24
- </div>
25
- </body>
26
- </html>