super 0.0.13 → 0.0.14
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 +1 -1
- data/app/assets/javascripts/super/application.js +5299 -5925
- data/app/assets/stylesheets/super/application.css +115322 -72920
- data/app/controllers/super/application_controller.rb +5 -0
- data/app/views/layouts/super/application.html.erb +15 -12
- data/app/views/super/application/_layout.html.erb +1 -1
- data/frontend/super-frontend/dist/application.css +115322 -72920
- data/frontend/super-frontend/dist/application.js +5299 -5925
- data/lib/generators/super/webpacker/webpacker_generator.rb +9 -5
- data/lib/super.rb +2 -1
- data/lib/super/assets.rb +44 -23
- data/lib/super/cheat.rb +17 -0
- data/lib/super/compatibility.rb +19 -0
- data/lib/super/link.rb +37 -31
- data/lib/super/link_builder.rb +58 -0
- data/lib/super/navigation.rb +164 -0
- data/lib/super/version.rb +1 -1
- data/lib/tasks/super/cheat.rake +9 -0
- metadata +6 -3
- data/lib/super/navigation/automatic.rb +0 -73
@@ -5,10 +5,14 @@ module Super
|
|
5
5
|
source_root File.expand_path("templates", __dir__)
|
6
6
|
|
7
7
|
def copy_the_pack_file
|
8
|
-
|
9
|
-
"
|
10
|
-
|
11
|
-
|
8
|
+
path =
|
9
|
+
if Gem::Dependency.new("webpacker", ">= 6.0.0.beta2", "!= 6.0.0.pre1", "!= 6.0.0.pre2").matching_specs.any?
|
10
|
+
"app/packs/entrypoints/super/application.js.erb"
|
11
|
+
else
|
12
|
+
"app/javascript/packs/super/application.js.erb"
|
13
|
+
end
|
14
|
+
|
15
|
+
template("pack_super_application.js.erb", path)
|
12
16
|
end
|
13
17
|
|
14
18
|
def set_asset_handler_to_webpacker
|
@@ -16,7 +20,7 @@ module Super
|
|
16
20
|
"config/initializers/super.rb",
|
17
21
|
" c.javascripts = Super::Assets.use_webpacker(c.javascripts)\n" \
|
18
22
|
" c.stylesheets = Super::Assets.use_webpacker(c.stylesheets)\n",
|
19
|
-
before:
|
23
|
+
before: /^end\b/
|
20
24
|
)
|
21
25
|
end
|
22
26
|
|
data/lib/super.rb
CHANGED
@@ -31,7 +31,8 @@ require "super/form/schema_types"
|
|
31
31
|
require "super/form/strong_params"
|
32
32
|
require "super/layout"
|
33
33
|
require "super/link"
|
34
|
-
require "super/
|
34
|
+
require "super/link_builder"
|
35
|
+
require "super/navigation"
|
35
36
|
require "super/pagination"
|
36
37
|
require "super/panel"
|
37
38
|
require "super/partial"
|
data/lib/super/assets.rb
CHANGED
@@ -21,7 +21,7 @@ module Super
|
|
21
21
|
assets.map do |asset|
|
22
22
|
grep_matches = grep && asset === grep
|
23
23
|
if grep_matches || !grep
|
24
|
-
asset.
|
24
|
+
asset.send(:handler=, Handler.webpacker)
|
25
25
|
end
|
26
26
|
|
27
27
|
asset
|
@@ -34,7 +34,7 @@ module Super
|
|
34
34
|
assets.map do |asset|
|
35
35
|
grep_matches = grep && asset === grep
|
36
36
|
if grep_matches || !grep
|
37
|
-
asset.
|
37
|
+
asset.send(:handler=, Handler.sprockets)
|
38
38
|
end
|
39
39
|
|
40
40
|
asset
|
@@ -52,6 +52,14 @@ module Super
|
|
52
52
|
attr_reader :path
|
53
53
|
attr_reader :arguments
|
54
54
|
|
55
|
+
def ==(other)
|
56
|
+
return false if handler != other.handler
|
57
|
+
return false if path != other.path
|
58
|
+
return false if arguments != other.arguments
|
59
|
+
|
60
|
+
true
|
61
|
+
end
|
62
|
+
|
55
63
|
def ===(other)
|
56
64
|
return true if path == other
|
57
65
|
return true if other.is_a?(Regexp) && path.match?(other)
|
@@ -61,6 +69,10 @@ module Super
|
|
61
69
|
|
62
70
|
false
|
63
71
|
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
attr_writer :handler
|
64
76
|
end
|
65
77
|
|
66
78
|
def self.dist(gem_name, package_name)
|
@@ -74,29 +86,34 @@ module Super
|
|
74
86
|
end
|
75
87
|
|
76
88
|
class Handler
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
else
|
94
|
-
none
|
89
|
+
class << self
|
90
|
+
def auto
|
91
|
+
sprockets_spec = gem_specification("sprockets")
|
92
|
+
if sprockets_spec
|
93
|
+
major = sprockets_spec.version.segments.first
|
94
|
+
if major >= 2
|
95
|
+
return sprockets
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
webpacker_spec = gem_specification("webpacker")
|
100
|
+
if webpacker_spec
|
101
|
+
major = webpacker_spec.version.segments.first
|
102
|
+
if major >= 4
|
103
|
+
return webpacker
|
104
|
+
end
|
95
105
|
end
|
96
|
-
end
|
97
106
|
|
98
|
-
|
99
|
-
|
107
|
+
none
|
108
|
+
end
|
109
|
+
|
110
|
+
def sprockets_available?
|
111
|
+
!gem_specification("sprockets").nil? && defined?(Sprockets)
|
112
|
+
end
|
113
|
+
|
114
|
+
def gem_specification(gem_name)
|
115
|
+
Gem::Dependency.new(gem_name).matching_specs&.sort_by(&:version)&.first
|
116
|
+
end
|
100
117
|
end
|
101
118
|
|
102
119
|
def self.sprockets
|
@@ -115,6 +132,10 @@ module Super
|
|
115
132
|
@asset_handler = asset_handler
|
116
133
|
end
|
117
134
|
|
135
|
+
def ==(other)
|
136
|
+
to_sym == other.to_sym
|
137
|
+
end
|
138
|
+
|
118
139
|
def sprockets?
|
119
140
|
@asset_handler == :sprockets
|
120
141
|
end
|
data/lib/super/cheat.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Super
|
4
|
+
class Cheat
|
5
|
+
def controls
|
6
|
+
paths = %w[controls.rb controls/optional.rb controls/steps.rb controls/view.rb]
|
7
|
+
methods =
|
8
|
+
paths
|
9
|
+
.map { |f| File.read(File.join(__dir__, f)) }
|
10
|
+
.flat_map { |content| content.scan(/^\s+def .*$/) }
|
11
|
+
.map { |method| method.strip.sub(/^def /, "#") }
|
12
|
+
|
13
|
+
puts "== Super::Controls"
|
14
|
+
puts methods.join("\n")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/super/compatibility.rb
CHANGED
@@ -23,5 +23,24 @@ module Super
|
|
23
23
|
ActiveRecord::Base.sanitize_sql_like(query)
|
24
24
|
end
|
25
25
|
end
|
26
|
+
|
27
|
+
def polymorphic_path_container
|
28
|
+
if Rails::VERSION::MAJOR == 5 && Rails::VERSION::MINOR == 0
|
29
|
+
@polymorphic_path_container ||=
|
30
|
+
begin
|
31
|
+
klass = Class.new do
|
32
|
+
include ActionDispatch::Routing::PolymorphicRoutes
|
33
|
+
|
34
|
+
def method_missing(method_name)
|
35
|
+
Rails.application.routes.url_helpers.public_send(method_name)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
klass.new
|
40
|
+
end
|
41
|
+
else
|
42
|
+
Rails.application.routes.url_helpers
|
43
|
+
end
|
44
|
+
end
|
26
45
|
end
|
27
46
|
end
|
data/lib/super/link.rb
CHANGED
@@ -22,57 +22,57 @@ module Super
|
|
22
22
|
|
23
23
|
def self.registry
|
24
24
|
@registry ||= {
|
25
|
-
new: new(
|
25
|
+
new: LinkBuilder.new(
|
26
26
|
"New",
|
27
27
|
-> (params:) {
|
28
|
-
|
28
|
+
{
|
29
29
|
controller: params[:controller],
|
30
30
|
action: :new,
|
31
31
|
only_path: true
|
32
|
-
|
32
|
+
}
|
33
33
|
}
|
34
34
|
),
|
35
|
-
index: new(
|
35
|
+
index: LinkBuilder.new(
|
36
36
|
"Index",
|
37
37
|
-> (params:) {
|
38
|
-
|
38
|
+
{
|
39
39
|
controller: params[:controller],
|
40
40
|
action: :index,
|
41
41
|
only_path: true
|
42
|
-
|
42
|
+
}
|
43
43
|
}
|
44
44
|
),
|
45
|
-
show: new(
|
45
|
+
show: LinkBuilder.new(
|
46
46
|
"View",
|
47
47
|
-> (record:, params:) {
|
48
|
-
|
48
|
+
{
|
49
49
|
controller: params[:controller],
|
50
50
|
action: :show,
|
51
51
|
id: record,
|
52
52
|
only_path: true
|
53
|
-
|
53
|
+
}
|
54
54
|
}
|
55
55
|
),
|
56
|
-
edit: new(
|
56
|
+
edit: LinkBuilder.new(
|
57
57
|
"Edit",
|
58
58
|
-> (record:, params:) {
|
59
|
-
|
59
|
+
{
|
60
60
|
controller: params[:controller],
|
61
61
|
action: :edit,
|
62
62
|
id: record,
|
63
63
|
only_path: true
|
64
|
-
|
64
|
+
}
|
65
65
|
}
|
66
66
|
),
|
67
|
-
destroy: new(
|
67
|
+
destroy: LinkBuilder.new(
|
68
68
|
"Delete",
|
69
69
|
-> (record:, params:) {
|
70
|
-
|
70
|
+
{
|
71
71
|
controller: params[:controller],
|
72
72
|
action: :destroy,
|
73
73
|
id: record,
|
74
74
|
only_path: true
|
75
|
-
|
75
|
+
}
|
76
76
|
},
|
77
77
|
method: :delete,
|
78
78
|
data: { confirm: "Really delete?" }
|
@@ -91,27 +91,33 @@ module Super
|
|
91
91
|
@options = options
|
92
92
|
end
|
93
93
|
|
94
|
-
|
94
|
+
attr_reader :text
|
95
|
+
attr_reader :options
|
96
|
+
|
97
|
+
def href
|
98
|
+
if @href.is_a?(String)
|
99
|
+
return @href
|
100
|
+
end
|
101
|
+
|
102
|
+
if @href.is_a?(Hash)
|
103
|
+
@href = Rails.application.routes.url_for(**@href)
|
104
|
+
return @href
|
105
|
+
end
|
106
|
+
|
107
|
+
@href = Super::Compatability.polymorphic_path_container.polymorphic_path(@href)
|
108
|
+
end
|
109
|
+
|
110
|
+
def to_s(default_options: nil)
|
95
111
|
default_options ||= {}
|
96
112
|
ActionController::Base.helpers.link_to(
|
97
|
-
|
98
|
-
|
99
|
-
default_options.deep_merge(
|
113
|
+
text,
|
114
|
+
href,
|
115
|
+
default_options.deep_merge(options)
|
100
116
|
)
|
101
117
|
end
|
102
118
|
|
103
|
-
|
104
|
-
|
105
|
-
attr_reader :text
|
106
|
-
attr_reader :href
|
107
|
-
attr_reader :options
|
108
|
-
|
109
|
-
def value(proc_or_value, proc_arguments)
|
110
|
-
if proc_or_value.kind_of?(Proc)
|
111
|
-
proc_or_value.call(**proc_arguments)
|
112
|
-
else
|
113
|
-
proc_or_value
|
114
|
-
end
|
119
|
+
def ==(other)
|
120
|
+
self.class == other.class && text == other.text && href == other.href && options == other.options
|
115
121
|
end
|
116
122
|
end
|
117
123
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Super
|
4
|
+
class LinkBuilder
|
5
|
+
def initialize(text, href, **options)
|
6
|
+
@text = text
|
7
|
+
@href = href
|
8
|
+
@options = options
|
9
|
+
@requirements = []
|
10
|
+
@requirements += gather_requirements(text)
|
11
|
+
@requirements += gather_requirements(href)
|
12
|
+
@requirements += gather_requirements(options)
|
13
|
+
|
14
|
+
unknown_arguments = @requirements - known_requirements
|
15
|
+
if unknown_arguments.any?
|
16
|
+
raise Error::ArgumentError, "Unknown arguments: #{unknown_arguments.join(", ")}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_reader :requirements
|
21
|
+
|
22
|
+
def to_s(default_options: nil, **kwargs)
|
23
|
+
resolve(**kwargs).to_s(default_options: default_options)
|
24
|
+
end
|
25
|
+
|
26
|
+
def resolve(**kwargs)
|
27
|
+
Link.new(
|
28
|
+
into_value(@text, kwargs),
|
29
|
+
into_value(@href, kwargs),
|
30
|
+
**into_value(@options, kwargs),
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def known_requirements
|
37
|
+
%i[params record].freeze
|
38
|
+
end
|
39
|
+
|
40
|
+
def gather_requirements(value_or_proc)
|
41
|
+
return [] if !value_or_proc.is_a?(Proc)
|
42
|
+
|
43
|
+
requirements =
|
44
|
+
value_or_proc
|
45
|
+
.parameters
|
46
|
+
.select { |(kind, name)| kind = :keyreq }
|
47
|
+
.map(&:last)
|
48
|
+
end
|
49
|
+
|
50
|
+
def into_value(value_or_proc, kwargs)
|
51
|
+
if value_or_proc.kind_of?(Proc)
|
52
|
+
value_or_proc.call(**kwargs)
|
53
|
+
else
|
54
|
+
value_or_proc
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Super
|
4
|
+
class Navigation
|
5
|
+
def initialize
|
6
|
+
@builder = Builder.new
|
7
|
+
@definition = yield @builder
|
8
|
+
if !@definition.is_a?(Array)
|
9
|
+
@definition = [@definition]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def definition
|
14
|
+
return @defs if instance_variable_defined?(:@defs)
|
15
|
+
|
16
|
+
searcher = RouteFormatterButReallySearcher.new
|
17
|
+
inspector = ActionDispatch::Routing::RoutesInspector.new(Rails.application.routes.routes)
|
18
|
+
inspector.format(searcher)
|
19
|
+
all_matches = searcher.matches
|
20
|
+
unused_matches = all_matches.each_with_object({}) { |match, hash| hash[match] = true }
|
21
|
+
|
22
|
+
defs = expand_proc_syntax_sugar(@definition)
|
23
|
+
defs = validate_and_determine_explicit_links(defs, unused_matches)
|
24
|
+
@defs = expand_directives(defs, all_matches, unused_matches.keys)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# This expands the syntax sugar that allows `nav.menu("Name")[nav.link(Item)]`
|
30
|
+
def expand_proc_syntax_sugar(definition)
|
31
|
+
definition.map do |link_or_menu_or_rest_or_menuproc|
|
32
|
+
link_or_menu_or_rest =
|
33
|
+
if link_or_menu_or_rest_or_menuproc.is_a?(Proc)
|
34
|
+
link_or_menu_or_rest_or_menuproc.call
|
35
|
+
else
|
36
|
+
link_or_menu_or_rest_or_menuproc
|
37
|
+
end
|
38
|
+
|
39
|
+
if link_or_menu_or_rest.is_a?(Menu)
|
40
|
+
link_or_menu_or_rest.links = link_or_menu_or_rest.links.map do |menu_item|
|
41
|
+
if menu_item.is_a?(Proc)
|
42
|
+
menu_item.call
|
43
|
+
else
|
44
|
+
menu_item
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
link_or_menu_or_rest
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def validate_and_determine_explicit_links(definition, unused_links)
|
54
|
+
definition.each do |link_or_menu_or_rest|
|
55
|
+
if link_or_menu_or_rest.is_a?(Super::Link)
|
56
|
+
unused_links.delete(link_or_menu_or_rest.href)
|
57
|
+
elsif link_or_menu_or_rest.is_a?(Menu)
|
58
|
+
link_or_menu_or_rest.links.each do |link_or_rest|
|
59
|
+
if link_or_rest.is_a?(Menu)
|
60
|
+
raise Super::Error::ArgumentError, "Navigation menus can't be nested"
|
61
|
+
end
|
62
|
+
|
63
|
+
if link_or_rest.is_a?(Link)
|
64
|
+
unused_links.delete(link_or_rest.href)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def expand_directives(defs, all_hrefs, rest_hrefs)
|
72
|
+
defs.flat_map do |link_or_menu_or_rest|
|
73
|
+
if link_or_menu_or_rest.is_a?(Menu)
|
74
|
+
link_or_menu_or_rest.links = link_or_menu_or_rest.links.flat_map do |link_or_rest|
|
75
|
+
if link_or_rest == ALL
|
76
|
+
linkify_hrefs(all_hrefs)
|
77
|
+
elsif link_or_rest == REST
|
78
|
+
linkify_hrefs(rest_hrefs)
|
79
|
+
else
|
80
|
+
link_or_rest
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
link_or_menu_or_rest
|
85
|
+
elsif link_or_menu_or_rest == ALL
|
86
|
+
linkify_hrefs(all_hrefs)
|
87
|
+
elsif link_or_menu_or_rest == REST
|
88
|
+
linkify_hrefs(rest_hrefs)
|
89
|
+
else
|
90
|
+
link_or_menu_or_rest
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def linkify_hrefs(hrefs)
|
96
|
+
hrefs.map do |href|
|
97
|
+
Super::Link.new(href.split("/").last.humanize, href)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
ALL = Object.new
|
102
|
+
REST = Object.new
|
103
|
+
Menu = Struct.new(:title, :links)
|
104
|
+
|
105
|
+
class Builder
|
106
|
+
def link(model, **kwargs)
|
107
|
+
text = model.model_name.human.pluralize
|
108
|
+
parts = Super::Link.polymorphic_parts(model)
|
109
|
+
|
110
|
+
Super::Link.new(text, parts, **kwargs)
|
111
|
+
end
|
112
|
+
|
113
|
+
def link_to(*args, **kwargs)
|
114
|
+
Super::Link.new(*args, **kwargs)
|
115
|
+
end
|
116
|
+
|
117
|
+
def menu(title, *links)
|
118
|
+
menu = Menu.new(title, links)
|
119
|
+
proc do |*more_links|
|
120
|
+
menu.links += more_links
|
121
|
+
menu
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def rest
|
126
|
+
REST
|
127
|
+
end
|
128
|
+
|
129
|
+
def all
|
130
|
+
ALL
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
class RouteFormatterButReallySearcher
|
135
|
+
def initialize(route_namespace: Super.configuration.path)
|
136
|
+
@route_namespace = route_namespace.strip.gsub(%r{\A/+}, "").gsub(%r{/+\z}, "").strip
|
137
|
+
@route_namespace = "/#{@route_namespace}/"
|
138
|
+
@matches = []
|
139
|
+
end
|
140
|
+
|
141
|
+
def matches
|
142
|
+
@matches.map do |route|
|
143
|
+
route[:path].sub(/\(.*\)\Z/, "")
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def section(routes)
|
148
|
+
@matches += routes.select do |route|
|
149
|
+
next false unless route[:verb] == "GET" || route[:verb] == ""
|
150
|
+
next false unless route[:path].start_with?(@route_namespace)
|
151
|
+
next false if route[:path].include?("/:")
|
152
|
+
next false if route[:reqs].end_with?("#new")
|
153
|
+
|
154
|
+
true
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def header(routes); end
|
159
|
+
def no_routes(routes, filter); end
|
160
|
+
def result; end
|
161
|
+
def section_title(title); end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|