oversee 0.2.0 → 0.3.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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/oversee_manifest.js +2 -0
  3. data/app/components/oversee/dashboard/filters.rb +23 -19
  4. data/app/components/oversee/dashboard/header.rb +34 -18
  5. data/app/components/oversee/dashboard/index.rb +23 -11
  6. data/app/components/oversee/dashboard/javascript.rb +4 -4
  7. data/app/components/oversee/dashboard/pagination.rb +1 -1
  8. data/app/components/oversee/dashboard/sidebar.rb +38 -1
  9. data/app/components/oversee/dashboard/tailwind.rb +30 -1
  10. data/app/components/oversee/field/display.rb +19 -10
  11. data/app/components/oversee/field/form.rb +4 -23
  12. data/app/components/oversee/field/input/belongs_to.rb +22 -0
  13. data/app/components/oversee/field/input/boolean.rb +1 -11
  14. data/app/components/oversee/field/input/datetime.rb +1 -11
  15. data/app/components/oversee/field/input/integer.rb +1 -11
  16. data/app/components/oversee/field/input/rich_text.rb +18 -0
  17. data/app/components/oversee/field/input/string.rb +1 -11
  18. data/app/components/oversee/field/input.rb +13 -5
  19. data/app/components/oversee/field/label.rb +3 -2
  20. data/app/components/oversee/field/value/belongs_to.rb +21 -0
  21. data/app/components/oversee/field/value/datetime.rb +1 -1
  22. data/app/components/oversee/field/value/rich_text.rb +9 -0
  23. data/app/components/oversee/field/value.rb +11 -5
  24. data/app/components/oversee/layout/application.rb +46 -0
  25. data/app/components/oversee/resources/index.rb +21 -2
  26. data/app/components/oversee/resources/new.rb +7 -3
  27. data/app/components/oversee/resources/show.rb +150 -69
  28. data/app/components/oversee/resources/table.rb +7 -1
  29. data/app/controllers/oversee/dashboard_controller.rb +1 -1
  30. data/app/controllers/oversee/resources/fields_controller.rb +20 -36
  31. data/app/controllers/oversee/resources_controller.rb +22 -22
  32. data/app/javascript/oversee/application.js +3 -0
  33. data/app/javascript/oversee/controllers/index.js +8 -0
  34. data/app/javascript/oversee/controllers/reveal_controller.js +7 -0
  35. data/app/javascript/oversee/controllers/sidebar/state_controller.js +21 -0
  36. data/app/models/oversee/resource.rb +43 -17
  37. data/app/{oversee → service/oversee}/filter.rb +2 -2
  38. data/app/{oversee → service/oversee}/search.rb +1 -1
  39. data/app/views/oversee/base.rb +5 -0
  40. data/config/importmap.rb +14 -0
  41. data/config/routes.rb +16 -10
  42. data/lib/generators/oversee/install_generator.rb +7 -0
  43. data/lib/oversee/engine.rb +19 -0
  44. data/lib/oversee/version.rb +1 -1
  45. data/lib/oversee.rb +12 -0
  46. data/lib/tasks/oversee_tasks.rake +6 -4
  47. metadata +31 -8
  48. data/app/jobs/oversee/application_job.rb +0 -4
  49. data/app/oversee/cards.rb +0 -2
  50. data/app/oversee/resource.rb +0 -10
  51. data/app/views/layouts/oversee/application.html.erb +0 -26
@@ -1,8 +1,15 @@
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 :rich_text_associations
6
+
7
+ attr_accessor :associations
8
+
9
+ def initialize(resource_class:, instance: nil)
3
10
  @resource_class = resource_class
4
- @resource = resource
5
11
  @resource_class_name = resource_class.to_s
12
+ @instance = instance
6
13
  end
7
14
 
8
15
  # Route helpers
@@ -13,24 +20,43 @@ class Oversee::Resource
13
20
  def resource_path
14
21
  end
15
22
 
23
+ # Columns
24
+ def columns_for_create
25
+ excluded_columns = [resource_class.primary_key, "created_at", "updated_at"]
26
+ resource_class.columns_hash.except(*excluded_columns)
27
+ end
28
+
29
+ def columns_for_show
30
+
31
+ end
32
+
16
33
  # Associations
34
+ # Structured by association macro
17
35
  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
- }
36
+ @associations ||= begin
37
+ map = Hash.new { |hash, key| hash[key] = [] }
38
+
39
+ @resource_class.reflect_on_all_associations.each do |association|
40
+ map[association.macro] << {
41
+ name: association.name,
42
+ class_name: association.class_name,
43
+ foreign_key: association.foreign_key,
44
+ optional: association.macro == :belongs_to ? !!association.options[:optional] : true,
45
+ through: association.options[:through],
46
+ rich_text: association.name.to_s.start_with?("rich_text_"),
47
+ }
48
+ end
49
+ map
32
50
  end
