oversee 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +53 -14
  3. data/app/components/oversee/{application_component.rb → base.rb} +1 -1
  4. data/app/components/oversee/card.rb +13 -0
  5. data/app/components/oversee/dashboard/filters.rb +54 -0
  6. data/app/components/oversee/dashboard/header.rb +41 -0
  7. data/app/components/oversee/dashboard/index.rb +24 -0
  8. data/app/components/oversee/dashboard/javascript.rb +9 -0
  9. data/app/components/oversee/dashboard/pagination.rb +23 -0
  10. data/app/components/oversee/dashboard/sidebar.rb +53 -0
  11. data/app/components/oversee/dashboard/tailwind.rb +33 -0
  12. data/app/components/oversee/field/display.rb +29 -0
  13. data/app/components/oversee/field/form.rb +49 -0
  14. data/app/components/oversee/field/input/boolean.rb +23 -0
  15. data/app/components/oversee/field/input/datetime.rb +20 -0
  16. data/app/components/oversee/field/input/integer.rb +20 -0
  17. data/app/components/oversee/field/input/string.rb +20 -0
  18. data/app/components/oversee/field/input.rb +26 -0
  19. data/app/components/oversee/field/label.rb +24 -0
  20. data/app/components/oversee/field/value/boolean.rb +50 -0
  21. data/app/components/oversee/field/value/datetime.rb +9 -0
  22. data/app/components/oversee/field/value/enum.rb +9 -0
  23. data/app/components/oversee/field/value/integer.rb +9 -0
  24. data/app/components/oversee/field/value/string.rb +20 -0
  25. data/app/components/oversee/field/value/text.rb +9 -0
  26. data/app/components/oversee/field/value.rb +34 -0
  27. data/app/components/oversee/resources/base.rb +4 -0
  28. data/app/components/oversee/resources/errors.rb +41 -0
  29. data/app/components/oversee/resources/form.rb +49 -0
  30. data/app/components/oversee/resources/index.rb +26 -0
  31. data/app/components/oversee/resources/new.rb +17 -0
  32. data/app/components/oversee/resources/show.rb +126 -0
  33. data/app/components/oversee/resources/table.rb +109 -0
  34. data/app/components/oversee/table/body.rb +13 -0
  35. data/app/components/oversee/table/data.rb +5 -0
  36. data/app/components/oversee/table/head.rb +9 -0
  37. data/app/components/oversee/table/row.rb +9 -0
  38. data/app/components/oversee/table.rb +21 -0
  39. data/app/controllers/oversee/dashboard_controller.rb +4 -0
  40. data/app/controllers/oversee/resources_controller.rb +62 -23
  41. data/app/models/oversee/resource.rb +36 -0
  42. data/app/oversee/filter.rb +39 -0
  43. data/app/oversee/search.rb +34 -0
  44. data/app/views/layouts/oversee/application.html.erb +5 -5
  45. data/config/locales/en.yml +4 -0
  46. data/config/locales/oversee.en.yml +4 -0
  47. data/config/routes.rb +10 -10
  48. data/lib/oversee/configuration.rb +3 -0
  49. data/lib/oversee/version.rb +1 -1
  50. data/lib/oversee.rb +14 -2
  51. metadata +71 -47
  52. data/app/assets/config/oversee_manifest.js +0 -1
  53. data/app/assets/stylesheets/oversee/application.css +0 -15
  54. data/app/components/oversee/card_component.rb +0 -15
  55. data/app/components/oversee/dashboard/sidebar_component.rb +0 -127
  56. data/app/components/oversee/field_component.rb +0 -39
  57. data/app/components/oversee/field_label_component.rb +0 -155
  58. data/app/components/oversee/fields/display_row_component.rb +0 -58
  59. data/app/components/oversee/fields/input/boolean_component.rb +0 -26
  60. data/app/components/oversee/fields/input/datetime_component.rb +0 -27
  61. data/app/components/oversee/fields/input/integer_component.rb +0 -26
  62. data/app/components/oversee/fields/input/string_component.rb +0 -26
  63. data/app/components/oversee/fields/value/boolean_component.rb +0 -44
  64. data/app/components/oversee/fields/value/datetime_component.rb +0 -16
  65. data/app/components/oversee/fields/value/enum_component.rb +0 -16
  66. data/app/components/oversee/fields/value/integer_component.rb +0 -16
  67. data/app/components/oversee/fields/value/string_component.rb +0 -23
  68. data/app/components/oversee/fields/value/text_component.rb +0 -16
  69. data/app/helpers/oversee/application_helper.rb +0 -5
  70. data/app/mailers/oversee/application_mailer.rb +0 -6
  71. data/app/views/oversee/application/_javascript.html.erb +0 -17
  72. data/app/views/oversee/dashboard/show.html.erb +0 -18
  73. data/app/views/oversee/resources/_form.html.erb +0 -10
  74. data/app/views/oversee/resources/_input_field.html.erb +0 -20
  75. data/app/views/oversee/resources/edit.html.erb +0 -30
  76. data/app/views/oversee/resources/index.html.erb +0 -59
  77. data/app/views/oversee/resources/input_field.html.erb +0 -1
  78. data/app/views/oversee/resources/new.html.erb +0 -28
  79. data/app/views/oversee/resources/show.html.erb +0 -51
  80. data/app/views/oversee/resources/update.turbo_stream.erb +0 -3
  81. data/app/views/shared/_sidebar.html.erb +0 -32
