super 0.17.0 → 0.20.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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -4
  3. data/app/assets/javascripts/super/application.js +1260 -117
  4. data/app/assets/stylesheets/super/application.css +90711 -90034
  5. data/app/controllers/super/application_controller.rb +34 -4
  6. data/app/controllers/super/substructure_controller.rb +125 -29
  7. data/app/helpers/super/form_builder_helper.rb +4 -4
  8. data/app/views/layouts/super/application.html.erb +1 -1
  9. data/app/views/super/application/_batch_button.html.erb +12 -0
  10. data/app/views/super/application/_batch_checkbox.csv.erb +1 -0
  11. data/app/views/super/application/_batch_checkbox.html.erb +9 -0
  12. data/app/views/super/application/_batch_form.html.erb +3 -0
  13. data/app/views/super/application/_collection_header.html.erb +7 -6
  14. data/app/views/super/application/_csv_button.html.erb +25 -0
  15. data/app/views/super/application/_display_actions.html.erb +2 -2
  16. data/app/views/super/application/_form.html.erb +1 -1
  17. data/app/views/super/application/_layout.html.erb +13 -14
  18. data/app/views/super/application/_link.html.erb +8 -0
  19. data/app/views/super/application/_member_header.html.erb +7 -7
  20. data/app/views/super/application/_pagination.html.erb +2 -4
  21. data/app/views/super/application/_site_footer.html.erb +1 -1
  22. data/app/views/super/application/_site_header.html.erb +4 -4
  23. data/app/views/super/application/_view_chain.html.erb +5 -0
  24. data/app/views/super/application/index.csv.erb +14 -0
  25. data/config/locales/en.yml +15 -1
  26. data/frontend/super-frontend/dist/application.css +90711 -90034
  27. data/frontend/super-frontend/dist/application.js +6512 -5379
  28. data/frontend/super-frontend/dist/package.json +13 -0
  29. data/lib/generators/super/webpacker/USAGE +1 -7
  30. data/lib/generators/super/webpacker/templates/pack_super_application.js.tt +2 -0
  31. data/lib/generators/super/webpacker/webpacker_generator.rb +10 -6
  32. data/lib/super/action_inquirer.rb +3 -0
  33. data/lib/super/cheat.rb +1 -0
  34. data/lib/super/display/schema_types.rb +6 -0
  35. data/lib/super/display.rb +2 -1
  36. data/lib/super/engine.rb +5 -0
  37. data/lib/super/error.rb +11 -0
  38. data/lib/super/form/schema_types.rb +8 -36
  39. data/lib/super/form_builder/action_text_methods.rb +16 -0
  40. data/lib/super/form_builder/base_methods.rb +73 -0
  41. data/lib/super/form_builder/flatpickr_methods.rb +75 -0
  42. data/lib/super/form_builder/option_methods.rb +73 -0
  43. data/lib/super/form_builder.rb +143 -0
  44. data/lib/super/layout.rb +9 -33
  45. data/lib/super/link.rb +49 -70
  46. data/lib/super/link_builder.rb +24 -47
  47. data/lib/super/packaged_asset.rb +49 -0
  48. data/lib/super/pagination.rb +2 -1
  49. data/lib/super/reorderable_hash.rb +88 -0
  50. data/lib/super/reset.rb +20 -1
  51. data/lib/super/useful/i19.rb +35 -0
  52. data/lib/super/version.rb +1 -1
  53. data/lib/super/view_chain.rb +25 -0
  54. data/lib/super.rb +9 -1
  55. metadata +55 -10
  56. data/lib/generators/super/webpacker/templates/pack_super_application.js.erb.tt +0 -2
  57. data/lib/super/form/builder.rb +0 -289
data/lib/super/link.rb CHANGED
@@ -9,75 +9,43 @@ module Super
9
9
  end
10
10
 
11
11
  def self.find(link)
12
- if link.kind_of?(self)
13
- return link
14
- end
15
-
16
12
  if registry.key?(link)
17
- return registry[link]
13
+ found = registry[link]
14
+
15
+ if found.is_a?(LinkBuilder)
16
+ return found.dup
17
+ else
18
+ return found
19
+ end
18
20
  end
19
21
 
20
22
  raise Error::LinkNotRegistered, "Unknown link `#{link}`"
21
23
  end
22
24
 
23
25
  def self.registry
