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.
- checksums.yaml +4 -4
- data/app/assets/config/oversee_manifest.js +2 -0
- data/app/components/oversee/dashboard/filters.rb +23 -19
- data/app/components/oversee/dashboard/header.rb +34 -18
- data/app/components/oversee/dashboard/index.rb +23 -11
- data/app/components/oversee/dashboard/javascript.rb +4 -4
- data/app/components/oversee/dashboard/pagination.rb +1 -1
- data/app/components/oversee/dashboard/sidebar.rb +38 -1
- data/app/components/oversee/dashboard/tailwind.rb +30 -1
- data/app/components/oversee/field/display.rb +19 -10
- data/app/components/oversee/field/form.rb +4 -23
- data/app/components/oversee/field/input/belongs_to.rb +22 -0
- data/app/components/oversee/field/input/boolean.rb +1 -11
- data/app/components/oversee/field/input/datetime.rb +1 -11
- data/app/components/oversee/field/input/integer.rb +1 -11
- data/app/components/oversee/field/input/rich_text.rb +18 -0
- data/app/components/oversee/field/input/string.rb +1 -11
- data/app/components/oversee/field/input.rb +13 -5
- data/app/components/oversee/field/label.rb +3 -2
- data/app/components/oversee/field/value/belongs_to.rb +21 -0
- data/app/components/oversee/field/value/datetime.rb +1 -1
- data/app/components/oversee/field/value/rich_text.rb +9 -0
- data/app/components/oversee/field/value.rb +11 -5
- data/app/components/oversee/layout/application.rb +46 -0
- data/app/components/oversee/resources/index.rb +21 -2
- data/app/components/oversee/resources/new.rb +7 -3
- data/app/components/oversee/resources/show.rb +150 -69
- data/app/components/oversee/resources/table.rb +7 -1
- data/app/controllers/oversee/dashboard_controller.rb +1 -1
- data/app/controllers/oversee/resources/fields_controller.rb +20 -36
- data/app/controllers/oversee/resources_controller.rb +22 -22
- data/app/javascript/oversee/application.js +3 -0
- data/app/javascript/oversee/controllers/index.js +8 -0
- data/app/javascript/oversee/controllers/reveal_controller.js +7 -0
- data/app/javascript/oversee/controllers/sidebar/state_controller.js +21 -0
- data/app/models/oversee/resource.rb +43 -17
- data/app/{oversee → service/oversee}/filter.rb +2 -2
- data/app/{oversee → service/oversee}/search.rb +1 -1
- data/app/views/oversee/base.rb +5 -0
- data/config/importmap.rb +14 -0
- data/config/routes.rb +16 -10
- data/lib/generators/oversee/install_generator.rb +7 -0
- data/lib/oversee/engine.rb +19 -0
- data/lib/oversee/version.rb +1 -1
- data/lib/oversee.rb +12 -0
- data/lib/tasks/oversee_tasks.rake +6 -4
- metadata +31 -8
- data/app/jobs/oversee/application_job.rb +0 -4
- data/app/oversee/cards.rb +0 -2
- data/app/oversee/resource.rb +0 -10
- data/app/views/layouts/oversee/application.html.erb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c31a8c277449dfaec238f66cfc8e404a64c51dff4beef1a944fee85c5935991c
|
4
|
+
data.tar.gz: f3fcd62d4ff3184f5b9f97273c2269e986b5f03736a9961440aca242b38a1292
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad42840ab6b72667e5e16853cea4d9028fc1356fd4ff2ec7d3909b6102c2fc80dca9287245ad4ab62021181c238beae371f77b473f1f9464bf0b1162a29946c5
|
7
|
+
data.tar.gz: 229f928f44cfe6d6535cd8ef6682472a9f5ecf59e29bc65714ed71e1c6147ab48b582e5c065fc1e9233d5e536155e16d8750a1fc92f3e74bd97e3720cbc58e42
|
@@ -8,29 +8,33 @@ class Oversee::Dashboard::Filters < Oversee::Base
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def view_template(&)
|
11
|
-
div(class: "
|
12
|
-
div(class: "flex items-center
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
plain "Filters"
|
18
|
-
end
|
19
|
-
end
|
20
|
-
if false
|
21
|
-
a(class:"rounded-full bg-gray-100 inline-flex gap-2 items-center text-xs px-4 py-2 font-medium hover:bg-gray-200") do
|
22
|
-
render Phlex::Icons::Iconoir::XMark.new(class: "size-4 text-gray-500")
|
23
|
-
plain "Clear sorting"
|
24
|
-
end
|
11
|
+
div(class: "flex items-center justify-between") do
|
12
|
+
div(class: "flex items-center gap-2") do
|
13
|
+
if show_action_section?
|
14
|
+
button(class:"rounded-full bg-gray-100 inline-flex gap-2 items-center text-xs px-4 py-2 font-medium hover:bg-gray-200") do
|
15
|
+
render Phlex::Icons::Iconoir::FilterAlt.new(class: "size-3")
|
16
|
+
plain "Filters"
|
25
17
|
end
|
26
18
|
end
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
19
|
+
if false
|
20
|
+
a(class:"rounded-full bg-gray-100 inline-flex gap-2 items-center text-xs px-4 py-2 font-medium hover:bg-gray-200") do
|
21
|
+
render Phlex::Icons::Iconoir::XMark.new(class: "size-4 text-gray-500")
|
22
|
+
plain "Clear sorting"
|
31
23
|
end
|
32
24
|
end
|
33
25
|
end
|
26
|
+
div(class: "flex items-center gap-4") do
|
27
|
+
form(action: "", class: "flex items-center gap-2") do
|
28
|
+
input(
|
29
|
+
type: :search,
|
30
|
+
name: :query,
|
31
|
+
value: @params[:query],
|
32
|
+
placeholder: search_placeholder,
|
33
|
+
class: "flex bg-gray-100 min-w-64 w-64 focus:w-96 transition-all h-10 items-center pl-4 py-2 placeholder:text-gray-500 rounded-sm text-sm"
|
34
|
+
)
|
35
|
+
button(class: "size-10 inline-flex items-center justify-center bg-gray-100 hover:bg-gray-200 transition-colors") { render Phlex::Icons::Iconoir::Search.new(class: "size-4 text-gray-600") }
|
36
|
+
end
|
37
|
+
end
|
34
38
|
end
|
35
39
|
end
|
36
40
|
|
@@ -46,7 +50,7 @@ class Oversee::Dashboard::Filters < Oversee::Base
|
|
46
50
|
end
|
47
51
|
|
48
52
|
def search_placeholder
|
49
|
-
context = Search.new(collection: nil, resource_class: @params[:resource_class_name].constantize)
|
53
|
+
context = Oversee::Search.new(collection: nil, resource_class: @params[:resource_class_name].constantize)
|
50
54
|
attr = context.default_searchable_attribute
|
51
55
|
|
52
56
|
"Search by #{attr}"
|
@@ -1,4 +1,9 @@
|
|
1
1
|
class Oversee::Dashboard::Header < Oversee::Base
|
2
|
+
attr_reader :title
|
3
|
+
attr_reader :subtitle
|
4
|
+
attr_reader :return_path
|
5
|
+
attr_reader :show_back_button
|
6
|
+
|
2
7
|
def initialize(title: nil, subtitle: nil, return_path: nil, show_back_button: true)
|
3
8
|
@title = title || "Dashboard"
|
4
9
|
@subtitle = subtitle || "Manage your account"
|
@@ -7,31 +12,42 @@ class Oversee::Dashboard::Header < Oversee::Base
|
|
7
12
|
end
|
8
13
|
|
9
14
|
def view_template(&)
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
18
|
-
div(class: "flex items-center gap-2") do
|
19
|
-
yield if block_given?
|
15
|
+
|
16
|
+
div(class: "min-h-10 flex items-center justify-between") do
|
17
|
+
if block_given?
|
18
|
+
yield(self)
|
19
|
+
else
|
20
|
+
left
|
21
|
+
right
|
20
22
|
end
|
21
23
|
end
|
22
24
|
end
|
23
25
|
|
26
|
+
def left(&)
|
27
|
+
div(class: "flex items-center gap-2") do
|
28
|
+
back_button if show_back_button
|
29
|
+
h3(class: "text-lg font-medium text-gray-900") { title } if title.present?
|
30
|
+
yield if block_given?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def right(&)
|
35
|
+
div(class: "flex items-center gap-4", &)
|
36
|
+
end
|
37
|
+
|
38
|
+
def separator
|
39
|
+
render Phlex::Icons::Iconoir::Slash.new(class: "size-4 text-gray-300", stroke_width: 1.75)
|
40
|
+
end
|
41
|
+
|
24
42
|
private
|
25
43
|
|
26
44
|
def back_button
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
)
|
33
|
-
render Phlex::Icons::Iconoir::ArrowLeft.new(class: "size-4 text-gray-900")
|
34
|
-
end
|
45
|
+
a(
|
46
|
+
href: return_button_path,
|
47
|
+
class: "mr-2 size-8 inline-flex items-center justify-center bg-gray-50 text-gray-500 hover:text-gray-900 hover:bg-gray-200 transition-colors",
|
48
|
+
data: { controller: "back", action: "back#navigate", turbo_action: "replace" }
|
49
|
+
) do
|
50
|
+
render Phlex::Icons::Iconoir::ArrowLeft.new(class: "size-3", stroke_width: 2.5)
|
35
51
|
end
|
36
52
|
end
|
37
53
|
|
@@ -1,23 +1,35 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Oversee::Dashboard::Index < Oversee::Base
|
4
|
+
|
5
|
+
def around_template
|
6
|
+
render Oversee::Layout::Application.new { super }
|
7
|
+
end
|
8
|
+
|
4
9
|
def view_template
|
5
|
-
div(class: "
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
+
div(class: "flex items-center justify-between") do
|
11
|
+
h1(class: "text-lg font-medium text-gray-900") { "Dashboard" }
|
12
|
+
h1(class: "text-sm font-medium text-gray-500") { Date.current.to_fs(:long) }
|
13
|
+
end
|
14
|
+
|
15
|
+
if Oversee.card_class_names.present?
|
16
|
+
div(class: "grid grid-cols-4 gap-4") do
|
17
|
+
Oversee.card_class_names.each do |card_name|
|
18
|
+
render Oversee::Card.new(card_name: card_name)
|
10
19
|
end
|
11
20
|
end
|
12
21
|
end
|
13
22
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
23
|
+
hr(class: "my-4")
|
24
|
+
|
25
|
+
div(class: "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-4") do
|
26
|
+
Oversee.application_resource_names.sort.each do |resource_class_name|
|
27
|
+
a(href: helpers.resources_path(resource_class_name:), class: "w-full bg-gray-100/75 block hover:bg-gray-50 p-4 truncate") do
|
28
|
+
div(class: "flex items-center justify-center size-8 bg-white") do
|
29
|
+
render Phlex::Icons::Iconoir::Folder.new(class: "size-4 text-gray-400")
|
30
|
+
end
|
31
|
+
p(class: "mt-4 font-medium text-gray-700") { resource_class_name }
|
19
32
|
end
|
20
|
-
end
|
21
33
|
end
|
22
34
|
end
|
23
35
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
class Oversee::Dashboard::Javascript < Phlex::HTML
|
2
|
+
include Phlex::Rails::Helpers::JavascriptImportmapTags
|
3
|
+
|
2
4
|
def view_template
|
3
|
-
script(async: true, src:"https://
|
4
|
-
|
5
|
-
raw %({"imports":{"@hotwired/stimulus":"https://unpkg.com/@hotwired/stimulus/dist/stimulus.js","@hotwired/turbo":"https://unpkg.com/@hotwired/turbo","@hotwired/turbo-rails":"https://unpkg.com/@hotwired/turbo-rails"}}).html_safe
|
6
|
-
end
|
5
|
+
script(async: true, src:"https://ga.jspm.io/npm:es-module-shims@1.8.2/dist/es-module-shims.js")
|
6
|
+
javascript_importmap_tags("application", importmap: Oversee.importmap)
|
7
7
|
script(type: "module") { raw %(import * as Turbo from "@hotwired/turbo-rails").html_safe }
|
8
8
|
end
|
9
9
|
end
|
@@ -9,7 +9,7 @@ class Oversee::Dashboard::Pagination < Oversee::Base
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def view_template
|
12
|
-
div(class:"
|
12
|
+
div(class:"mt-4 flex items-center justify-between") do
|
13
13
|
|
14
14
|
div(class: "font-regular text-xs") do
|
15
15
|
raw pagy_info(@pagy).html_safe
|
@@ -21,8 +21,45 @@ class Oversee::Dashboard::Sidebar < Oversee::Base
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
+
if Rails.env.development?
|
25
|
+
hr(class: "my-4 -mx-4")
|
26
|
+
details(
|
27
|
+
id: "links-menu",
|
28
|
+
class: "group",
|
29
|
+
# open: true,
|
30
|
+
data: {
|
31
|
+
controller: "sidebar--state",
|
32
|
+
action: "sidebar--state#persist",
|
33
|
+
sidebar__state_target: "expandable"
|
34
|
+
}
|
35
|
+
) do
|
36
|
+
summary(class: "flex items-center justify-between cursor-pointer") do
|
37
|
+
p(class: "text-[0.7rem] uppercase text-gray-400 font-medium") { "Links" }
|
38
|
+
render Phlex::Icons::Iconoir::NavArrowDown.new(class: "size-4 text-gray-400 transform transition-transform group-open:rotate-180 group-hover:text-blue-500")
|
39
|
+
end
|
40
|
+
ul(class: "mt-2 text-sm text-gray-700 overflow-x-hidden") do
|
41
|
+
li do
|
42
|
+
a(href: "https://github.com/primevise/oversee", target: "_blank", class: "flex items-center gap-2 hover:bg-gray-50 p-2 truncate") do
|
43
|
+
render Phlex::Icons::Iconoir::ArrowUpRightSquare.new(class: "size-4 text-gray-400")
|
44
|
+
span { "Repository" }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
24
51
|
hr(class: "my-4 -mx-4")
|
25
|
-
|
52
|
+
|
53
|
+
details(
|
54
|
+
id: "resources-menu",
|
55
|
+
class: "group",
|
56
|
+
# open: true,
|
57
|
+
data: {
|
58
|
+
controller: "sidebar--state",
|
59
|
+
action: "sidebar--state#persist",
|
60
|
+
sidebar__state_target: "expandable"
|
61
|
+
}
|
62
|
+
) do
|
26
63
|
summary(class: "flex items-center justify-between cursor-pointer") do
|
27
64
|
p(class: "text-[0.7rem] uppercase text-gray-400 font-medium") { "Resources" }
|
28
65
|
render Phlex::Icons::Iconoir::NavArrowDown.new(class: "size-4 text-gray-400 transform transition-transform group-open:rotate-180 group-hover:text-blue-500")
|
@@ -1,11 +1,40 @@
|
|
1
1
|
class Oversee::Dashboard::Tailwind < Phlex::HTML
|
2
2
|
def view_template
|
3
|
-
script(src: "https://cdn.tailwindcss.com?plugins=typography")
|
3
|
+
script(src: "https://cdn.tailwindcss.com/3.4.15?plugins=typography@0.5.15")
|
4
4
|
style(type:"text/tailwindcss") do
|
5
5
|
raw pagy_css.html_safe
|
6
|
+
raw trix_css.html_safe
|
6
7
|
end
|
7
8
|
end
|
8
9
|
|
10
|
+
def trix_css
|
11
|
+
<<~CSS
|
12
|
+
trix-editor {
|
13
|
+
@apply rounded-b rounded-t-none border border-t-0 border-gray-200 !ring-0;
|
14
|
+
}
|
15
|
+
|
16
|
+
.trix-active {
|
17
|
+
@apply !bg-gray-100 !text-blue-500;
|
18
|
+
}
|
19
|
+
|
20
|
+
.trix-button-row {
|
21
|
+
@apply overflow-hidden rounded-t border;
|
22
|
+
}
|
23
|
+
|
24
|
+
.trix-button {
|
25
|
+
@apply !relative !inline-flex !h-7 !items-center !justify-center border-0 !border-b-0 !border-l-0 !px-7 !py-4;
|
26
|
+
}
|
27
|
+
|
28
|
+
.trix-button::before {
|
29
|
+
@apply !top-1.5 !h-5;
|
30
|
+
}
|
31
|
+
|
32
|
+
.trix-button-group {
|
33
|
+
@apply !mb-0 rounded-b-none !border-0 border-gray-200;
|
34
|
+
}
|
35
|
+
CSS
|
36
|
+
end
|
37
|
+
|
9
38
|
def pagy_css
|
10
39
|
<<~CSS
|
11
40
|
.pagy {
|
@@ -1,29 +1,38 @@
|
|
1
1
|
class Oversee::Field::Display < Oversee::Base
|
2
|
-
|
2
|
+
|
3
|
+
attr_reader :resource
|
4
|
+
attr_reader :key
|
5
|
+
attr_reader :value
|
6
|
+
attr_reader :datatype
|
7
|
+
|
8
|
+
def initialize(resource:, key: nil, value: nil, datatype: :string, **options)
|
3
9
|
@resource = resource
|
4
10
|
@key = key
|
5
11
|
@value = value
|
6
12
|
@datatype = datatype
|
7
|
-
@
|
13
|
+
@options = options
|
8
14
|
end
|
9
15
|
|
10
16
|
def view_template
|
11
|
-
|
12
|
-
id: dom_id(
|
13
|
-
href: helpers.
|
17
|
+
html_tag(
|
18
|
+
id: dom_id(resource, key),
|
19
|
+
href: helpers.resource_input_path(resource_class_name:, key:, datatype:),
|
14
20
|
class: "bg-gray-100 h-10 flex items-center px-4 py-2 hover:bg-gray-200 transition-colors w-full cursor-pointer",
|
15
|
-
data: { turbo_stream: true }
|
16
|
-
|
21
|
+
data: { turbo_stream: true }
|
22
|
+
) do
|
23
|
+
render Oversee::Field::Value.new(key:, value:, datatype:, **@options)
|
17
24
|
end
|
18
25
|
end
|
19
26
|
|
20
27
|
private
|
21
28
|
|
22
29
|
def resource_class_name
|
23
|
-
@resource.class.name
|
30
|
+
@resource_class_name ||= @resource.class.name
|
24
31
|
end
|
25
32
|
|
26
|
-
def
|
27
|
-
|
33
|
+
def html_tag(...)
|
34
|
+
edittable? ? a(...) : div(...)
|
28
35
|
end
|
36
|
+
|
37
|
+
def edittable? = @options[:edittable] || true
|
29
38
|
end
|
@@ -1,21 +1,22 @@
|
|
1
1
|
class Oversee::Field::Form < Oversee::Base
|
2
2
|
include Phlex::Rails::Helpers::FormWith
|
3
3
|
|
4
|
-
def initialize(resource:, key: nil, value: nil, datatype: :string, method: :patch)
|
4
|
+
def initialize(resource:, key: nil, value: nil, datatype: :string, method: :patch, **options)
|
5
5
|
@resource = resource
|
6
6
|
@key = key
|
7
7
|
@value = value
|
8
8
|
@datatype = datatype
|
9
9
|
@method = method
|
10
|
+
@options = options
|
10
11
|
end
|
11
12
|
|
12
13
|
def view_template
|
13
14
|
form_with(id: dom_id(@resource, @key), model: @resource, url: helpers.update_resource_path(resource_class_name: resource_class_name, id: @resource.id), method: @method, class: "flex items-center w-full gap-4") do |form|
|
14
15
|
input type: :hidden, id: "oversee_key", name: "oversee_key", value: @key.to_s
|
15
16
|
input type: :hidden, id: "oversee_datatype", name: "oversee_datatype", value: @datatype
|
16
|
-
render Oversee::Field::Input.new(key: @key, value: @value, datatype: @datatype)
|
17
|
+
render Oversee::Field::Input.new(key: @key, value: @value, datatype: @datatype, **@options)
|
17
18
|
button(class:"h-9 bg-gray-900 hover:bg-gray-700 text-white inline-flex items-center cursor-pointer gap-2 px-4 rounded-full text-xs font-medium") {
|
18
|
-
|
19
|
+
render Phlex::Icons::Iconoir::Check.new(class: "size-4")
|
19
20
|
plain "Save"
|
20
21
|
}
|
21
22
|
end
|
@@ -26,24 +27,4 @@ class Oversee::Field::Form < Oversee::Base
|
|
26
27
|
def resource_class_name
|
27
28
|
@resource.class.name
|
28
29
|
end
|
29
|
-
|
30
|
-
def save_icon
|
31
|
-
svg(
|
32
|
-
stroke_width: "2.5",
|
33
|
-
viewbox: "0 0 24 24",
|
34
|
-
fill: "none",
|
35
|
-
xmlns: "http://www.w3.org/2000/svg",
|
36
|
-
class: "size-4",
|
37
|
-
color: "currentColor"
|
38
|
-
) do |s|
|
39
|
-
s.path(
|
40
|
-
d: "M5 13L9 17L19 7",
|
41
|
-
stroke: "currentColor",
|
42
|
-
stroke_width: "2.5",
|
43
|
-
stroke_linecap: "round",
|
44
|
-
stroke_linejoin: "round"
|
45
|
-
)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
30
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Oversee::Field::Input::BelongsTo < Oversee::Field::Input
|
2
|
+
def initialize(key:, value:, **options)
|
3
|
+
@key = key
|
4
|
+
@value = value
|
5
|
+
end
|
6
|
+
|
7
|
+
def view_template
|
8
|
+
input type: "text", id: field_id, name: field_name, value: @value, class: "flex border px-4 py-2 text-sm w-full rounded-sm"
|
9
|
+
|
10
|
+
# select(id: field_id, name: field_name, class: "flex w-full border rounded-sm px-4 py-2 text-sm") do
|
11
|
+
|
12
|
+
# option(value: 1, selected: @value) { "True" }
|
13
|
+
# option(value: 0, selected: !@value) { "False" }
|
14
|
+
# end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def select_values
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class Oversee::Field::Input::Boolean <
|
1
|
+
class Oversee::Field::Input::Boolean < Oversee::Field::Input
|
2
2
|
def initialize(key:, value:)
|
3
3
|
@key = key
|
4
4
|
@value = value
|
@@ -10,14 +10,4 @@ class Oversee::Field::Input::Boolean < Phlex::HTML
|
|
10
10
|
option(value: 0, selected: !@value) { "False" }
|
11
11
|
end
|
12
12
|
end
|
13
|
-
|
14
|
-
private
|
15
|
-
|
16
|
-
def field_id
|
17
|
-
"resource_#{@key.to_s}"
|
18
|
-
end
|
19
|
-
|
20
|
-
def field_name
|
21
|
-
"resource[#{@key.to_s}]"
|
22
|
-
end
|
23
13
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class Oversee::Field::Input::Datetime <
|
1
|
+
class Oversee::Field::Input::Datetime < Oversee::Field::Input
|
2
2
|
def initialize(key:, value:)
|
3
3
|
@key = key
|
4
4
|
@value = value
|
@@ -7,14 +7,4 @@ class Oversee::Field::Input::Datetime < Phlex::HTML
|
|
7
7
|
def view_template
|
8
8
|
input type: "datetime-local", id: field_id, name: field_name, value: @value&.strftime("%Y-%m-%dT%T"), class: "flex w-full border rounded-sm px-4 py-2 text-sm"
|
9
9
|
end
|
10
|
-
|
11
|
-
private
|
12
|
-
|
13
|
-
def field_id
|
14
|
-
"resource_#{@key.to_s}"
|
15
|
-
end
|
16
|
-
|
17
|
-
def field_name
|
18
|
-
"resource[#{@key.to_s}]"
|
19
|
-
end
|
20
10
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class Oversee::Field::Input::Integer <
|
1
|
+
class Oversee::Field::Input::Integer < Oversee::Field::Input
|
2
2
|
def initialize(key:, value:)
|
3
3
|
@key = key
|
4
4
|
@value = value
|
@@ -7,14 +7,4 @@ class Oversee::Field::Input::Integer < Phlex::HTML
|
|
7
7
|
def view_template
|
8
8
|
input type: "number", id: field_id, name: field_name, value: @value, class: "flex w-full border rounded-sm px-4 py-2 text-sm"
|
9
9
|
end
|
10
|
-
|
11
|
-
private
|
12
|
-
|
13
|
-
def field_id
|
14
|
-
"resource_#{@key.to_s}"
|
15
|
-
end
|
16
|
-
|
17
|
-
def field_name
|
18
|
-
"resource[#{@key.to_s}]"
|
19
|
-
end
|
20
10
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Oversee::Field::Input::RichText < Oversee::Field::Input
|
2
|
+
register_element :trix_editor
|
3
|
+
|
4
|
+
attr_reader :key
|
5
|
+
attr_reader :value
|
6
|
+
|
7
|
+
def initialize(key:, value:)
|
8
|
+
@key = key
|
9
|
+
@value = value
|
10
|
+
end
|
11
|
+
|
12
|
+
def view_template
|
13
|
+
div do
|
14
|
+
input(type: "hidden", id: field_id, name: field_name, value:)
|
15
|
+
trix_editor(id: "#{field_id}_trix_editor", input: field_id)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class Oversee::Field::Input::String <
|
1
|
+
class Oversee::Field::Input::String < Oversee::Field::Input
|
2
2
|
def initialize(key:, value:)
|
3
3
|
@key = key
|
4
4
|
@value = value
|
@@ -7,14 +7,4 @@ class Oversee::Field::Input::String < Phlex::HTML
|
|
7
7
|
def view_template
|
8
8
|
input type: "text", id: field_id, name: field_name, value: @value, class: "flex border px-4 py-2 text-sm w-full rounded-sm"
|
9
9
|
end
|
10
|
-
|
11
|
-
private
|
12
|
-
|
13
|
-
def field_id
|
14
|
-
"resource_#{@key.to_s}"
|
15
|
-
end
|
16
|
-
|
17
|
-
def field_name
|
18
|
-
"resource[#{@key.to_s}]"
|
19
|
-
end
|
20
10
|
end
|
@@ -1,21 +1,24 @@
|
|
1
1
|
class Oversee::Field::Input < Oversee::Base
|
2
2
|
MAP = {
|
3
|
-
|
3
|
+
belongs_to: Oversee::Field::Input::BelongsTo,
|
4
4
|
boolean: Oversee::Field::Input::Boolean,
|
5
|
-
integer: Oversee::Field::Input::Integer,
|
6
5
|
datetime: Oversee::Field::Input::Datetime,
|
6
|
+
enum: Oversee::Field::Input::String,
|
7
|
+
integer: Oversee::Field::Input::Integer,
|
8
|
+
rich_text: Oversee::Field::Input::RichText,
|
9
|
+
string: Oversee::Field::Input::String,
|
7
10
|
text: Oversee::Field::Input::String,
|
8
|
-
enum: Oversee::Field::Input::String
|
9
11
|
}
|
10
12
|
|
11
|
-
def initialize(key: nil, value: nil, datatype: :string)
|
13
|
+
def initialize(key: nil, value: nil, datatype: :string, **options)
|
12
14
|
@key = key
|
13
15
|
@value = value
|
14
16
|
@datatype = datatype
|
17
|
+
@options = options
|
15
18
|
end
|
16
19
|
|
17
20
|
def view_template
|
18
|
-
render component_class.new(key: @key, value: @value)
|
21
|
+
render component_class.new(key: @key, value: @value, **@options)
|
19
22
|
end
|
20
23
|
|
21
24
|
private
|
@@ -23,4 +26,9 @@ class Oversee::Field::Input < Oversee::Base
|
|
23
26
|
def component_class
|
24
27
|
MAP[@datatype.to_sym] || Oversee::Field::Input::String
|
25
28
|
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def field_id = "resource_#{@key.to_s}"
|
33
|
+
def field_name = "resource[#{@key.to_s}]"
|
26
34
|
end
|
@@ -2,6 +2,7 @@ class Oversee::Field::Label < Oversee::Base
|
|
2
2
|
ICON_MAP = {
|
3
3
|
string: Phlex::Icons::Iconoir::Text,
|
4
4
|
text: Phlex::Icons::Iconoir::TextSquare,
|
5
|
+
rich_text: Phlex::Icons::Iconoir::TextSquare,
|
5
6
|
integer: Phlex::Icons::Iconoir::Number0Square,
|
6
7
|
datetime: Phlex::Icons::Iconoir::Calendar,
|
7
8
|
boolean: Phlex::Icons::Iconoir::SwitchOn,
|
@@ -14,11 +15,11 @@ class Oversee::Field::Label < Oversee::Base
|
|
14
15
|
end
|
15
16
|
|
16
17
|
def view_template
|
17
|
-
div(class:"inline-flex items-center space-x-2") do
|
18
|
+
div(id: "#{@key}_label", class:"inline-flex items-center space-x-2") do
|
18
19
|
div(class: "size-5 bg-gray-100 inline-flex items-center justify-center") do
|
19
20
|
render ICON_MAP[@datatype] ? ICON_MAP[@datatype].new(class: "size-3") : ICON_MAP[:data].new(class: "size-3")
|
20
21
|
end
|
21
|
-
label(class: "uppercase text-xs text-gray
|
22
|
+
label(class: "uppercase text-xs text-gray-700 font-medium block cursor-auto") { @key.to_s.humanize(keep_id_suffix: true) }
|
22
23
|
end
|
23
24
|
end
|
24
25
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Oversee::Field::Value::BelongsTo < Phlex::HTML
|
2
|
+
def initialize(key: nil, value: nil, **options)
|
3
|
+
@key = key
|
4
|
+
@value = value
|
5
|
+
@options = options
|
6
|
+
end
|
7
|
+
|
8
|
+
def view_template
|
9
|
+
p(title: @value, class:"inline-flex items-center gap-1") do
|
10
|
+
if display_key?
|
11
|
+
span { @key.humanize }
|
12
|
+
span {"|"}
|
13
|
+
end
|
14
|
+
span { @value }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def display_key? = !!@options[:display_key]
|
21
|
+
end
|