@@ -0,0 +1,36 @@
1
+ class Oversee::Resource
2
+ def initialize(resource_class:, resource: nil)
3
+ @resource_class = resource_class
4
+ @resource = resource
5
+ @resource_class_name = resource_class.to_s
6
+ end
7
+
8
+ # Route helpers
9
+ def resources_path
10
+
11
+ end
12
+
13
+ def resource_path
14
+ end
15
+
16
+ # Associations
17
+ 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
+ }
32
+ end
33
+
34
+ return map
35
+ end
36
+ end
@@ -0,0 +1,39 @@
1
+ class Filter
2
+ ALLOWED_OPERATORS = %w[eq in gt gte lt lte].freeze
3
+
4
+ def initialize(collection:, params: nil)
5
+ @collection = collection
6
+ @params = params
7
+ end
8
+
9
+
10
+ def apply
11
+ return @collection if filters.blank?
12
+
13
+ filters.each do |key, constraint|
14
+ operator = constraint.keys.first
15
+ next unless ALLOWED_OPERATORS.include?(operator)
16
+
17
+ value = constraint[operator]
18
+ chain(key:, operator:, value:)
19
+ end
20
+ return @collection
21
+ end
22
+
23
+ private
24
+
25
+ # Example params hash:
26
+ # filters[kind][is][]=get => {"kind"=>{"is"=>["get"]}}
27
+ def filters
28
+ @filters ||= @params[:filters]
29
+ end
30
+
31
+ def chain(key:, operator:, value:)
32
+ @collection = case operator
33
+ when "eq"
34
+ @collection.then { _1.where(key => value) }
35
+ when "in"
36
+ @collection.then { _1.where(key => value) }
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,34 @@
1
+ class Search
2
+ DEFAULT_SEARCHABLE_ATTRIBUTES = %w[name title email email_address]
3
+
4
+ def initialize(collection:, resource_class:, query: nil)
5
+ @collection = collection
6
+ @resource_class = resource_class
7
+ @query = query
8
+ end
9
+
10
+ def call
11
+ return @collection if @query.blank? || @resource_class.blank?
12
+ default_searchable_by
13
+ end
14
+
15
+ def default_searchable_attribute
16
+ DEFAULT_SEARCHABLE_ATTRIBUTES.each do |attr|
17
+ return attr if @resource_class.column_names.include?(attr)
18
+ end
19
+
20
+ return @resource_class.primary_key
21
+ end
22
+
23
+ private
24
+
25
+ def default_searchable_by
26
+ return @collection.where(default_searchable_attribute => @query) if @resource_class.primary_key == default_searchable_attribute
27
+
28
+ @collection
29
+ .where(@resource_class.arel_table[default_searchable_attribute]
30
+ .matches("%#{@query}%"))
31
+ end
32
+
33
+
34
+ end
@@ -7,17 +7,17 @@
7
7
  <title>Oversee | <%= Oversee.application_name %></title>
