nitro_rails 0.1.0 → 0.1.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.
- checksums.yaml +4 -4
- data/README.md +18 -0
- data/app/assets/audio/mousetap.mp3 +0 -0
- data/app/assets/config/nitro_rails_manifest.js +2 -0
- data/app/assets/javascript/nitro_rails/application.js +4 -0
- data/app/assets/javascript/nitro_rails/controllers/application.js +9 -0
- data/app/assets/javascript/nitro_rails/controllers/audio_controller.js +16 -0
- data/app/assets/javascript/nitro_rails/controllers/clock_controller.js +21 -0
- data/app/assets/javascript/nitro_rails/controllers/editable_text_controller.js +61 -0
- data/app/assets/javascript/nitro_rails/controllers/index.js +21 -0
- data/app/assets/javascript/nitro_rails/controllers/nitro_collection_controller.js +127 -0
- data/app/assets/javascript/nitro_rails/controllers/nitro_controller.js +35 -0
- data/app/assets/javascript/nitro_rails/controllers/nitro_form_controller.js +81 -0
- data/app/assets/javascript/nitro_rails/controllers/panel_controller.js +70 -0
- data/app/assets/javascript/nitro_rails/controllers/panel_manager_controller.js +89 -0
- data/app/assets/javascript/nitro_rails/controllers/tabs_controller.js +81 -0
- data/app/assets/javascript/nitro_rails/controllers/time_zone_controller.js +47 -0
- data/app/assets/javascript/nitro_rails/controllers/togglable_checkbox_controller.js +9 -0
- data/app/assets/javascript/nitro_rails/helpers/device_info_helper.js +99 -0
- data/app/assets/javascript/nitro_rails/helpers/screen_info_helper.js +20 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/clear_errors.js +22 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/focus.js +8 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/index.js +8 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/insert.js +10 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/redirect.js +10 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/refresh_frame.js +9 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/render_errors.js +26 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/toggle_checkbox.js +9 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/toggle_class.js +14 -0
- data/app/assets/stylesheets/nitro_rails/__reset.css +25 -0
- data/app/assets/stylesheets/nitro_rails/_base/_color.css +24 -0
- data/app/assets/stylesheets/nitro_rails/_base/_font.css +35 -0
- data/app/assets/stylesheets/nitro_rails/_base/_format.css +38 -0
- data/app/assets/stylesheets/nitro_rails/_base/_grayscale.css +79 -0
- data/app/assets/stylesheets/nitro_rails/_base/_utility.css +34 -0
- data/app/assets/stylesheets/nitro_rails/application.css +23 -0
- data/app/assets/stylesheets/nitro_rails/modules/action-navigation.css +24 -0
- data/app/assets/stylesheets/nitro_rails/modules/alert.css +31 -0
- data/app/assets/stylesheets/nitro_rails/modules/btn.css +57 -0
- data/app/assets/stylesheets/nitro_rails/modules/checkbox.css +42 -0
- data/app/assets/stylesheets/nitro_rails/modules/clickable.css +9 -0
- data/app/assets/stylesheets/nitro_rails/modules/clock.css +0 -0
- data/app/assets/stylesheets/nitro_rails/modules/editable-text.css +45 -0
- data/app/assets/stylesheets/nitro_rails/modules/forms.css +108 -0
- data/app/assets/stylesheets/nitro_rails/modules/hover-reveal.css +11 -0
- data/app/assets/stylesheets/nitro_rails/modules/inline-svg.css +14 -0
- data/app/assets/stylesheets/nitro_rails/modules/list.css +29 -0
- data/app/assets/stylesheets/nitro_rails/modules/main-navigation.css +20 -0
- data/app/assets/stylesheets/nitro_rails/modules/nitro-checkbox.css +42 -0
- data/app/assets/stylesheets/nitro_rails/modules/resource-collection.css +12 -0
- data/app/assets/stylesheets/nitro_rails/modules/search-bar.css +36 -0
- data/app/assets/stylesheets/nitro_rails/modules/settings.css +33 -0
- data/app/assets/stylesheets/nitro_rails/modules/tabs.css +38 -0
- data/app/assets/stylesheets/nitro_rails/modules/toggle-switch.css +60 -0
- data/app/assets/stylesheets/nitro_rails/panels/bound-card-dropdown-panel.css +0 -0
- data/app/assets/stylesheets/nitro_rails/panels/card-panel.css +0 -0
- data/app/assets/stylesheets/nitro_rails/panels/embedded-panel.css +31 -0
- data/app/assets/stylesheets/nitro_rails/panels/panel-display.css +111 -0
- data/app/assets/stylesheets/nitro_rails/panels/popup-panel.css +123 -0
- data/app/assets/stylesheets/nitro_rails/panels/side-panel.css +0 -0
- data/app/controllers/nitro_rails/sequence_controller.rb +64 -0
- data/app/helpers/nitro_rails/application_helper.rb +42 -1
- data/app/helpers/nitro_rails/color_helper.rb +23 -0
- data/app/helpers/nitro_rails/components_helper.rb +49 -0
- data/app/helpers/nitro_rails/inline_edit_helper.rb +48 -0
- data/app/helpers/nitro_rails/nitro_action_helper.rb +178 -0
- data/app/helpers/nitro_rails/nitro_collection_helper.rb +87 -0
- data/app/helpers/nitro_rails/nitro_edit_helper.rb +15 -0
- data/app/helpers/nitro_rails/nitro_form_helper.rb +104 -0
- data/app/helpers/nitro_rails/nitro_options_helper.rb +78 -0
- data/app/helpers/nitro_rails/nitro_tag_helper.rb +183 -0
- data/app/helpers/nitro_rails/panel_helper.rb +65 -0
- data/app/helpers/nitro_rails/resource_collection_helper.rb +66 -0
- data/app/helpers/nitro_rails/tabs_helper.rb +51 -0
- data/app/helpers/nitro_rails/turbo_stream_helper.rb +46 -0
- data/app/lib/nitro_rails/local_time.rb +51 -0
- data/app/lib/nitro_rails/performable_routes.rb +24 -0
- data/app/lib/nitro_rails/resource_collection.rb +183 -0
- data/app/lib/nitro_rails/sequential_routes.rb +36 -0
- data/app/lib/nitro_rails/time_interval.rb +88 -0
- data/app/lib/nitro_rails/time_string.rb +22 -0
- data/app/models/nitro_rails/broadcast.rb +76 -0
- data/app/models/nitro_rails/broadcastable_model.rb +91 -0
- data/app/models/nitro_rails/broadcastable_record.rb +118 -0
- data/app/models/nitro_rails/default_broadcasts.rb +149 -0
- data/app/models/nitro_rails/record.rb +50 -0
- data/app/pseudocode/nitro.html.erb +18 -0
- data/app/view_components/nitro_rails/nitro_collection/batch_selectable.rb +24 -0
- data/app/view_components/nitro_rails/nitro_collection.rb +66 -0
- data/app/view_components/nitro_rails/view_component.rb +9 -0
- data/app/views/layouts/nitro_rails/application.html.erb +3 -5
- data/app/views/nitro_rails/_editable_text.html.erb +32 -0
- data/app/views/nitro_rails/_nitro_checkbox.html.erb +5 -0
- data/app/views/nitro_rails/_nitro_form.html.erb +10 -0
- data/app/views/nitro_rails/_panel_frame_tag.html.erb +8 -0
- data/app/views/nitro_rails/_panel_template.html.erb +40 -0
- data/app/views/nitro_rails/_togglable_checkbox.html.erb +16 -0
- data/config/importmap.rb +1 -0
- data/config/initializers/date_formatters.rb +9 -0
- data/lib/nitro_rails/engine.rb +25 -0
- data/lib/nitro_rails/version.rb +1 -1
- metadata +165 -3
- data/app/models/nitro_rails/application_record.rb +0 -5
@@ -0,0 +1,123 @@
|
|
1
|
+
.panel-container.popup .panel-display {
|
2
|
+
width: 500px;
|
3
|
+
z-index: 100;
|
4
|
+
opacity: 1;
|
5
|
+
margin: 0 auto;
|
6
|
+
right: initial;
|
7
|
+
top: initial;
|
8
|
+
display: block;
|
9
|
+
height: 80vh;
|
10
|
+
max-height: 800px;
|
11
|
+
animation: slideUp ease-in-out 200ms 1 forwards;
|
12
|
+
}
|
13
|
+
|
14
|
+
@keyframes slideUp {
|
15
|
+
0% {
|
16
|
+
transform: translateY(8%);
|
17
|
+
opacity: 0;
|
18
|
+
}
|
19
|
+
100% {
|
20
|
+
transform: translateY(0);
|
21
|
+
opacity: 1;
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
|
26
|
+
.panel-container.popup .panel-display .content {
|
27
|
+
transition: background-color 1s;
|
28
|
+
}
|
29
|
+
|
30
|
+
|
31
|
+
.panel-container.popup .panel-display .content {
|
32
|
+
padding: 30px;
|
33
|
+
}
|
34
|
+
|
35
|
+
.panel-container.popup.active .panel-background {
|
36
|
+
background-color: rgba(0, 0, 0, 0.5);
|
37
|
+
/* add blur */
|
38
|
+
backdrop-filter: blur(10px);
|
39
|
+
-webkit-backdrop-filter: blur(10px);
|
40
|
+
position: fixed;
|
41
|
+
top: 0;
|
42
|
+
left: 0;
|
43
|
+
right: 0;
|
44
|
+
bottom: 0;
|
45
|
+
overflow: hidden;
|
46
|
+
z-index: 10000;
|
47
|
+
align-items: center;
|
48
|
+
justify-content: center;
|
49
|
+
animation: overlayFadeIn ease-in-out 200ms 1 forwards;
|
50
|
+
}
|
51
|
+
|
52
|
+
@keyframes overlayFadeIn {
|
53
|
+
0% {
|
54
|
+
background-color: rgba(0, 0, 0, 0);
|
55
|
+
-webkit-backdrop-filter: blur(0);
|
56
|
+
backdrop-filter: blur(0);
|
57
|
+
}
|
58
|
+
100% {
|
59
|
+
background-color: rgba(0, 0, 0, 0.5);
|
60
|
+
-webkit-backdrop-filter: blur(10px);
|
61
|
+
backdrop-filter: blur(10px);
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
/* html:has(.panel-container.popup.active) {
|
66
|
+
overflow: hidden !important;
|
67
|
+
} */
|
68
|
+
|
69
|
+
|
70
|
+
/* TODO - Review Code Below */
|
71
|
+
|
72
|
+
.panel-container.popup .panel.hidden .panel-background {
|
73
|
+
background-color: rgba(0, 0, 0, 0);
|
74
|
+
-webkit-backdrop-filter: blur(0);
|
75
|
+
backdrop-filter: blur(0);
|
76
|
+
position: fixed;
|
77
|
+
top: 0;
|
78
|
+
left: 0;
|
79
|
+
right: 0;
|
80
|
+
bottom: 0;
|
81
|
+
overflow: hidden;
|
82
|
+
z-index: 10000;
|
83
|
+
align-items: center;
|
84
|
+
justify-content: center;
|
85
|
+
animation: overlayFadeOut ease-in-out 200ms 1 forwards;
|
86
|
+
}
|
87
|
+
|
88
|
+
@keyframes overlayFadeOut {
|
89
|
+
0% {
|
90
|
+
background-color: rgba(0, 0, 0, 0.5);
|
91
|
+
-webkit-backdrop-filter: blur(10px);
|
92
|
+
backdrop-filter: blur(10px);
|
93
|
+
}
|
94
|
+
99% {
|
95
|
+
background-color: rgba(0, 0, 0, 0);
|
96
|
+
-webkit-backdrop-filter: blur(0);
|
97
|
+
backdrop-filter: blur(0);
|
98
|
+
}
|
99
|
+
100% {
|
100
|
+
display: none;
|
101
|
+
position: relative;
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
.panel-container.popup .panel.hidden {
|
106
|
+
display: block !important;
|
107
|
+
}
|
108
|
+
|
109
|
+
.panel-container.popup .panel.hidden .panel-display {
|
110
|
+
animation: slideDown ease-in-out 200ms 1 forwards;
|
111
|
+
}
|
112
|
+
|
113
|
+
@keyframes slideDown {
|
114
|
+
0% {
|
115
|
+
transform: translateY(0);
|
116
|
+
opacity: 1;
|
117
|
+
}
|
118
|
+
100% {
|
119
|
+
transform: translateY(8%);
|
120
|
+
opacity: 0;
|
121
|
+
display: none;
|
122
|
+
}
|
123
|
+
}
|
File without changes
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module NitroRails
|
2
|
+
class SequenceController < ActionController::Base
|
3
|
+
layout 'application'
|
4
|
+
|
5
|
+
before_action :set_sequence
|
6
|
+
|
7
|
+
helper_method :next_step_in_sequence_path, :previous_step_in_sequence_path, :first_step_in_sequence_path, :last_step_in_sequence_path
|
8
|
+
|
9
|
+
def self.sequence(*steps)
|
10
|
+
@sequence = [:start, *steps, :finish]
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.before_each_step(action)
|
14
|
+
before_action action, only: [:step, :finish]
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.get_step_for(step)
|
18
|
+
return @sequence[step]
|
19
|
+
end
|
20
|
+
|
21
|
+
def redirect_to_step(step)
|
22
|
+
redirect_to self.class.get_step_for(step)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Convenience Methods
|
26
|
+
|
27
|
+
def next_step_in_sequence_path(id = nil)
|
28
|
+
# binding.pry
|
29
|
+
url_for(request.params.slice(:controller).merge(action: @sequence[:next_step], id: id)) if @sequence[:next_step]
|
30
|
+
end
|
31
|
+
|
32
|
+
def previous_step_in_sequence_path
|
33
|
+
url_for(request.params.slice(:controller).merge(action: @sequence[:previous_step])) if @sequence[:previous_step]
|
34
|
+
end
|
35
|
+
|
36
|
+
def first_step_in_sequence_path(resource = nil)
|
37
|
+
url_for(request.params.slice(:controller).merge(action: @sequence[:first_step])) if @sequence[:first_step]
|
38
|
+
end
|
39
|
+
|
40
|
+
def last_step_in_sequence_path
|
41
|
+
url_for(request.params.slice(:controller).merge(action: @sequence[:last_step])) if @sequence[:last_step]
|
42
|
+
end
|
43
|
+
|
44
|
+
# Initialization Information
|
45
|
+
#
|
46
|
+
def start
|
47
|
+
redirect_to next_step_in_sequence_path
|
48
|
+
end
|
49
|
+
|
50
|
+
def set_sequence
|
51
|
+
steps = self.class.instance_variable_get(:@sequence)
|
52
|
+
current_step_index = steps.index(params[:action].gsub(/!/, "").to_sym)
|
53
|
+
|
54
|
+
@sequence = {
|
55
|
+
steps: steps,
|
56
|
+
first_step: steps[0],
|
57
|
+
previous_step: current_step_index <= 1 ? nil : steps[current_step_index - 1],
|
58
|
+
current_step: steps[current_step_index],
|
59
|
+
next_step: steps[current_step_index + 1],
|
60
|
+
last_step: steps[-1],
|
61
|
+
}
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -1,4 +1,45 @@
|
|
1
1
|
module NitroRails
|
2
2
|
module ApplicationHelper
|
3
|
+
def alert_message(message, threat=:notice)
|
4
|
+
content_tag(:div, message, class: "alert #{threat}")
|
5
|
+
end
|
6
|
+
|
7
|
+
def current_color_scheme
|
8
|
+
current_user && current_user.respond_to?(:settings) && current_user.settings.dark_mode? ? "dark-mode" : "light-mode"
|
9
|
+
end
|
10
|
+
|
11
|
+
def back_path(default = root_path)
|
12
|
+
params[:referrer] || default # Should we add in :back?
|
13
|
+
end
|
14
|
+
|
15
|
+
def polymorphize(record, polymorphic_type)
|
16
|
+
{ "#{polymorphic_type}_id": record.id, "#{polymorphic_type}_type": record.class.name }
|
17
|
+
end
|
18
|
+
|
19
|
+
def contextual_day_format(date, offset: 0)
|
20
|
+
relative_date = Time.current.in_time_zone(offset).to_date
|
21
|
+
case (relative_date - date).to_i
|
22
|
+
when 0...1
|
23
|
+
"Today"
|
24
|
+
when 1...2
|
25
|
+
"Yesterday"
|
26
|
+
when 2...7
|
27
|
+
date.to_fs(:weekday)
|
28
|
+
else
|
29
|
+
if (relative_date.year == date.year)
|
30
|
+
date.to_fs(:month_and_day)
|
31
|
+
else
|
32
|
+
date.to_fs(:month_day_and_year)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def ios_app?
|
38
|
+
request.user_agent&.include?("iOS")
|
39
|
+
end
|
40
|
+
|
41
|
+
def android_app?
|
42
|
+
request.user_agent&.include?("Android")
|
43
|
+
end
|
3
44
|
end
|
4
|
-
end
|
45
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module NitroRails
|
2
|
+
module ColorHelper
|
3
|
+
def brightness_indicator(color)
|
4
|
+
case brightness(color)
|
5
|
+
when 0..100
|
6
|
+
"dark"
|
7
|
+
when 101..200
|
8
|
+
"medium"
|
9
|
+
else
|
10
|
+
"light"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def brightness(color)
|
15
|
+
if color&.start_with?("#")
|
16
|
+
r = color[1..2].to_i(16)
|
17
|
+
g = color[3..4].to_i(16)
|
18
|
+
b = color[5..6].to_i(16)
|
19
|
+
(r * 299 + g * 587 + b * 114) / 1000
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module NitroRails
|
2
|
+
module ComponentsHelper
|
3
|
+
def inline_svg(path, **options)
|
4
|
+
nitro_options(options) do |options|
|
5
|
+
options.concat(:class, "inline-svg")
|
6
|
+
options.concat(:class, "svg-#{path.split("/").last}")
|
7
|
+
options.concat(:class, options.delete(:size))
|
8
|
+
options.concat(:style, "transform: rotate(#{options.delete(:rotate)}deg);") if options[:rotate]
|
9
|
+
end
|
10
|
+
|
11
|
+
# Rails.cache.clear
|
12
|
+
svg = Rails.cache.fetch("inline_svg/#{path}", expires_in: 12.hours) do
|
13
|
+
app_path = Rails.root.join("app/assets/images/svgs/#{path}.svg")
|
14
|
+
gem_path = NitroRails::Engine.root.join("app/assets/images/nitro_rails/#{path}.svg")
|
15
|
+
|
16
|
+
if File.exist?(app_path)
|
17
|
+
File.read(app_path).html_safe
|
18
|
+
elsif File.exist?(gem_path)
|
19
|
+
File.read(gem_path).html_safe
|
20
|
+
else
|
21
|
+
"(SVG file not found: #{path})"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
content_tag(:div, **options) do
|
26
|
+
render inline: svg
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def clock
|
31
|
+
content_tag(:div, class: "clock", data: { controller: "clock" }) do
|
32
|
+
content_tag(:span, Time.now.strftime("%-I:%M %p"), class: "clock-time", data: { "clock-target": "time" })
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def search_bar(**options)
|
37
|
+
options[:class] = "search-bar #{options[:class]}"
|
38
|
+
options[:data] ||= {}
|
39
|
+
options[:data][:controller] = "search"
|
40
|
+
|
41
|
+
content_tag(:div, **options) do
|
42
|
+
content_tag(:i, "", class: "fas fa-search") +
|
43
|
+
form_with(url: '/', method: :get, data: { turbo: false }) do
|
44
|
+
text_field_tag(:query, params[:query], class: "search-bar-input", placeholder: "Search", data: { action: "keyup->search#search" })
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module NitroRails
|
2
|
+
module InlineEditHelper
|
3
|
+
def editable_text(resource_path, attribute, context: :broadcast, placeholder: nil, focus: false, tag: :p)
|
4
|
+
render partial: 'nitro_rails/editable_text', locals: {
|
5
|
+
resource_path: resource_path,
|
6
|
+
resource: resource_path.is_a?(Array) ? resource_path.last : resource_path,
|
7
|
+
attribute: attribute,
|
8
|
+
context: context,
|
9
|
+
placeholder: placeholder,
|
10
|
+
focus: focus,
|
11
|
+
tag: tag
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
def togglable_checkbox(resource_path, attribute, context: :broadcast)
|
16
|
+
render partial: 'nitro_rails/togglable_checkbox', locals: {
|
17
|
+
resource_path: resource_path,
|
18
|
+
resource: resource = resource_path.is_a?(Array) ? resource_path.last : resource_path,
|
19
|
+
attribute: attribute,
|
20
|
+
context: context
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
def updatable_text(resource, attribute, placeholder: nil)
|
25
|
+
content_tag(:span, resource.send(attribute).presence, class: "updatable-text", placeholder: placeholder, data: {
|
26
|
+
nitro_id: resource.nitro_id(attribute)
|
27
|
+
})
|
28
|
+
end
|
29
|
+
|
30
|
+
def error_badge(resource, attribute)
|
31
|
+
error_count = resource.errors[attribute].length
|
32
|
+
content_tag(:span, error_count, class: "error-badge #{'visible' if error_count > 0}", data: {
|
33
|
+
attribute_error_count_id: resource.nitro_id(attribute)
|
34
|
+
})
|
35
|
+
end
|
36
|
+
|
37
|
+
def error_message(resource, attribute)
|
38
|
+
error_message = resource.errors.full_messages_for(attribute).first
|
39
|
+
content_tag(:span, error_message, class: "error-message #{'visible' if error_message}", data: {
|
40
|
+
attribute_error_message_id: resource.nitro_id(attribute)
|
41
|
+
})
|
42
|
+
end
|
43
|
+
|
44
|
+
def attribute_classes(resource, attribute)
|
45
|
+
"#{resource.class.name.downcase.dasherize}-#{attribute} #{resource.class.name.downcase.dasherize}-#{resource.id}-#{attribute} #{attribute}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,178 @@
|
|
1
|
+
module NitroRails
|
2
|
+
module NitroActionHelper
|
3
|
+
def nitro_action_form(**options, &block)
|
4
|
+
nitro_hidden_action_form(**options) do |form|
|
5
|
+
form.submit_div(&block)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def nitro_action_button(text, **options, &block)
|
10
|
+
text ||= "Save" if !block_given?
|
11
|
+
|
12
|
+
nitro_hidden_action_form(**options) do |form|
|
13
|
+
form.submit(text, &block)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def nitro_hidden_action_form(**options, &block)
|
18
|
+
nitro_form(**options) do |form|
|
19
|
+
concat(form.generate_hidden_attribute_fields)
|
20
|
+
concat(yield(form))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
############
|
25
|
+
## CREATE ##
|
26
|
+
############
|
27
|
+
|
28
|
+
def nitro_create(type, **options, &block)
|
29
|
+
nitro_create_options(type, options)
|
30
|
+
nitro_action_form(**options, &block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def nitro_create_button(text=nil, type, **options, &block)
|
34
|
+
nitro_create_options(type, options)
|
35
|
+
nitro_action_button(text, **options, &block)
|
36
|
+
end
|
37
|
+
|
38
|
+
def nitro_create_options(type, options)
|
39
|
+
nitro_options(options) do |options|
|
40
|
+
options.default(:method, :post)
|
41
|
+
options.default(:model, type.to_s.classify.constantize.new)
|
42
|
+
options.default(:params, type.to_sym => options.delete(:params) || {})
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
##########
|
47
|
+
## SAVE ##
|
48
|
+
##########
|
49
|
+
|
50
|
+
def nitro_save(resource = current_nitro_resource, **options, &block)
|
51
|
+
nitro_save_options(resource, options)
|
52
|
+
nitro_action_form(**options, &block)
|
53
|
+
end
|
54
|
+
|
55
|
+
# No idea if any of the buttons are working
|
56
|
+
def nitro_save_button(text_or_resource = nil, maybe_resource = current_nitro_resource, **options, &block)
|
57
|
+
resource, text = button_args(text_or_resource, maybe_resource)
|
58
|
+
nitro_save_options(resource, options)
|
59
|
+
nitro_action_button(text, **options, &block)
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
def nitro_save_options(resource, options)
|
64
|
+
nitro_options(options) do |options|
|
65
|
+
options.default(:method, resource.persisted? ? :patch : :post)
|
66
|
+
options.default(:model, resource)
|
67
|
+
options.default(:params, resource.type.to_sym => options.delete(:params) || {})
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
############
|
72
|
+
## UPDATE ##
|
73
|
+
############
|
74
|
+
|
75
|
+
def nitro_update(resource = current_nitro_resource, **options, &block)
|
76
|
+
nitro_update_options(resource, options)
|
77
|
+
nitro_action_form(**options, &block)
|
78
|
+
end
|
79
|
+
|
80
|
+
def nitro_update_button(text_or_resource = nil, maybe_resource = current_nitro_resource, **options, &block)
|
81
|
+
resource, text = button_args(text_or_resource, maybe_resource)
|
82
|
+
nitro_update_options(resource, options)
|
83
|
+
nitro_action_button(text, **options, &block)
|
84
|
+
end
|
85
|
+
|
86
|
+
def nitro_update_options(resource, options)
|
87
|
+
nitro_options(options) do |options|
|
88
|
+
options.default(:method, :patch)
|
89
|
+
options.default(:model, resource)
|
90
|
+
options.default(:params, resource.type.to_sym => options.delete(:params) || {})
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
#############
|
95
|
+
## DESTROY ##
|
96
|
+
#############
|
97
|
+
|
98
|
+
def nitro_destroy(resource = current_nitro_resource, **options, &block)
|
99
|
+
nitro_destroy_options(resource, options)
|
100
|
+
nitro_action_form(**options, &block)
|
101
|
+
end
|
102
|
+
|
103
|
+
def nitro_destroy_button(text_or_resource = nil, maybe_resource = current_nitro_resource, **options, &block)
|
104
|
+
resource, text = button_args(text_or_resource, maybe_resource)
|
105
|
+
nitro_destroy_options(resource, options)
|
106
|
+
nitro_action_button(text, **options, &block)
|
107
|
+
end
|
108
|
+
|
109
|
+
def nitro_destroy_options(resource, options)
|
110
|
+
nitro_options(options) do |options|
|
111
|
+
options.default(:method, :delete)
|
112
|
+
options.default(:model, resource)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
#############
|
119
|
+
## HELPERS ##
|
120
|
+
#############
|
121
|
+
|
122
|
+
# Refactor at some point
|
123
|
+
def button_args(*args)
|
124
|
+
if args.length > 3
|
125
|
+
raise ArgumentError, "Too many arguments. Expected 0, 1, or 2 arguments."
|
126
|
+
end
|
127
|
+
|
128
|
+
if args.first == nil || args.first.is_a?(String) || args.first.is_a?(Symbol)
|
129
|
+
return [args.last, args.first]
|
130
|
+
end
|
131
|
+
|
132
|
+
if args.first.is_a?(ActiveRecord::Base)
|
133
|
+
return [args.first, nil]
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
###########
|
140
|
+
## STASH ##
|
141
|
+
###########
|
142
|
+
|
143
|
+
# def nitro_create_button(text=nil, record_type, **opts, &block)
|
144
|
+
# options = { method: :post, data: { turbo: true, controller: "nitro", action: "nitro#insertNewItem" }}.merge(opts.delete(:options).to_h)
|
145
|
+
# params = { params: { record_type.to_sym => opts } }
|
146
|
+
# path = record_type.to_s.pluralize.to_sym
|
147
|
+
|
148
|
+
# forges = opts[:forges].is_a?(Array) ? opts[:forges] : [opts[:forges]].compact
|
149
|
+
|
150
|
+
|
151
|
+
# content_tag(:div, class: "nitro-form-stack") do
|
152
|
+
# forges.each do |forger|
|
153
|
+
# concat(forger_form(forger)) unless forger.persisted?
|
154
|
+
# end
|
155
|
+
|
156
|
+
# if block_given?
|
157
|
+
# concat(button_to(path, options.merge(params), &block))
|
158
|
+
# else
|
159
|
+
# concat(button_to(text || "Create #{record_type}", path, options.merge(params)))
|
160
|
+
# end
|
161
|
+
# end
|
162
|
+
# end
|
163
|
+
#
|
164
|
+
# def forger_form(forger)
|
165
|
+
# nitro_hidden_resource_form(forger) {}
|
166
|
+
# end
|
167
|
+
#
|
168
|
+
# def harvest_arguments(arguments, keys)
|
169
|
+
# output = []
|
170
|
+
# arguments.each_with_index do |argument, index|
|
171
|
+
# if keys[index] == :text? && (argument.is_a?(String) || argument.is_a?(Symbol)) || argument.nil?
|
172
|
+
# output << argument
|
173
|
+
# else
|
174
|
+
# output << arg
|
175
|
+
|
176
|
+
# end
|
177
|
+
# end
|
178
|
+
# end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module NitroRails
|
2
|
+
module NitroCollectionHelper
|
3
|
+
def nitro_collection_tag(tag = :ul, parent, resource_method, **options, &block)
|
4
|
+
nitro_options(options) do |options|
|
5
|
+
options.default(:nitro_id, parent.nitro_id(resource_method))
|
6
|
+
options.concat(:class, classify(resource_method))
|
7
|
+
options.concat(:class, classify(parent.type, resource_method))
|
8
|
+
end
|
9
|
+
|
10
|
+
nitro_tag(tag, **options, &block)
|
11
|
+
end
|
12
|
+
|
13
|
+
def nitro_collection(parent, resource_method, **options, &block)
|
14
|
+
content_tag(:div, data: { controller: "nitro-collection", nitro_collection_target: "container", nitro_collection_id: "#{parent.nitro_id}:#{resource_method}" }) do
|
15
|
+
nitro_collection_tag(:ul, parent, resource_method, data: { nitro_collection_target: :collection }, **options) do
|
16
|
+
resources = parent.send(resource_method)
|
17
|
+
resources = resources.order(options.delete(:order)) if options[:order]
|
18
|
+
resources = resources.where(options.delete(:where)) if options[:where]
|
19
|
+
resources = resources.take(options.delete(:take)) if options[:take]
|
20
|
+
|
21
|
+
|
22
|
+
resources.map do |resource|
|
23
|
+
yield resource
|
24
|
+
end
|
25
|
+
end +
|
26
|
+
|
27
|
+
content_tag(:template, class: "nitro-collection-template", style: "display: none;", data: { nitro_collection_target: :template }) do
|
28
|
+
yield parent.send(resource_method).template
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def chain_methods(*array)
|
34
|
+
array.inject { |obj, method| obj.public_send(method) }
|
35
|
+
end
|
36
|
+
|
37
|
+
def new_nitro_collection(*resources_or_path, **options, &block)
|
38
|
+
resources = is_active_collection?(resources_or_path.first) ? resources_or_path.first : chain_methods(*resources_or_path)
|
39
|
+
NitroCollection.new(resources, view: self, **options).render_content(&block)
|
40
|
+
end
|
41
|
+
|
42
|
+
def is_active_collection?(collection)
|
43
|
+
collection.is_a?(ActiveRecord::Associations::CollectionProxy || ActiveRecord::Relation)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
# resources: collection_proxy,
|
50
|
+
# resource_type: collection_proxy.proxy_association.reflection.klass.name.underscore,
|
51
|
+
# parent: collection_proxy.proxy_association.owner,
|
52
|
+
# where_clause: collection_proxy.where_clause,
|
53
|
+
# order_clause: collection_proxy.order_values,
|
54
|
+
# request_hash: collection_proxy.to_sql.hash
|
55
|
+
|
56
|
+
|
57
|
+
# class NitroCollection
|
58
|
+
# def initialize(**options)
|
59
|
+
# @parent = options[:affiliation]
|
60
|
+
# @method = options[:method]
|
61
|
+
# @order = options[:order]
|
62
|
+
# @resources = @parent.send(@method).order(options[:order])
|
63
|
+
# @type = options[:type] || @resources.first.class.name.underscore
|
64
|
+
# @method = method
|
65
|
+
# end
|
66
|
+
|
67
|
+
# def render_content(&block)
|
68
|
+
|
69
|
+
# end
|
70
|
+
# end
|
71
|
+
|
72
|
+
# def nitro_collection(tag = :ul, parent, resource_method, **options, &block)
|
73
|
+
# content_tag(:div, class: "nitro-collection-container") do
|
74
|
+
# nitro_collection_tag(tag, parent, resource_method, **options) do
|
75
|
+
# parent.send(resource_method).order(options[:order]).map do |resource|
|
76
|
+
# yield resource
|
77
|
+
# end
|
78
|
+
# end +
|
79
|
+
|
80
|
+
# content_tag(:template, class: "nitro-collection-template", style: "display: none;") do
|
81
|
+
# yield parent.send(resource_method).template
|
82
|
+
# end
|
83
|
+
# end
|
84
|
+
# end
|
85
|
+
|
86
|
+
# private?
|
87
|
+
# NitroCollection.new(affiliation: @day, method: :tasks, order: :created_at)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module NitroRails
|
2
|
+
module NitroEditHelper
|
3
|
+
def nitro_checkbox(record, attribute, **options)
|
4
|
+
nitro_options(options) do |options|
|
5
|
+
options.default(:method, :patch)
|
6
|
+
options.default(:data, :turbo, true)
|
7
|
+
options.concat(:data, :controller, "nitro-form")
|
8
|
+
options.concat(:data, :nitro_form_target, "form")
|
9
|
+
options.concat(:data, :nitro_form_resource_target_value, record.nitro_id)
|
10
|
+
end
|
11
|
+
|
12
|
+
render partial: 'nitro_rails/nitro_checkbox', locals: { record: record, attribute: attribute, options: options }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|