24
- @registry ||= {
25
- new: LinkBuilder.new(
26
- "New",
27
- -> (params:) {
28
- {
29
- controller: params[:controller],
30
- action: :new,
31
- only_path: true
32
- }
33
- }
34
- ),
35
- index: LinkBuilder.new(
36
- "Index",
37
- -> (params:) {
38
- {
39
- controller: params[:controller],
40
- action: :index,
41
- only_path: true
42
- }
43
- }
44
- ),
45
- show: LinkBuilder.new(
46
- "View",
47
- -> (record:, params:) {
48
- {
49
- controller: params[:controller],
50
- action: :show,
51
- id: record,
52
- only_path: true
53
- }
54
- }
55
- ),
56
- edit: LinkBuilder.new(
57
- "Edit",
58
- -> (record:, params:) {
59
- {
60
- controller: params[:controller],
61
- action: :edit,
62
- id: record,
63
- only_path: true
64
- }
65
- }
66
- ),
67
- destroy: LinkBuilder.new(
68
- "Delete",
69
- -> (record:, params:) {
70
- {
71
- controller: params[:controller],
72
- action: :destroy,
73
- id: record,
74
- only_path: true
75
- }
76
- },
77
- method: :delete,
78
- data: { confirm: "Really delete?" }
79
- ),
80
- }
26
+ @registry ||= {}.tap do |reg|
27
+ reg[:new] = LinkBuilder.new
28
+ .text { |params:| Super::Useful::I19.i18n_with_fallback("super", params[:controller].split("/"), "actions.new") }
29
+ .href { |params:| { controller: params[:controller], action: :new, only_path: true } }
30
+ .freeze
31
+ reg[:index] = LinkBuilder.new
32
+ .text { |params:| Super::Useful::I19.i18n_with_fallback("super", params[:controller].split("/"), "actions.index") }
33
+ .href { |params:| { controller: params[:controller], action: :index, only_path: true } }
34
+ .freeze
35
+ reg[:show] = LinkBuilder.new
36
+ .text { |params:, **| Super::Useful::I19.i18n_with_fallback("super", params[:controller].split("/"), "actions.show") }
37
+ .href { |params:, record:| { controller: params[:controller], action: :show, id: record, only_path: true } }
38
+ .freeze
39
+ reg[:edit] = LinkBuilder.new
40
+ .text { |params:, **| Super::Useful::I19.i18n_with_fallback("super", params[:controller].split("/"), "actions.edit") }
41
+ .href { |params:, record:| { controller: params[:controller], action: :edit, id: record, only_path: true } }
42
+ .freeze
43
+ reg[:destroy] = LinkBuilder.new
44
+ .text { |params:, **| Super::Useful::I19.i18n_with_fallback("super", params[:controller].split("/"), "actions.destroy") }
45
+ .href { |params:, record:| { controller: params[:controller], action: :destroy, id: record, only_path: true } }
46
+ .options { |**| { method: :delete, data: { confirm: "Really delete?" } } }
47
+ .freeze
48
+ end
81
49
  end
82
50
 
83
51
  def self.polymorphic_parts(*parts_tail)
@@ -85,15 +53,31 @@ module Super
85
53
  parts_head.map { |part| part.is_a?(String) ? part.to_sym : part } + parts_tail
86
54
  end
87
55
 
56
+ # The first argument should be the text of the link. If it's an array,
57
+ # it'll send it directly into `I18n.t`
88
58
  def initialize(text, href, **options)
89
59
  @text = text
90
60
  @href = href
91
61
  @options = options
92
62
  end
93
63
 
94
- attr_reader :text
95
64
  attr_reader :options
96
65
 
66
+ def text
67
+ if @text.is_a?(Array)
68
+ *head, tail = @text
69
+ if !tail.is_a?(Hash)
70
+ head.push(tail)
71
+ tail = {}
72
+ end
73
+
74
+ @text = I18n.t(*head, **tail)
75
+ return @text
76
+ end
77
+
78
+ @text
79
+ end
80
+
97
81
  def href
98
82
  if @href.is_a?(String)
99
83
  return @href
@@ -107,13 +91,8 @@ module Super
107
91
  @href = Super::Compatability.polymorphic_path_container.polymorphic_path(@href)
108
92
  end
109
93
 
110
- def to_s(default_options: nil, **)
111
- default_options ||= {}
112
- ActionController::Base.helpers.link_to(
113
- text,
114
- href,
115
- default_options.deep_merge(options)
116
- )
94
+ def to_partial_path
95
+ "link"
117
96
  end
118
97
 
119
98
  def ==(other)
@@ -2,57 +2,34 @@
2
2
 
3
3
  module Super
4
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)
5
+ %i[text href options].each do |method_name|
6
+ class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
7
+ def #{method_name}(&block)
8
+ @#{method_name} = block
9
+ self
10
+ end
11
+
12
+ def process_#{method_name}(&block)
13
+ @process_#{method_name} = block
14
+ self
15
+ end
16
+ RUBY
24
17
  end
25
18
 
26
19
  def resolve(**kwargs)