8
8
  <%= csrf_meta_tags %>
9
9
  <%= csp_meta_tag %>
10
-
11
- <%# stylesheet_link_tag "oversee/application", media: "all" %>
12
- <%= render "oversee/application/javascript" %>
10
+ <%= render Oversee::Dashboard::Javascript.new %>
11
+ <%= render Oversee::Dashboard::Tailwind.new %>
13
12
  </head>
14
13
  <body class="min-h-screen bg-gray-100 p-8">
14
+ <pre><%#= Oversee.filtered_resources.to_yaml %></pre>
15
15
  <div class="flex gap-4 w-full">
16
16
  <div class="w-72 shrink-0">
17
- <%= render Oversee::Dashboard::SidebarComponent.new %>
17
+ <%= render Oversee::Dashboard::Sidebar.new %>
18
18
  </div>
19
19
  <div class="w-full overflow-scroll">
20
- <div class="bg-white rounded-lg border overflow-clip">
20
+ <div class="bg-white rounded-lg overflow-clip">
21
21
  <%= yield %>
22
22
  </div>
23
23
  </div>
@@ -0,0 +1,4 @@
1
+ en:
2
+ pagy:
3
+ prev: "« Prev"
4
+ next: "Next »"
@@ -0,0 +1,4 @@
1
+ en:
2
+ pagy:
3
+ prev: "« Prev"
4
+ next: "Next »"
data/config/routes.rb CHANGED
@@ -1,16 +1,16 @@
1
1
  Oversee::Engine.routes.draw do
2
-
3
2
  # Resources
4
3
  scope :resources, controller: "resources" do
5
- get ":resource/", action: :index, as: :resources
6
- get ":resource/new", action: :new, as: :new_resource
7
- post ":resource_class/", action: :create, as: :create_resource
8
- get ":resource/:id", action: :show, as: :resource
9
- get ":resource/:id/edit", action: :edit, as: :edit_resource
10
- patch ":resource/:id", action: :update, as: :update_resource
11
- delete ":resource/:id", action: :destroy, as: :destroy_resource
12
- get ":resource/:id/input_field", action: :input_field, as: :input_field
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
13
13
  end
14
14
 
15
- root to: "dashboard#show"
15
+ root to: "dashboard#index"
16
16
  end
@@ -2,14 +2,17 @@
2
2
 
3
3
  module Oversee
4
4
  class Configuration
5
+ # Attributes
5
6
  attr_accessor :excluded_resources
6
7
  attr_accessor :filter_sensitive_columns
7
8
  attr_accessor :sensitive_column_titles
9
+ attr_accessor :per_page
8
10
 
9
11
  def initialize
10
12
  @excluded_resources = []
11
13
  @filter_sensitive_columns = true
12
14
  @sensitive_column_titles = %w[password password_digest access_token]
15
+ @per_page = 24
13
16
  end
14
17
  end
15
18
 
@@ -1,3 +1,3 @@
1
1
  module Oversee
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/oversee.rb CHANGED
@@ -1,10 +1,15 @@
1
+ # Zeitwerk
1
2
  require "zeitwerk"
2
3
 
4
+ # Oversee
3
5
  require "oversee/version"
4
6
  require "oversee/engine"
5
7
  require "oversee/configuration"
6
8
 
9
+ # Phlex
7
10
  require "phlex-rails"
11
+
12
+ # Pagy
8
13
  require "pagy"
9
14
 
10
15
  # Zeitwerk