51
+ end
52
+
53
+ def foreign_keys
54
+ resource_class.reflections.map do |name, reflection|
55
+ reflection.foreign_key if reflection.belongs_to?
56
+ end.compact
57
+ end
33
58
 
34
- return map
59
+ def rich_text_associations
60
+ @rich_text_associations ||= associations[:has_one].select { |association| association[:rich_text] }
35
61
  end
36
62
  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.0"
3
3
  end
data/lib/oversee.rb CHANGED
@@ -18,6 +18,9 @@ loader.ignore("#{__dir__}/generators")
18
18
  loader.setup
19
19
 
20
20
  module Oversee
21
+
22
+ mattr_accessor :importmap, default: Importmap::Map.new
23
+
21
24
  class << self
22
25
 
23
26
  def application_name
@@ -41,4 +44,13 @@ module Oversee
41
44
  files.map! { |f| f.split(root.to_s).last.delete_suffix(".rb").classify.prepend("Cards::") }
42
45
  end
43
46
  end
47
+
48
+ # VIEWS
49
+ module Views
50
+ end
51
+
52
+ # COMPONENTS
53
+ module Components
54
+ extend Phlex::Kit
55
+ end
44
56
  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.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elvinas Predkelis
@@ -9,7 +9,7 @@ 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-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -25,6 +25,20 @@ dependencies:
25
25
  - - ">="
26
26
  - !ruby/object:Gem::Version
27
27
  version: 7.0.0
28
+ - !ruby/object:Gem::Dependency
29
+ name: importmap-rails
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
28
42
  - !ruby/object:Gem::Dependency
29
43
  name: pagy
30
44
  requirement: !ruby/object:Gem::Requirement
@@ -105,6 +119,7 @@ files:
105
119
  - LICENCE
106
120
  - README.md
107
121
  - Rakefile
122
+ - app/assets/config/oversee_manifest.js
108
123
  - app/components/oversee/base.rb
109
124
  - app/components/oversee/card.rb
110
125
  - app/components/oversee/dashboard/filters.rb
@@ -117,18 +132,23 @@ files:
117
132
  - app/components/oversee/field/display.rb
118
133
  - app/components/oversee/field/form.rb
119
134
  - app/components/oversee/field/input.rb
135
+ - app/components/oversee/field/input/belongs_to.rb
120
136
  - app/components/oversee/field/input/boolean.rb
121
137
  - app/components/oversee/field/input/datetime.rb
122
138
  - app/components/oversee/field/input/integer.rb
139
+ - app/components/oversee/field/input/rich_text.rb
123
140
  - app/components/oversee/field/input/string.rb
124
141
  - app/components/oversee/field/label.rb
125
142
  - app/components/oversee/field/value.rb
143
+ - app/components/oversee/field/value/belongs_to.rb
126
144
  - app/components/oversee/field/value/boolean.rb
127
145
  - app/components/oversee/field/value/datetime.rb
128
146
  - app/components/oversee/field/value/enum.rb
129
147
  - app/components/oversee/field/value/integer.rb
148
+ - app/components/oversee/field/value/rich_text.rb
130
149
  - app/components/oversee/field/value/string.rb
131
150
  - app/components/oversee/field/value/text.rb
151
+ - app/components/oversee/layout/application.rb
132
152
  - app/components/oversee/resources/base.rb
133
153
  - app/components/oversee/resources/errors.rb
134
154
  - app/components/oversee/resources/form.rb
@@ -146,17 +166,20 @@ files:
146
166
  - app/controllers/oversee/dashboard_controller.rb
147
167
  - app/controllers/oversee/resources/fields_controller.rb
148
168
  - app/controllers/oversee/resources_controller.rb
149
- - app/jobs/oversee/application_job.rb
169
+ - app/javascript/oversee/application.js
170
+ - app/javascript/oversee/controllers/index.js
171
+ - app/javascript/oversee/controllers/reveal_controller.js
172
+ - app/javascript/oversee/controllers/sidebar/state_controller.js
150
173
  - app/models/oversee/application_record.rb
151
174
  - 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
175
+ - app/service/oversee/filter.rb
176
+ - app/service/oversee/search.rb
177
+ - app/views/oversee/base.rb
178
+ - config/importmap.rb
157
179
  - config/locales/en.yml
158
180
  - config/locales/oversee.en.yml
159
181
  - config/routes.rb
182
+ - lib/generators/oversee/install_generator.rb
160
183
  - lib/oversee.rb
161
184
  - lib/oversee/configuration.rb
162
185
  - 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>