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,104 @@
|
|
1
|
+
module NitroRails
|
2
|
+
module NitroFormHelper
|
3
|
+
def nitro_form(**options, &block)
|
4
|
+
nitro_options(options) do |options|
|
5
|
+
options.default(:builder, NitroFormBuilder)
|
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, options[:model].nitro_id) if options[:model] && options[:model].persisted?
|
10
|
+
options.concat(:data, :nitro_effects, effects_for(options[:method]))
|
11
|
+
end
|
12
|
+
|
13
|
+
form_with(**options, &block)
|
14
|
+
end
|
15
|
+
|
16
|
+
def effects_for(method)
|
17
|
+
case method
|
18
|
+
when :post
|
19
|
+
"insertItemAndFocus attributeEffects"
|
20
|
+
when :patch, :put
|
21
|
+
"attributeEffects"
|
22
|
+
when :delete
|
23
|
+
"removeItem"
|
24
|
+
else
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class NitroFormBuilder < ActionView::Helpers::FormBuilder
|
30
|
+
include NitroRails::NitroOptionsHelper
|
31
|
+
|
32
|
+
############
|
33
|
+
## SUBMIT ##
|
34
|
+
############
|
35
|
+
|
36
|
+
def submit_div(**options, &block)
|
37
|
+
nitro_options(options) do |options|
|
38
|
+
options.default(:class, "nitro-form-submit")
|
39
|
+
options.concat(:data, :action, "click->nitro-form#submit")
|
40
|
+
end
|
41
|
+
|
42
|
+
@template.content_tag(:div, **options, &block)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Don't know if this works.
|
46
|
+
def submit(text = nil, **options, &block)
|
47
|
+
nitro_options(options) do |options|
|
48
|
+
options.default(:class, "btn button_to")
|
49
|
+
options.concat(:data, :action, "click->nitro-form#submit")
|
50
|
+
end
|
51
|
+
|
52
|
+
super(text, **options, &block)
|
53
|
+
end
|
54
|
+
|
55
|
+
###################
|
56
|
+
## HIDDEN FIELDS ##
|
57
|
+
###################
|
58
|
+
|
59
|
+
def generate_hidden_attribute_fields()
|
60
|
+
object_key = @object.class.name.underscore.to_sym
|
61
|
+
attributes = {}
|
62
|
+
|
63
|
+
if @object
|
64
|
+
@object.changes.each do |attribute, (old_value, new_value)|
|
65
|
+
attributes[attribute] = new_value
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
if @options[:params] && @options[:params][object_key]
|
70
|
+
attributes.merge!(@options[:params][object_key])
|
71
|
+
end
|
72
|
+
|
73
|
+
attributes.map do |attribute, value|
|
74
|
+
hidden_attribute_field(attribute, value)
|
75
|
+
end.join.html_safe +
|
76
|
+
if @options[:belongs_to]
|
77
|
+
hidden_affiliation_field(@options[:belongs_to])
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def hidden_affiliation_field(affiliation, **options)
|
82
|
+
nitro_options(options) do |options|
|
83
|
+
options.override(:value, affiliation.id)
|
84
|
+
options.default(:data, :nitro_form_target, "field")
|
85
|
+
options.concat(:data, :nitro_effects, "addToAffiliatedLists")
|
86
|
+
options.override(:data, :nitro_attribute, affiliation.nitro_id(@object.type.pluralize))
|
87
|
+
end
|
88
|
+
|
89
|
+
hidden_field("#{affiliation.class.name.underscore}_id", **options)
|
90
|
+
end
|
91
|
+
|
92
|
+
def hidden_attribute_field(attribute, value, **options)
|
93
|
+
nitro_options(options) do |options|
|
94
|
+
options.override(:value, value)
|
95
|
+
options.default(:data, :nitro_form_target, "field")
|
96
|
+
options.concat(:data, :nitro_effects, @object.attribute_effects(attribute).join(" ").camelize(:lower))
|
97
|
+
options.override(:data, :nitro_attribute, attribute.to_s)
|
98
|
+
end
|
99
|
+
|
100
|
+
hidden_field(attribute, **options)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# Maybe could move to lib folder
|
2
|
+
module NitroRails
|
3
|
+
module NitroOptionsHelper
|
4
|
+
def nitro_options(*options, &block)
|
5
|
+
nitro_options = NitroOptions.new(*options)
|
6
|
+
nitro_defaults(nitro_options)
|
7
|
+
# app_defaults(nitro_options)
|
8
|
+
yield nitro_options
|
9
|
+
return nitro_options.options
|
10
|
+
end
|
11
|
+
|
12
|
+
# This shouldn't need to be run every time nitro_options is called
|
13
|
+
def nitro_defaults(nitro_options)
|
14
|
+
nitro_options.translate(:audio) do |value|
|
15
|
+
nitro_options.concat(:data, :controller, "audio")
|
16
|
+
nitro_options.concat(:data, :action, "audio#play")
|
17
|
+
nitro_options.concat(:data, :audio, value)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Need to deal with adding styles when style key already exists
|
21
|
+
if(nitro_options.options[:style].class == Hash)
|
22
|
+
nitro_options.override(:style, nitro_options.delete(:style).map do |key, value|
|
23
|
+
"#{key.to_s.dasherize}: #{ value.is_a?(Integer) ? "#{value}px" : value };"
|
24
|
+
end.join(" "))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class NitroOptions
|
29
|
+
attr_reader :options
|
30
|
+
|
31
|
+
def initialize(*options)
|
32
|
+
@options = merge(*options)
|
33
|
+
end
|
34
|
+
|
35
|
+
def merge(*options)
|
36
|
+
options.first
|
37
|
+
end
|
38
|
+
|
39
|
+
def default(*key_path, value)
|
40
|
+
modify_options(*key_path) { |memo, key| memo[key] = memo[key].nil? ? value : memo[key] }
|
41
|
+
end
|
42
|
+
|
43
|
+
def override(*key_path, value)
|
44
|
+
modify_options(*key_path) { |memo, key| memo[key] = value }
|
45
|
+
end
|
46
|
+
|
47
|
+
def concat(*key_path, value)
|
48
|
+
modify_options(*key_path) { |memo, key| memo[key] = [memo[key], value].compact.join(" ") }
|
49
|
+
end
|
50
|
+
|
51
|
+
def translate(*key_path)
|
52
|
+
yield delete(*key_path) if exists?(*key_path)
|
53
|
+
end
|
54
|
+
|
55
|
+
def exists?(*key_path)
|
56
|
+
key_path.reduce(@options) { |memo, key| memo[key] }.present?
|
57
|
+
end
|
58
|
+
|
59
|
+
def [](key)
|
60
|
+
@options[key]
|
61
|
+
end
|
62
|
+
|
63
|
+
def delete(*key_path)
|
64
|
+
modify_options(*key_path) { |memo, key| memo.delete(key) }
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
# def get_item(key)
|
70
|
+
|
71
|
+
def modify_options(*key_path)
|
72
|
+
last_key = key_path.pop
|
73
|
+
nested_options = key_path.reduce(@options) { |memo, key| memo[key] ||= {} }
|
74
|
+
yield(nested_options, last_key)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,183 @@
|
|
1
|
+
module NitroRails
|
2
|
+
module NitroTagHelper
|
3
|
+
def nitro_tag(tag = :div, text = nil, nitro_id: nil, link: nil, **options, &block)
|
4
|
+
nitro_options(options) do |options|
|
5
|
+
options.default(:data, :nitro_id, nitro_id) if nitro_id
|
6
|
+
end
|
7
|
+
|
8
|
+
content_tag(tag, text, **options, &block)
|
9
|
+
end
|
10
|
+
|
11
|
+
##########
|
12
|
+
## BODY ##
|
13
|
+
##########
|
14
|
+
|
15
|
+
def nitro_body_tag(**options, &block)
|
16
|
+
options.merge!(@custom_body_options) if @custom_body_options
|
17
|
+
|
18
|
+
nitro_options(options, @custom_body_options) do |options|
|
19
|
+
options.concat(:class, options.delete(:color_scheme) || current_color_scheme)
|
20
|
+
options.concat(:class, "#{controller_name}-#{action_name}")
|
21
|
+
|
22
|
+
if turbo_native_app?
|
23
|
+
options.concat(:class, "turbo-native")
|
24
|
+
|
25
|
+
if ios_app?
|
26
|
+
options.concat(:class, "ios")
|
27
|
+
options.override(:data, :turbo_native, "iOS")
|
28
|
+
elsif android_app?
|
29
|
+
options.concat(:class, "android")
|
30
|
+
options.override(:data, :turbo_native, "Android")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
options.concat(:data, :controller, "panel-manager time-zone nitro")
|
35
|
+
options.concat(:data, :action, "turbo@morph->panel-manager#morph click->panel-manager#closeOtherPanels touchend->panel-manager#closeOtherPanels")
|
36
|
+
options.default(:data, :panel_manager_target, "container")
|
37
|
+
options.default(:data, :time_zone_server_time_value, "#{Time.now.utc.iso8601}")
|
38
|
+
end
|
39
|
+
|
40
|
+
content_tag(:body, **options, &block) # Should use nitro_tag
|
41
|
+
end
|
42
|
+
|
43
|
+
def body_options(**options)
|
44
|
+
@custom_body_options = options
|
45
|
+
end
|
46
|
+
|
47
|
+
##########
|
48
|
+
## LINK ##
|
49
|
+
##########
|
50
|
+
|
51
|
+
def nitro_link_tag(*args, **options, &block)
|
52
|
+
nitro_options(options) do |options|
|
53
|
+
options.concat(:class, "nitro-link")
|
54
|
+
options.concat(:class, "active") if current_page?(args.last)
|
55
|
+
end
|
56
|
+
|
57
|
+
link_to(*args, **options, &block)
|
58
|
+
end
|
59
|
+
|
60
|
+
alias_method :nitro_link, :nitro_link_tag
|
61
|
+
|
62
|
+
##############
|
63
|
+
## RESOURCE ##
|
64
|
+
##############
|
65
|
+
|
66
|
+
def nitro_resource_tag(tag = :div, resource, **options, &block)
|
67
|
+
nitro_options(options) do |options|
|
68
|
+
options.default(:nitro_id, resource.nitro_id) # Maybe add default?
|
69
|
+
options.default(:data, :id, resource.id)
|
70
|
+
options.concat(:class, classify(resource.type))
|
71
|
+
options.concat(:class, resource_status_classes(resource))
|
72
|
+
options.concat(:class, "hover-context") unless options[:hover_context] == false
|
73
|
+
|
74
|
+
if link = options.delete(:link)
|
75
|
+
options.default(:data, :action, "click->nitro#link")
|
76
|
+
options.default(:data, :nitro_link, link == true ? url_for(resource) : link)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
with_nitro_resource(resource) do
|
81
|
+
nitro_tag(tag, **options, &block)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def nitro_resource(resource, **options, &block)
|
86
|
+
nitro_resource_tag(options.delete(:tag) || :div, resource, **options, &block)
|
87
|
+
end
|
88
|
+
|
89
|
+
def with_nitro_resource(resource)
|
90
|
+
(@_nitro_resource_stack ||= []).push(resource)
|
91
|
+
yield
|
92
|
+
ensure
|
93
|
+
@_nitro_resource_stack.pop
|
94
|
+
end
|
95
|
+
|
96
|
+
def current_nitro_resource
|
97
|
+
@_nitro_resource_stack&.last
|
98
|
+
end
|
99
|
+
|
100
|
+
###############
|
101
|
+
## ATTRIBUTE ##
|
102
|
+
###############
|
103
|
+
|
104
|
+
def nitro_attribute_tag(tag_or_resource = :p, maybe_resource = current_nitro_resource, attribute, **options, &block)
|
105
|
+
# Not sure this works for all cases
|
106
|
+
# nitro_attribute_tag(:p, @task, :name, **options)
|
107
|
+
# nitro_attribute_tag(@task, :name, **options)
|
108
|
+
# nitro_attribute_tag(:name, **options)
|
109
|
+
# nitro_attribute_tag(:p, :name, **options)
|
110
|
+
#
|
111
|
+
## First argument can be tag, resource, or attribute
|
112
|
+
## Second argument can be resource or attribute
|
113
|
+
## Third argument is always attribute
|
114
|
+
if tag_or_resource.is_a?(Symbol) || tag_or_resource.is_a?(String)
|
115
|
+
tag = tag_or_resource
|
116
|
+
resource = maybe_resource
|
117
|
+
else
|
118
|
+
tag = :p
|
119
|
+
resource = tag_or_resource
|
120
|
+
end
|
121
|
+
|
122
|
+
nitro_options(options) do |options|
|
123
|
+
options.default(:nitro_id, resource.nitro_id(attribute))
|
124
|
+
options.concat(:class, classify(attribute))
|
125
|
+
options.concat(:class, classify(resource.type, attribute))
|
126
|
+
options.concat(:class, attribute_status_class(resource, attribute))
|
127
|
+
end
|
128
|
+
|
129
|
+
# NEW CODE
|
130
|
+
value = resource.send(attribute)
|
131
|
+
|
132
|
+
if options[:format] && value.present?
|
133
|
+
options.delete(:format).each do |method, params|
|
134
|
+
value = value.send(method, *params)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
value = value.presence || options.delete(:default) || ""
|
139
|
+
# END NEW CODE
|
140
|
+
|
141
|
+
nitro_tag(tag, value, **options, &block)
|
142
|
+
end
|
143
|
+
|
144
|
+
def nitro_attribute(resource = current_nitro_resource, attribute, **options)
|
145
|
+
nitro_attribute_tag(options.delete(:tag) || :p, resource, attribute, **options)
|
146
|
+
end
|
147
|
+
|
148
|
+
private
|
149
|
+
|
150
|
+
#############
|
151
|
+
## HELPERS ##
|
152
|
+
#############
|
153
|
+
|
154
|
+
def resource_status_classes(resource)
|
155
|
+
classes = []
|
156
|
+
|
157
|
+
resource.status_attributes.each do |attribute|
|
158
|
+
if resource.send(attribute).is_a?(TrueClass) || resource.send(attribute).is_a?(FalseClass)
|
159
|
+
classes.push("#{attribute}") if resource.send(attribute).is_a?(TrueClass)
|
160
|
+
classes.push("not-#{attribute}") if resource.send(attribute).is_a?(FalseClass)
|
161
|
+
elsif resource.class.defined_enums.key?(attribute.to_s)
|
162
|
+
classes.push("#{resource.send(attribute)}")
|
163
|
+
else
|
164
|
+
classes.push("#{attribute}-#{resource.send(attribute)}")
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
classes.join(" ")
|
169
|
+
end
|
170
|
+
|
171
|
+
def attribute_status_class(resource, attribute)
|
172
|
+
if resource.send(attribute).is_a?(TrueClass) || resource.send(attribute).is_a?(FalseClass)
|
173
|
+
"#{resource.send(attribute)}"
|
174
|
+
else
|
175
|
+
"#{attribute}-#{resource.send(attribute)&.gsub(/ /, "-")}".downcase
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def classify(*strings)
|
180
|
+
strings.join("-").dasherize
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# Need to clean up this file.
|
2
|
+
module NitroRails
|
3
|
+
module PanelHelper
|
4
|
+
def panel_frame_tag
|
5
|
+
render partial: "nitro_rails/panel_frame_tag", locals: { component_id: "nie" } # nie?
|
6
|
+
end
|
7
|
+
|
8
|
+
def panel_template
|
9
|
+
render partial: "nitro_rails/panel_template"
|
10
|
+
end
|
11
|
+
|
12
|
+
def popup_panel_link(*args, **opts, &block)
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
def in_panel?
|
17
|
+
request.headers['Turbo-Panel-Request'].present?
|
18
|
+
end
|
19
|
+
|
20
|
+
def panel_link(*args, **opts, &block)
|
21
|
+
if in_panel?
|
22
|
+
return link_to(*args, **opts, &block)
|
23
|
+
end
|
24
|
+
|
25
|
+
opts[:data] ||= {}
|
26
|
+
opts[:data][:action] = "click->panel-manager#toggle"
|
27
|
+
|
28
|
+
if opts[:panel].is_a?(Hash)
|
29
|
+
opts[:panel].each do |key, value|
|
30
|
+
opts[:data]["panel-#{key.to_s.dasherize}"] = value.to_s.dasherize
|
31
|
+
end
|
32
|
+
else
|
33
|
+
opts[:data][:panel] = "default"
|
34
|
+
end
|
35
|
+
|
36
|
+
opts[:data][:panel_id] = "#{opts.to_s}#{args[-1].to_s}".hash
|
37
|
+
|
38
|
+
if opts[:panel] && opts[:panel][:presentation]
|
39
|
+
args[-1] = args[1] + "?presentation=#{opts[:panel][:presentation]}"
|
40
|
+
end
|
41
|
+
|
42
|
+
presentation = opts[:panel] && opts[:panel][:presentation] ? opts[:panel][:presentation] : "card"
|
43
|
+
|
44
|
+
container_opts = opts.delete(:container) || {}
|
45
|
+
container_opts[:class] ? container_opts[:class] += " panel-container #{presentation}" : container_opts[:class] = "panel-container #{presentation}"
|
46
|
+
|
47
|
+
content_tag(:div, **container_opts) do
|
48
|
+
link_to(*args, **opts, &block)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class PanelLinkComponent
|
53
|
+
def initialize(content = nil, path, **opts, &block)
|
54
|
+
@panel_options = opts.delete(:panel) || {}
|
55
|
+
@container_options = opts.delete(:container) || {}
|
56
|
+
@type = opts.delete(:type) || :card
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# <a href="/path?ios-presentation=modal" data-panel-presentation="card" >
|
63
|
+
# ...
|
64
|
+
# </a>
|
65
|
+
# Could merge this and navigation helper methods into a single helper module
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module NitroRails
|
2
|
+
module ResourceCollectionHelper
|
3
|
+
def resource_collection(*resources_or_path, **options, &block)
|
4
|
+
# signature = source_stamp.hash.abs.to_s(36)
|
5
|
+
|
6
|
+
if resources_or_path.last.is_a?(Symbol)
|
7
|
+
resources_method = resources_or_path[-1]
|
8
|
+
resources_type = resources_method.to_s.singularize
|
9
|
+
resources_parent = resources_or_path[-2]
|
10
|
+
# resources_parent_type = resources_parent.type
|
11
|
+
resources_path = [resources_parent, resources_method]
|
12
|
+
resources = resources_parent.send(resources_method).where(options[:where])
|
13
|
+
else
|
14
|
+
resources_type = resources_or_path.first.table.name.singularize
|
15
|
+
resources = resources_or_path.first
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
# binding.pry
|
20
|
+
ResourceCollection.new(resources, view: self, create_path: resources_path, parent: resources_parent, resource_type: resources_type, id: block.to_s.hash).render_content(&block)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
# class ResourceCollection
|
27
|
+
# attr_reader :controller, :parent, :resource_type
|
28
|
+
|
29
|
+
# def initialize(controller, parent, resource_type)
|
30
|
+
# @controller = controller
|
31
|
+
# @parent = parent
|
32
|
+
# @resource_type = resource_type
|
33
|
+
# end
|
34
|
+
|
35
|
+
# def main_classes
|
36
|
+
# @main_classes ||= "#{parent.type}-#{resource_type} #{parent.type}-#{resource_type}-list #{resource_type} #{resource_type}-list list list--arrow-detail list--basic-link"
|
37
|
+
# end
|
38
|
+
|
39
|
+
# def broadcast_tag
|
40
|
+
# @broadcast_tag ||= "#{parent.resource_id}:#{resource_type}"
|
41
|
+
# end
|
42
|
+
|
43
|
+
# def resources
|
44
|
+
# @resources ||= parent.send(resource_type)
|
45
|
+
# end
|
46
|
+
|
47
|
+
# def render(&block)
|
48
|
+
# controller.render(layout: "aros/resource_collection", locals: {
|
49
|
+
# resource_type: resource_type,
|
50
|
+
# classes: main_classes,
|
51
|
+
# broadcast_tag: broadcast_tag,
|
52
|
+
# resources: resources,
|
53
|
+
# resource_collection: self
|
54
|
+
# }) do
|
55
|
+
# controller.capture(self, &block)
|
56
|
+
# end
|
57
|
+
# end
|
58
|
+
|
59
|
+
# def render_items(**opts, &block)
|
60
|
+
# resources.order(opts[:order] || :created_at).each do |resource|
|
61
|
+
# controller.concat(controller.capture(resource, &block))
|
62
|
+
# end
|
63
|
+
# end
|
64
|
+
# end
|
65
|
+
|
66
|
+
# resource_type, classes, broadcast_tag, resources
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module NitroRails
|
2
|
+
module TabsHelper
|
3
|
+
def tabs_controller(**options, &block)
|
4
|
+
nitro_options(options) do |transformer|
|
5
|
+
transformer.concat(:class, "tabs-container")
|
6
|
+
transformer.concat(:data, :controller, "tabs")
|
7
|
+
end
|
8
|
+
|
9
|
+
content_tag(options.delete(:tag) || :div, **options, &block)
|
10
|
+
end
|
11
|
+
|
12
|
+
def tabs(**options, &block)
|
13
|
+
nitro_options(options) do |transformer|
|
14
|
+
transformer.concat(:class, "tabs")
|
15
|
+
end
|
16
|
+
|
17
|
+
content_tag(options.delete(:tag) || :div, **options, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def tab(screen, text = nil, **options, &block)
|
21
|
+
nitro_options(options) do |transformer|
|
22
|
+
transformer.concat(:class, "tab")
|
23
|
+
transformer.concat(:data, :action, "click->tabs#changeScreens")
|
24
|
+
transformer.concat(:data, :tabs_target, "tab")
|
25
|
+
transformer.concat(:data, :tabs_screen, screen.to_s)
|
26
|
+
end
|
27
|
+
|
28
|
+
content_tag(options.delete(:tag) || :button, text, **options, &block)
|
29
|
+
end
|
30
|
+
|
31
|
+
def tab_screens(**options, &block)
|
32
|
+
nitro_options(options) do |transformer|
|
33
|
+
transformer.concat(:class, "tab-screens")
|
34
|
+
transformer.concat(:data, :tabs_target, "screens")
|
35
|
+
end
|
36
|
+
|
37
|
+
content_tag(options.delete(:tag) || :div, **options, &block)
|
38
|
+
end
|
39
|
+
|
40
|
+
def tab_screen(screen, content = nil, **options, &block)
|
41
|
+
nitro_options(options) do |transformer|
|
42
|
+
transformer.concat(:class, "tab-screen")
|
43
|
+
transformer.concat(:data, :tabs_target, "screen")
|
44
|
+
transformer.concat(:data, :tabs_screen, screen.to_s)
|
45
|
+
transformer.concat(:class, "hidden") unless options.delete(:visible)
|
46
|
+
end
|
47
|
+
|
48
|
+
content_tag(options.delete(:tag) || :div, content, **options, &block)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# I don't think this file is even being used (except for first two methods.)
|
2
|
+
module NitroRails
|
3
|
+
module TurboStreamHelper
|
4
|
+
def private_stream_for(user, &block)
|
5
|
+
turbo_stream_from user, &block
|
6
|
+
end
|
7
|
+
|
8
|
+
def public_stream(&block)
|
9
|
+
turbo_stream_from :public, &block
|
10
|
+
end
|
11
|
+
|
12
|
+
# METHODS BELOW ONLY NEEDED FOR VIEW/CONTROLLER STREAMS
|
13
|
+
# Is this necessary? Is any of this file for that matter?
|
14
|
+
def toggle_class(target, class_name, status:)
|
15
|
+
turbo_stream_action_tag :toggle_class, targets: target, class: class_name, status: status
|
16
|
+
end
|
17
|
+
|
18
|
+
# def render_errors(resource, authenticity_token)
|
19
|
+
# if(resource.errors.any?)
|
20
|
+
# resource.errors.attribute_names.map do |attribute|
|
21
|
+
# turbo_stream_action_tag(:render_errors,
|
22
|
+
# authenticity_token: authenticity_token,
|
23
|
+
# attribute_id: attribute_id(resource, attribute),
|
24
|
+
# error_message: resource.errors.full_messages_for(attribute).first,
|
25
|
+
# error_length: resource.errors[attribute].length,
|
26
|
+
# )
|
27
|
+
# end.join.html_safe
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
|
31
|
+
# def redirect(url)
|
32
|
+
# turbo_stream_action_tag :redirect, url: url
|
33
|
+
# end
|
34
|
+
|
35
|
+
# def clear_errors(resource, authenticity_token)
|
36
|
+
# turbo_stream_action_tag :clear_errors, authenticity_token: authenticity_token
|
37
|
+
# end
|
38
|
+
|
39
|
+
# def attribute_id(resource, attribute)
|
40
|
+
# "#{resource.class.name.underscore}_#{resource.id}:#{attribute}"
|
41
|
+
# end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Not sure this belongs in a helper, not sure any of this module does for that matter
|
46
|
+
Turbo::Streams::TagBuilder.prepend(NitroRails::TurboStreamHelper)
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module NitroRails
|
2
|
+
module LocalTime
|
3
|
+
# def local_time(timezone)
|
4
|
+
# end
|
5
|
+
|
6
|
+
# def self.included(base)
|
7
|
+
# base.extend(ClassMethods)
|
8
|
+
# end
|
9
|
+
|
10
|
+
# def timezone_accessor
|
11
|
+
# return @accessor if @accessor
|
12
|
+
# delegate = self.class.instance_variable_get(:@delegate)
|
13
|
+
# if delegate
|
14
|
+
# @accessor = send(delegate)
|
15
|
+
# else
|
16
|
+
# @accessor = self
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
|
20
|
+
# def timezone_location
|
21
|
+
# timezone_accessor.timezone_location
|
22
|
+
# end
|
23
|
+
|
24
|
+
# module ClassMethods
|
25
|
+
# def self.extended(base)
|
26
|
+
# base.class_eval do
|
27
|
+
# @delegate = self
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
|
31
|
+
# def delegate_timezone_to(delegate)
|
32
|
+
# @delegate = delegate
|
33
|
+
# end
|
34
|
+
|
35
|
+
# def timezone_accessor_methods
|
36
|
+
# @timezone_accessor_methods ||= set_timezone_accessors
|
37
|
+
# end
|
38
|
+
|
39
|
+
# def set_timezone_accessors(location: :timezone_location, short: :short_timezone, long: :long_timezone, offset: :utc_offset)
|
40
|
+
# @timezone_accessor_methods = {
|
41
|
+
# timezone_location: location,
|
42
|
+
# short_timezone: short,
|
43
|
+
# long_timezone: long,
|
44
|
+
# utc_offset: offset
|
45
|
+
# }
|
46
|
+
# end
|
47
|
+
# end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# delegate_timezone_to :settings
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module NitroRails::PerformableRoutes
|
2
|
+
def performable(resource_name)
|
3
|
+
namespace = "sequence"
|
4
|
+
controller = "#{namespace}/#{resource_name}"
|
5
|
+
|
6
|
+
# Initiate (post)
|
7
|
+
post "#{resource_name}/initiate", to: "#{controller}#initiate", as: "initiate_#{resource_name.to_s.singularize}"
|
8
|
+
# Setup (get)
|
9
|
+
get "#{resource_name}/:id/setup", to: "#{controller}#setup", as: "setup_#{resource_name.to_s.singularize}"
|
10
|
+
# Start (post)
|
11
|
+
post "#{resource_name}/:id/start", to: "#{controller}#start", as: "start_#{resource_name.to_s.singularize}"
|
12
|
+
# Perform (get)
|
13
|
+
get "#{resource_name}/:id/perform", to: "#{controller}#perform", as: "perform_#{resource_name.to_s.singularize}"
|
14
|
+
get "#{resource_name}/:id/perform/:step", to: "#{controller}#perform", as: "perform_#{resource_name.to_s.singularize}_step"
|
15
|
+
# Next step (post)
|
16
|
+
post "#{resource_name}/:id/perform/:step/next", to: "#{controller}#next", as: "#{resource_name.to_s.singularize}_next_step"
|
17
|
+
# Back step (post)
|
18
|
+
post "#{resource_name}/:id/perform/:step/back", to: "#{controller}#back", as: "#{resource_name.to_s.singularize}_back_step"
|
19
|
+
# Complete (post)
|
20
|
+
post "#{resource_name}/:id/complete", to: "#{controller}#complete", as: "complete_#{resource_name.to_s.singularize}"
|
21
|
+
# Abandon (post)
|
22
|
+
post "#{resource_name}/:id/abandon", to: "#{controller}#abandon", as: "abandon_#{resource_name.to_s.singularize}"
|
23
|
+
end
|
24
|
+
end
|