@@ -19,10 +24,17 @@ module Oversee
19
24
  Rails.application.class.to_s.gsub("::Application", "")
20
25
  end
21
26
 
22
- def allowed_resource_list
23
- ApplicationRecord.descendants
27
+ # Resources
28
+ def application_resources(filtered: true)
29
+ resources = ::ApplicationRecord.descendants
30
+ resources = resources.filter { |klass| !Oversee.configuration.excluded_resources.include?(klass.to_s) } if filtered
31
+ end
32
+
33
+ def application_resource_names(filtered: true)
34
+ application_resources(filtered:).map(&:to_s)
24
35
  end
25
36
 
37
+ # Cards
26
38
  def card_class_names
27
39
  root = Rails.root.join("app/oversee/cards/")
28
40
  files = Dir.glob(root.join("**/*.rb"))
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.1.1
4
+ version: 0.2.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-10 00:00:00.000000000 Z
12
+ date: 2024-10-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -17,70 +17,84 @@ dependencies:
17
17
  requirements:
18
18
  - - ">="
19
19
  - !ruby/object:Gem::Version
20
- version: 7.0.3
20
+ version: 7.0.0
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - ">="
26
26
  - !ruby/object:Gem::Version
27
- version: 7.0.3
27
+ version: 7.0.0
28
28
  - !ruby/object:Gem::Dependency
29
- name: zeitwerk
29
+ name: pagy
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
32
  - - ">="
33
33
  - !ruby/object:Gem::Version
34
- version: 2.6.12
34
+ version: 7.0.0
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - ">="
40
40
  - !ruby/object:Gem::Version
41
- version: 2.6.12
41
+ version: 7.0.0
42
42
  - !ruby/object:Gem::Dependency
43
- name: pagy
43
+ name: phlex-rails
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
46
  - - ">="
47
47
  - !ruby/object:Gem::Version
48
- version: '3.5'
48
+ version: 2.0.0.beta2
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - ">="
54
54
  - !ruby/object:Gem::Version
55
- version: '3.5'
55
+ version: 2.0.0.beta2
56
56
  - !ruby/object:Gem::Dependency
57
- name: phlex-rails
57
+ name: phlex-icons-iconoir
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
60
  - - ">="
61
61
  - !ruby/object:Gem::Version
62
- version: 1.1.1
62
+ version: 0.1.0
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - ">="
68
68
  - !ruby/object:Gem::Version
69
- version: 1.1.1
69
+ version: 0.1.0
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: turbo-rails
72
72
  requirement: !ruby/object:Gem::Requirement
73
73
  requirements:
74
74
  - - ">="
75
75
  - !ruby/object:Gem::Version
76
- version: '0'
76
+ version: 2.0.0
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: 2.0.0
84
+ - !ruby/object:Gem::Dependency
85
+ name: zeitwerk
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: 2.6.12
77
91
  type: :runtime
78
92
  prerelease: false
79
93
  version_requirements: !ruby/object:Gem::Requirement
80
94
  requirements:
81
95
  - - ">="
82
96
  - !ruby/object:Gem::Version
83
- version: '0'
97
+ version: 2.6.12
84
98
  description: Lightweight admin dashboard for Rails
85
99
  email:
86
100
  - info@primevise.com
@@ -91,47 +105,57 @@ files:
91
105
  - LICENCE
92
106
  - README.md
93
107
  - Rakefile