27
- Link.new(
28
- into_value(@text, kwargs),
29
- into_value(@href, kwargs),
30
- **into_value(@options, kwargs),
20
+ raise Super::Error::IncompleteBuilder, "LinkBuilder requires that #text is set" if @text.nil?
21
+ raise Super::Error::IncompleteBuilder, "LinkBuilder requires that #href is set" if @href.nil?
22
+
23
+ @options ||= -> (**) { {} }
24
+ @process_text ||= -> (t) { t }
25
+ @process_href ||= -> (h) { h }
26
+ @process_options ||= -> (o) { o }
27
+
28
+ Super::Link.new(
29
+ @process_text.call(@text.call(**kwargs)),
30
+ @process_href.call(@href.call(**kwargs)),
31
+ **@process_options.call(@options.call(**kwargs))
31
32
  )
32
33
  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
34
  end
58
35
  end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Super
4
+ class PackagedAsset
5
+ VERSION_BEGINNING = /\A\d+\.\d+.\d+/.freeze
6
+
7
+ class << self
8
+ attr_accessor :warning_message
9
+ end
10
+
11
+ def self.comparable_super_version
12
+ ::Super::VERSION[VERSION_BEGINNING]
13
+ end
14
+
15
+ def self.version_matches_gem?(package_json_path)
16
+ return true if ENV.key?("SUPER_IGNORE_PACKAGE_JSON_VERSION")
17
+
18
+ asset = new(package_json_path)
19
+
20
+ return true if !asset.comparable_version
21
+
22
+ asset.comparable_version == comparable_super_version
23
+ end
24
+
25
+ def initialize(package_json_path)
26
+ @package_json_path = package_json_path
27
+ end
28
+
29
+ def full_version
30
+ if instance_variable_defined?(:@full_version)
31
+ return @full_version
32
+ end
33
+
34
+ @full_version = JSON.parse(@package_json_path.read).dig("dependencies", "@superadministration/super")
35
+ rescue
36
+ @full_version = nil
37
+ end
38
+
39
+ def comparable_version
40
+ if instance_variable_defined?(:@asset_version)
41
+ return @asset_version
42
+ end
43
+
44
+ @asset_version = full_version[VERSION_BEGINNING]
45
+ rescue
46
+ @asset_version = nil
47
+ end
48
+ end
49
+ end
@@ -76,9 +76,10 @@ module Super
76
76
  module ControllerMethods
77
77
  def index
78
78
  super
79
+ return if !@records
79
80
  @pagination = initialize_pagination
80
81
  @records = paginate_records
81
- @view.mains.first.parts.push(:@pagination)
82
+ @view.main.insert(:pagination, @pagination, before: :main)
82
83
  end
83
84
  end
84
85
  end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Super
4
+ class ReorderableHash
5
+ include TSort
6
+ include Enumerable
7
+
8
+ UNDEFINED = BasicObject.new
9
+
10
+ def initialize(data = {})
11
+ @data = data
12
+ @ordering = {}
13
+ keys = @data.keys
14
+ dependencies = []
15
+ keys.each do |key|
16
+ @ordering[key] = dependencies.dup
17
+ dependencies.push(key)
18
+ end
19
+ end
20
+
21
+ def insert(key, value, before: UNDEFINED, after: UNDEFINED)
22
+ if @ordering.key?(key) || @data.key?(key)
23
+ raise Super::Error::ReorderableHash::DuplicateKey, "Duplicate key: #{key}"
24
+ end
25
+ @ordering[key] = []
26
+ @data[key] = value
27
+
28
+ order(key, before: before, after: after)
29
+
30
+ nil
31
+ end
32
+
33
+ def order(key, before: UNDEFINED, after: UNDEFINED)
34
+ if before != UNDEFINED
35
+ if !@ordering.key?(before)
36
+ raise KeyError, "Before key not found. Have: #{@data.keys} Requested: #{before}"
37
+ end
38
+ @ordering[before].push(key)
39
+ end
40
+
41
+ if after != UNDEFINED
42
+ if !@ordering.key?(after)
43
+ raise KeyError, "After key not found. Have: #{@data.keys} Requested: #{after}"
44
+ end
45
+ @ordering[key].push(after)
46
+ end
47
+ end
48
+
49
+ def tsort_each_node(&block)
50
+ @ordering.each_key(&block)
51
+ end
52
+
53
+ def tsort_each_child(node, &block)
54
+ dependencies = @ordering.fetch(node) { [] }
55
+ dependencies.each(&block)
56
+ end
57
+
58
+ def []=(key, where, value)
59
+ insert(key, value, **where)
60
+ end
61
+
62
+ def keys
63
+ tsort
64
+ end
65
+
66
+ def values
67
+ keys.each_with_object([]) do |key, array|
68
+ array.push(@data[key])
69
+ end
70
+ end
71
+
72
+ def to_h
73
+ keys.each_with_object({}) do |key, hash|
74
+ hash[key] = @data[key]
75
+ end
76
+ end
77
+
78
+ def each
79
+ if !block_given?
80
+ return enum_for(:each)
81
+ end
82
+
83
+ tsort_each do |key|
84
+ yield key, @data[key]
85
+ end
86
+ end
87
+ end
88
+ end
data/lib/super/reset.rb CHANGED
@@ -4,6 +4,20 @@ module Super
4
4
  module Reset
5
5
  extend ActiveSupport::Concern
6
6
 
7
+ KEEP = {
8
+ # Defined by Rails
9
+ _layout: true,
10
+ _generate_paths_by_default: true,
11
+
12
+ # Defined in Super::SubstructureController
13
+ navigation: true,
14
+ page_title: true,
15
+
16
+ # Defined in Super::ApplicationController
17
+ current_action: true,
18
+ with_current_action: true,
19
+ }
20
+
7
21
  included do
8
22
  undef_method :index
9
23
  undef_method :show
@@ -14,7 +28,12 @@ module Super
14
28
  undef_method :destroy
15
29
 
16
30
  Super::SubstructureController.private_instance_methods(false).each do |imethod|
17
- next if imethod == :navigation
31
+ next if KEEP.key?(imethod)
32
+ undef_method imethod
33
+ end
34
+
35
+ Super::ApplicationController.private_instance_methods(false).each do |imethod|
36
+ next if KEEP.key?(imethod)
18
37
  undef_method imethod
19
38
  end
20
39
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Super
4
+ module Useful
5
+ module I19
6
+ module_function
7
+
8
+ def build_chain(prefix, optional, suffix)
9
+ prefix = Array(prefix)
10
+ optional = Array(optional)
11
+ suffix = Array(suffix)
12
+
13
+ result = []
14
+
15
+ (optional.size + 1).times do
16
+ lookup = [prefix, optional, suffix].flatten.join(".").to_sym
17
+ result.push(lookup)
18
+ optional.pop
19
+ end
20
+
21
+ result
22
+ end
23
+
24
+ def chain_to_i18n(chain)
25
+ head, *tail = chain
26
+
27
+ [head, { default: tail }]
28
+ end
29
+
30
+ def i18n_with_fallback(prefix, optional, suffix)
31
+ chain_to_i18n(build_chain(prefix, optional, suffix))
32
+ end
33
+ end
34
+ end
35
+ end
data/lib/super/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Super
4
- VERSION = "0.17.0"
4
+ VERSION = "0.20.0"
5
5
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Super
4
+ class ViewChain
5
+ def initialize(chain)
6
+ @data = ReorderableHash.new(chain)
7
+ end
8
+
9
+ def chain
10
+ @chain ||= @data.values
11
+ end
12
+
13
+ def insert(*args, **kwargs)
14
+ if instance_variable_defined?(:@chain)
15
+ raise Error::ViewChain::ChainAlreadyStarted
16
+ end
17
+
18
+ @data.insert(*args, **kwargs)
19
+ end
20
+
21
+ def to_partial_path
22
+ "view_chain"
23
+ end
24
+ end
25
+ end
data/lib/super.rb CHANGED
@@ -7,6 +7,7 @@ require "rails/engine"
7
7
  require "super/schema/common"
8
8
  require "super/useful/builder"
9
9
  require "super/useful/enum"
10
+ require "super/useful/i19"
10
11
 
11
12
  require "super/action_inquirer"
12
13
  require "super/assets"
@@ -24,26 +25,33 @@ require "super/filter/guesser"
24
25
  require "super/filter/operator"
25
26
  require "super/filter/schema_types"
26
27
  require "super/form"
27
- require "super/form/builder"
28
28
  require "super/form/field_transcript"
29
29
  require "super/form/guesser"
30
30
  require "super/form/inline_errors"
31
31
  require "super/form/schema_types"
32
32
  require "super/form/strong_params"
33
+ require "super/form_builder"
34
+ require "super/form_builder/action_text_methods"
35
+ require "super/form_builder/base_methods"
36
+ require "super/form_builder/flatpickr_methods"
37
+ require "super/form_builder/option_methods"
33
38
  require "super/layout"
34
39
  require "super/link"
35
40
  require "super/link_builder"
36
41
  require "super/navigation"
42
+ require "super/packaged_asset"
37
43
  require "super/pagination"
38
44
  require "super/panel"
39
45
  require "super/partial"
40
46
  require "super/plugin"
41
47
  require "super/query/form_object"
48
+ require "super/reorderable_hash"
42
49
  require "super/reset"
43
50
  require "super/schema"
44
51
  require "super/schema/guesser"
45
52
  require "super/sort"
46
53
  require "super/version"
54
+ require "super/view_chain"
47
55
  require "super/view_helper"
48
56
 
49
57
  require "super/engine"