94
- - app/assets/config/oversee_manifest.js
95
- - app/assets/stylesheets/oversee/application.css
96
- - app/components/oversee/application_component.rb
97
- - app/components/oversee/card_component.rb
98
- - app/components/oversee/dashboard/sidebar_component.rb
99
- - app/components/oversee/field_component.rb
100
- - app/components/oversee/field_label_component.rb
101
- - app/components/oversee/fields/display_row_component.rb
102
- - app/components/oversee/fields/input/boolean_component.rb
103
- - app/components/oversee/fields/input/datetime_component.rb
104
- - app/components/oversee/fields/input/integer_component.rb
105
- - app/components/oversee/fields/input/string_component.rb
106
- - app/components/oversee/fields/value/boolean_component.rb
107
- - app/components/oversee/fields/value/datetime_component.rb
108
- - app/components/oversee/fields/value/enum_component.rb
109
- - app/components/oversee/fields/value/integer_component.rb
110
- - app/components/oversee/fields/value/string_component.rb
111
- - app/components/oversee/fields/value/text_component.rb
108
+ - app/components/oversee/base.rb
109
+ - app/components/oversee/card.rb
110
+ - app/components/oversee/dashboard/filters.rb
111
+ - app/components/oversee/dashboard/header.rb
112
+ - app/components/oversee/dashboard/index.rb
113
+ - app/components/oversee/dashboard/javascript.rb
114
+ - app/components/oversee/dashboard/pagination.rb
115
+ - app/components/oversee/dashboard/sidebar.rb
116
+ - app/components/oversee/dashboard/tailwind.rb
117
+ - app/components/oversee/field/display.rb
118
+ - app/components/oversee/field/form.rb
119
+ - app/components/oversee/field/input.rb
120
+ - app/components/oversee/field/input/boolean.rb
121
+ - app/components/oversee/field/input/datetime.rb
122
+ - app/components/oversee/field/input/integer.rb
123
+ - app/components/oversee/field/input/string.rb
124
+ - app/components/oversee/field/label.rb
125
+ - app/components/oversee/field/value.rb
126
+ - app/components/oversee/field/value/boolean.rb
127
+ - app/components/oversee/field/value/datetime.rb
128
+ - app/components/oversee/field/value/enum.rb
129
+ - app/components/oversee/field/value/integer.rb
130
+ - app/components/oversee/field/value/string.rb
131
+ - app/components/oversee/field/value/text.rb
132
+ - app/components/oversee/resources/base.rb
133
+ - app/components/oversee/resources/errors.rb
134
+ - app/components/oversee/resources/form.rb
135
+ - app/components/oversee/resources/index.rb
136
+ - app/components/oversee/resources/new.rb
137
+ - app/components/oversee/resources/show.rb
138
+ - app/components/oversee/resources/table.rb
139
+ - app/components/oversee/table.rb
140
+ - app/components/oversee/table/body.rb
141
+ - app/components/oversee/table/data.rb
142
+ - app/components/oversee/table/head.rb
143
+ - app/components/oversee/table/row.rb
112
144
  - app/controllers/oversee/application_controller.rb
113
145
  - app/controllers/oversee/base_controller.rb
114
146
  - app/controllers/oversee/dashboard_controller.rb
115
147
  - app/controllers/oversee/resources/fields_controller.rb
116
148
  - app/controllers/oversee/resources_controller.rb
117
- - app/helpers/oversee/application_helper.rb
118
149
  - app/jobs/oversee/application_job.rb
119
- - app/mailers/oversee/application_mailer.rb
120
150
  - app/models/oversee/application_record.rb
151
+ - app/models/oversee/resource.rb
121
152
  - app/oversee/cards.rb
153
+ - app/oversee/filter.rb
122
154
  - app/oversee/resource.rb
155
+ - app/oversee/search.rb
123
156
  - app/views/layouts/oversee/application.html.erb
124
- - app/views/oversee/application/_javascript.html.erb
125
- - app/views/oversee/dashboard/show.html.erb
126
- - app/views/oversee/resources/_form.html.erb
127
- - app/views/oversee/resources/_input_field.html.erb
128
- - app/views/oversee/resources/edit.html.erb
129
- - app/views/oversee/resources/index.html.erb
130
- - app/views/oversee/resources/input_field.html.erb
131
- - app/views/oversee/resources/new.html.erb
132
- - app/views/oversee/resources/show.html.erb
133
- - app/views/oversee/resources/update.turbo_stream.erb
134
- - app/views/shared/_sidebar.html.erb
157
+ - config/locales/en.yml
158
+ - config/locales/oversee.en.yml
135
159
  - config/routes.rb
136
160
  - lib/oversee.rb
137
161
  - lib/oversee/configuration.rb
@@ -152,7 +176,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
152
176
  requirements:
153
177
  - - ">="
154
178
  - !ruby/object:Gem::Version
155
- version: '0'
179
+ version: 3.3.1
156
180
  required_rubygems_version: !ruby/object:Gem::Requirement
157
181
  requirements:
158
182
  - - ">="
@@ -1 +0,0 @@
1
- //= link_directory ../stylesheets/oversee .css
@@ -1,15 +0,0 @@
1
- /*
2
- * This is a manifest file that'll be compiled into application.css, which will include all the files
3
- * listed below.
4
- *
5
- * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
- * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
- *
8
- * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
- * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
- * files in this directory. Styles in this file should be added after the last require_* statement.
11
- * It is generally better to create a new file per style scope.
12
- *
13
- *= require_tree .
14
- *= require_self
15
- */
@@ -1,15 +0,0 @@
1
- module Oversee
2
- class CardComponent < Phlex::HTML
3
- def initialize(card_name: )
4
- @card_name = card_name
5
- @card = card_name.constantize.new
6
- end
7
-
8
- def view_template
9
- div(class: "bg-white rounded-md border shadow-sm p-4") do
10
- p(class: "text-xs uppercase font-medium text-gray-400") { @card.label }
11
- h4(class: "mt-2 text-gray-900 text-2xl") { @card.value }
12
- end
13
- end
14
- end
15
- end
@@ -1,127 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Oversee::Dashboard::SidebarComponent < Oversee::ApplicationComponent
4
- include Phlex::Rails::Helpers::LinkTo
5
- include Phlex::Rails::Helpers::ButtonTo
6
-
7
- def view_template
8
- div(class: "bg-white border p-4 rounded-lg") do
9
-
10
- p(class: "text-[0.7rem] uppercase text-gray-400 font-medium mb-2") { "Menu" }
11
- ul(class: "text-sm text-gray-700") do
12
- li do
13
- link_to root_path,
14
- class:
15
- "flex items-center gap-2 hover:bg-gray-50 p-2 rounded-lg" do
16
- layout_icon
17
- span { "Dashboard" }
18
- end
19
- end
20
- li do
21
- link_to helpers.main_app.root_path,
22
- class:
23
- "flex items-center gap-2 hover:bg-gray-50 p-2 rounded-lg" do
24
- main_app_icon
25
- span { "Return to app" }
26
- end
27
- end
28
- end
29
-
30
- hr(class: "my-4")
31
- p(class: "text-[0.7rem] uppercase text-gray-400 font-medium mb-2") { "Resources" }
32
- ul(class: "text-sm text-gray-700") do
33
- ApplicationRecord.descendants.map(&:to_s).sort.each do |resource_name|
34
- li do
35
- link_to helpers.resources_path(resource: resource_name), class: "flex items-center gap-2 hover:bg-gray-50 p-2 rounded-lg" do
36
- folder_icon
37
- span { resource_name }
38
- end
39
- end
40
- end
41
- end
42
-
43
- hr(class: "my-4")
44
- p(class: "text-xs text-gray-500") do
45
- plain("Powered by ")
46
- a(
47
- href: "https://github.com/primevise/oversee",
48
- class: "text-blue-500 hover:underline",
49
- target: "_blank"
50
- ) { "Oversee" }
51
- end
52
- end
53
- end
54
-
55
- private
56
-
57
- def folder_icon
58
- svg(
59
- xmlns: "http://www.w3.org/2000/svg",
60
- width: "24",
61
- height: "24",
62
- viewbox: "0 0 24 24",
63
- fill: "none",
64
- stroke: "currentColor",
65
- stroke_width: "2",
66
- stroke_linecap: "round",
67
- stroke_linejoin: "round",
68
- class: "h-4 w-4 text-gray-400"
69
- ) do |s|
70
- s.path(stroke: "none", d: "M0 0h24v24H0z", fill: "none")
71
- s.path(
72
- d:
73
- "M5 4h4l3 3h7a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-11a2 2 0 0 1 2 -2"
74
- )
75
- end
76
- end
77
-
78
- def main_app_icon
79
- svg(
80
- xmlns: "http://www.w3.org/2000/svg",
81
- width: "24",
82
- height: "24",
83
- viewbox: "0 0 24 24",
84
- fill: "none",
85
- stroke: "currentColor",
86
- stroke_width: "2",
87
- stroke_linecap: "round",
88
- stroke_linejoin: "round",
89
- class: "h-4 w-4 text-gray-400"
90
- ) do |s|
91
- s.path(stroke: "none", d: "M0 0h24v24H0z", fill: "none")
92
- s.path(d: "M9 21v-6a2 2 0 0 1 2 -2h2c.247 0 .484 .045 .702 .127")
93
- s.path(d: "M19 12h2l-9 -9l-9 9h2v7a2 2 0 0 0 2 2h5")
94
- s.path(d: "M16 22l5 -5")
95
- s.path(d: "M21 21.5v-4.5h-4.5")
96
- end
97
- end
98
-
99
- def layout_icon
100
- svg(
101
- xmlns: "http://www.w3.org/2000/svg",
102
- width: "24",
103
- height: "24",
104
- viewbox: "0 0 24 24",
105
- fill: "none",
106
- stroke: "currentColor",
107
- stroke_width: "2",
108
- stroke_linecap: "round",
109
- stroke_linejoin: "round",
110
- class: "h-4 w-4 text-gray-400"
111
- ) do |s|
112
- s.path(stroke: "none", d: "M0 0h24v24H0z", fill: "none")
113
- s.path(
114
- d:
115
- "M4 4m0 2a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v1a2 2 0 0 1 -2 2h-2a2 2 0 0 1 -2 -2z"
116
- )
117
- s.path(
118
- d:
119
- "M4 13m0 2a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v3a2 2 0 0 1 -2 2h-2a2 2 0 0 1 -2 -2z"
120
- )
121
- s.path(
122
- d:
123
- "M14 4m0 2a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-2a2 2 0 0 1 -2 -2z"
124
- )
125
- end
126
- end
127
- end
@@ -1,39 +0,0 @@
1
- module Oversee
2
- class FieldComponent < Phlex::HTML
3
- # A map for components to use when rendering a value
4
- VALUE_MAP = {
5
- string: Oversee::Fields::Value::StringComponent,
6
- boolean: Oversee::Fields::Value::BooleanComponent,
7
- integer: Oversee::Fields::Value::IntegerComponent,
8
- datetime: Oversee::Fields::Value::DatetimeComponent,
9
- text: Oversee::Fields::Value::TextComponent,
10
- enum: Oversee::Fields::Value::EnumComponent
11
- }
12
-
13
- # A map for components to use when rendering a form input field
14
- INPUT_MAP ={
15
- string: Oversee::Fields::Input::StringComponent,
16
- boolean: Oversee::Fields::Input::StringComponent,
17
- integer: Oversee::Fields::Input::IntegerComponent,
18
- datetime: Oversee::Fields::Input::DatetimeComponent,
19
- text: Oversee::Fields::Input::StringComponent,
20
- enum: Oversee::Fields::Input::StringComponent,
21
- }
22
-
23
- MAP = {
24
- value: VALUE_MAP,
25
- input: INPUT_MAP,
26
- }
27
-
28
- def initialize(resource: nil, datatype: :string, kind: :value, key: nil, value: nil)
29
- @kind = kind
30
- @datatype = VALUE_MAP.key?(datatype) ? datatype : :text
31
- @key = key
32
- @value = value || nil
33
- end
34
-
35
- def view_template
36
- render MAP[@kind][@datatype.to_sym].new(key: @key, value: @value)
37
- end
38
- end
39
- end