five-two-nw-olivander 0.1.2.1 → 0.1.2.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc230db07c2624d5ca4398239976b374c1fcdec0a4d741a27387f7ecfd3705dd
4
- data.tar.gz: 45767c0b8bfca58e6ce48672e6c8bc310baec3bc15c2bedf8f34d95e330085a0
3
+ metadata.gz: 597764e454652e4a42b1d81c7d63db17f9495a662886fd9184c7fc3790d16c75
4
+ data.tar.gz: faa979538cb5fa01390a65e0378054b3f916b3f3630ac45e586ff64fb43e9ffa
5
5
  SHA512:
6
- metadata.gz: b96d61fa31cb64a25fd0ceb3097979d4874763f88891fc503318a7b3f30fde73f306e9973525205f3876b9ea07739f7f4c45b4fa24c814289bcf2564984d0077
7
- data.tar.gz: 74ca5454b8081887b6c16ede1e4fa941248bc8854d41998dab7007011b07fe548efc6b970b1f5ccc6999b58d15a4a90fdb4e328e1b20992e0404c1397186a9fd
6
+ metadata.gz: b1d0847e4694082bcbf22f3717f4ea551f1144697b51e809539118402f347e46158767a8fdca8eab49b1262dde97e09ad964f8722b0d3701cfbfe3789478da34
7
+ data.tar.gz: 92df52efda623339deb45a35ad86c5a52e0205ba5eb49e71aa70d5683eb2df079825531407f58634c0970c0a6802b8c62081e6c910fdedd494dec4a88fbd90a6
@@ -0,0 +1,13 @@
1
+ module Olivander
2
+ module Resources
3
+ module AutoFormAttributes
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ def auto_form_attributes
8
+ attributes.keys - ['updated_at', 'created_at', 'deleted_at']
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,129 @@
1
+ module Olivander
2
+ module Resources
3
+ class ResourceAction
4
+ attr_accessor :sym, :action, :verb, :confirm, :turbo_frame, :collection, :controller, :crud_action, :show_in_form, :show_in_datatable, :no_route
5
+
6
+ def initialize(sym, action: nil, controller: nil, verb: :get, confirm: false, turbo_frame: nil, collection: false, crud_action: false,
7
+ show_in_form: true, show_in_datatable: true, no_route: false)
8
+ self.sym = sym
9
+ self.action = action || sym
10
+ self.controller = controller
11
+ self.verb = verb
12
+ self.confirm = confirm
13
+ self.turbo_frame = turbo_frame
14
+ self.collection = collection
15
+ self.crud_action = crud_action
16
+ self.show_in_form = show_in_form
17
+ self.show_in_datatable = show_in_datatable
18
+ self.no_route = no_route
19
+ end
20
+ end
21
+
22
+ class RoutedResource
23
+ attr_accessor :model, :actions
24
+
25
+ def initialize(model, crud_actions)
26
+ self.model = model
27
+ self.actions = []
28
+ crud_actions.each do |ca|
29
+ actions << ResourceAction.new(ca, controller: model, crud_action: true)
30
+ end
31
+ end
32
+
33
+ def crud_actions
34
+ actions.select{ |x| x.crud_action }
35
+ end
36
+
37
+ def additional_actions
38
+ actions.select{ |x| !x.crud_action }
39
+ end
40
+
41
+ def member_actions
42
+ additional_actions.select{ |x| !x.collection }
43
+ end
44
+
45
+ def collection_actions
46
+ additional_actions.select{ |x| x.collection }
47
+ end
48
+
49
+ def datatable_bulk_actions
50
+ collection_actions.select{ |x| x.show_in_datatable }
51
+ end
52
+
53
+ def unpersisted_crud_actions
54
+ allowed = %i[index new]
55
+ crud_actions.select{ |x| allowed.include?(x.sym) }
56
+ end
57
+
58
+ def persisted_crud_actions
59
+ allowed = %i[show edit destroy]
60
+ crud_actions.select{ |x| allowed.include?(x.sym) }
61
+ end
62
+ end
63
+
64
+ module RouteBuilder
65
+ extend ActiveSupport::Concern
66
+
67
+ DEFAULT_CRUD_ACTIONS = %i[index new create show edit update destroy]
68
+
69
+ included do
70
+ class_attribute :resources, default: {}
71
+ class_attribute :current_resource
72
+ end
73
+
74
+ class_methods do
75
+ def resource(model, only: DEFAULT_CRUD_ACTIONS, except: [], &block)
76
+ self.current_resource = RoutedResource.new(model, DEFAULT_CRUD_ACTIONS & (only - except))
77
+ yield if block_given?
78
+ resources[model] = current_resource
79
+ self.current_resource = nil
80
+ end
81
+
82
+ def action(sym, verb: :get, confirm: false, turbo_frame: nil, collection: false, show_in_datatable: true, show_in_form: true, no_route: false, controller: nil, action: nil)
83
+ raise 'Must be invoked in a resource block' unless current_resource.present?
84
+
85
+ controller ||= current_resource.model
86
+ current_resource.actions << ResourceAction.new(
87
+ sym, action: action, controller: controller, verb: verb, confirm: confirm, turbo_frame: turbo_frame, collection: collection,
88
+ show_in_datatable: show_in_datatable, show_in_form: show_in_form, no_route: no_route
89
+ )
90
+ end
91
+
92
+ def build_routes(mapper)
93
+ build_resource_routes(mapper)
94
+ end
95
+
96
+ def build_resource_routes(mapper)
97
+ resources.keys.each do |k|
98
+ r = resources[k]
99
+ mapper.resources r.model, only: r.crud_actions.map{ |ca| ca.action } do
100
+ mapper.member do
101
+ r.member_actions.each do |ma|
102
+ next if ma.no_route
103
+ if ma.confirm
104
+ mapper.get ma.action, action: "confirm_#{ma.action}"
105
+ mapper.post ma.action
106
+ else
107
+ mapper.send(ma.verb, ma.action)
108
+ end
109
+ end
110
+ end
111
+
112
+ mapper.collection do
113
+ r.collection_actions.each do |ba|
114
+ next if ba.no_route
115
+ if ba.confirm
116
+ mapper.get ba.action, action: "confirm_#{ba.action}"
117
+ mapper.post ba.action
118
+ else
119
+ mapper.send(ma.verb, ba.action)
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
@@ -16,5 +16,22 @@ module Olivander
16
16
  def user_image_path(user)
17
17
  "avatar#{SecureRandom.random_number(4)}.png"
18
18
  end
19
+
20
+ def authorized_resource_actions(resource, for_action: :show)
21
+ plural_name = resource.is_a?(Class) ? resource.table_name : resource.class.table_name
22
+ routed_resource = @context.route_builder.resources[plural_name.to_sym]
23
+ actions = resource.is_a?(Class) ?
24
+ (routed_resource.unpersisted_crud_actions | routed_resource.collection_actions) :
25
+ (resource.persisted? ? (routed_resource.persisted_crud_actions | routed_resource.member_actions): [])
26
+ actions.reject{ |a| a.sym == for_action }
27
+ end
28
+
29
+ def resource_form_actions(resource, for_action: :show)
30
+ [].tap do |output|
31
+ authorized_resource_actions(resource, for_action: for_action).select{ |x| x.show_in_form }.each do |a|
32
+ output << link_to(a.sym, {controller: a.controller, action: a.action}, method: a.verb, class: 'btn btn-primary', data: { turbo: true })
33
+ end
34
+ end.join('&nbsp;').html_safe
35
+ end
19
36
  end
20
37
  end
@@ -0,0 +1,17 @@
1
+ - read_only = action_name != 'edit'
2
+ = simple_form_for(@resource) do |f|
3
+ .card
4
+ .card-header
5
+ .card-tools
6
+ = resource_form_actions(@resource, for_action: action_name.to_sym)
7
+ .card-body
8
+ =f.error_notification
9
+ =f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present?
10
+ - @resource.auto_form_attributes.each do |a|
11
+ .row
12
+ .col-12
13
+ = f.input a, disabled: read_only
14
+ .card-footer.text-right
15
+ = link_to 'Cancel', @_effective_resource.action_path(:index), class: 'btn btn-secondary'
16
+ - unless read_only
17
+ = f.button :submit, class: 'btn btn-primary'
@@ -3,9 +3,5 @@
3
3
 
4
4
  - if @resource
5
5
  .row
6
- .col-8
7
- %h1= @page_title
8
- .col-4.text-right
9
- = render_resource_buttons(@resource, edit: false)
10
-
11
- = render_resource_form(@resource)
6
+ .col-12
7
+ = render_resource_form(@resource)
@@ -4,7 +4,9 @@
4
4
  .col-12
5
5
  .card
6
6
  .card-header
7
- %h1= @page_title
7
+ %h3.card-title= @page_title
8
+ .card-tools
9
+ = resource_form_actions(resource.klass, for_action: :index)
8
10
  .card-body
9
11
  - if @datatable
10
12
  = render_datatable(@datatable)
@@ -19,6 +21,5 @@
19
21
  %p effective_resources index view is not sure what to render.
20
22
  %p Define an @datatable, @#{resource.try(:plural_name) || 'a plural'}, or @#{resource.try(:name) || 'a singular'}.
21
23
  %p or include Effective::CrudController in your controller
22
- .card-footer
23
- = render_resource_buttons(resource.klass, (action ||= :index) => false)
24
+ -# .card-footer
24
25
 
@@ -2,10 +2,4 @@
2
2
  - @resource = instance_variable_get('@' + resource.name) if resource.name
3
3
 
4
4
  - if @resource
5
- .row
6
- .col-8
7
- %h1= @page_title
8
- .col-4.text-right
9
- = render_resource_buttons(@resource)
10
-
11
5
  = render_resource_form(@resource)
@@ -3,12 +3,6 @@
3
3
 
4
4
  - if @resource
5
5
  .row
6
- .col-8
7
- %h1= @page_title
8
- .col-4.text-right
9
- = render_resource_buttons(@resource, show: false)
6
+ .col-12
7
+ = render_resource_form(@resource)
10
8
 
11
- = render_resource_partial(@resource)
12
-
13
- .form-actions
14
- = link_to 'Continue', (resource.action_path(:index) || root_path), class: 'btn btn-primary'
@@ -0,0 +1,3 @@
1
+ = dropdown(variation: :dropleft, btn_class: btn_class) do
2
+ - authorized_resource_actions(resource, for_action: action_name).select{ |x| x.show_in_datatable }.each do |a|
3
+ = dropdown_link_to a.sym, { controller: a.controller, action: a.action, id: resource.id }
@@ -8,4 +8,4 @@
8
8
  = javascript_include_tag "https://www.gstatic.com/charts/loader.js"
9
9
  = stylesheet_link_tag "adminlte", "data-turbo-track": "reload"
10
10
  = javascript_include_tag "adminlte", "data-turbo-track": "reload"
11
- -# = javascript_importmap_tags
11
+ = javascript_importmap_tags
@@ -24,3 +24,38 @@
24
24
  %ul.nav.nav-pills.nav-sidebar.nav-compact.flex-column{"data-accordion" => "false", "data-widget" => "treeview", :role => "menu"}
25
25
  - @context.menu_items.each do |menu_item|
26
26
  = render Olivander::Components::MenuItemComponent.new(menu_item)
27
+
28
+
29
+ :javascript
30
+ $(document).ready(function(){
31
+ function getUrl() {
32
+ const reg = /\/new|\/[0-9]+[\/edit]*/,
33
+ url = "" + window.location;
34
+ return url.replace(reg, '');
35
+ }
36
+ const url = getUrl();
37
+
38
+ $('ul.nav-sidebar a').filter(function() {
39
+ return this.href == url;
40
+ }).addClass('active');
41
+
42
+ $('ul.nav-sidebar a').filter(function() {
43
+ return this.href == url;
44
+ }).parent().addClass('active');
45
+
46
+ $('ul.nav-treeview a').filter(function() {
47
+ return this.href == url;
48
+ }).parentsUntil(".sidebar-menu > .nav-treeview").addClass('menu-open');
49
+
50
+ $('ul.nav-treeview a').filter(function() {
51
+ return this.href == url;
52
+ }).addClass('active');
53
+
54
+ $('li.has-treeview a').filter(function() {
55
+ return this.href == url;
56
+ }).addClass('active');
57
+
58
+ $('ul.nav-treeview a').filter(function() {
59
+ return this.href == url;
60
+ }).parentsUntil(".sidebar-menu > .nav-treeview").children(0).addClass('active');
61
+ });
@@ -0,0 +1,176 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Uncomment this and change the path if necessary to include your own
4
+ # components.
5
+ # See https://github.com/heartcombo/simple_form#custom-components to know
6
+ # more about custom components.
7
+ # Dir[Rails.root.join('lib/components/**/*.rb')].each { |f| require f }
8
+ #
9
+ # Use this setup block to configure all options available in SimpleForm.
10
+ SimpleForm.setup do |config|
11
+ # Wrappers are used by the form builder to generate a
12
+ # complete input. You can remove any component from the
13
+ # wrapper, change the order or even add your own to the
14
+ # stack. The options given below are used to wrap the
15
+ # whole input.
16
+ config.wrappers :default, class: :input,
17
+ hint_class: :field_with_hint, error_class: :field_with_errors, valid_class: :field_without_errors do |b|
18
+ ## Extensions enabled by default
19
+ # Any of these extensions can be disabled for a
20
+ # given input by passing: `f.input EXTENSION_NAME => false`.
21
+ # You can make any of these extensions optional by
22
+ # renaming `b.use` to `b.optional`.
23
+
24
+ # Determines whether to use HTML5 (:email, :url, ...)
25
+ # and required attributes
26
+ b.use :html5
27
+
28
+ # Calculates placeholders automatically from I18n
29
+ # You can also pass a string as f.input placeholder: "Placeholder"
30
+ b.use :placeholder
31
+
32
+ ## Optional extensions
33
+ # They are disabled unless you pass `f.input EXTENSION_NAME => true`
34
+ # to the input. If so, they will retrieve the values from the model
35
+ # if any exists. If you want to enable any of those
36
+ # extensions by default, you can change `b.optional` to `b.use`.
37
+
38
+ # Calculates maxlength from length validations for string inputs
39
+ # and/or database column lengths
40
+ b.optional :maxlength
41
+
42
+ # Calculate minlength from length validations for string inputs
43
+ b.optional :minlength
44
+
45
+ # Calculates pattern from format validations for string inputs
46
+ b.optional :pattern
47
+
48
+ # Calculates min and max from length validations for numeric inputs
49
+ b.optional :min_max
50
+
51
+ # Calculates readonly automatically from readonly attributes
52
+ b.optional :readonly
53
+
54
+ ## Inputs
55
+ # b.use :input, class: 'input', error_class: 'is-invalid', valid_class: 'is-valid'
56
+ b.use :label_input
57
+ b.use :hint, wrap_with: { tag: :span, class: :hint }
58
+ b.use :error, wrap_with: { tag: :span, class: :error }
59
+
60
+ ## full_messages_for
61
+ # If you want to display the full error message for the attribute, you can
62
+ # use the component :full_error, like:
63
+ #
64
+ # b.use :full_error, wrap_with: { tag: :span, class: :error }
65
+ end
66
+
67
+ # The default wrapper to be used by the FormBuilder.
68
+ config.default_wrapper = :default
69
+
70
+ # Define the way to render check boxes / radio buttons with labels.
71
+ # Defaults to :nested for bootstrap config.
72
+ # inline: input + label
73
+ # nested: label > input
74
+ config.boolean_style = :nested
75
+
76
+ # Default class for buttons
77
+ config.button_class = 'btn'
78
+
79
+ # Method used to tidy up errors. Specify any Rails Array method.
80
+ # :first lists the first message for each field.
81
+ # Use :to_sentence to list all errors for each field.
82
+ # config.error_method = :first
83
+
84
+ # Default tag used for error notification helper.
85
+ config.error_notification_tag = :div
86
+
87
+ # CSS class to add for error notification helper.
88
+ config.error_notification_class = 'error_notification'
89
+
90
+ # Series of attempts to detect a default label method for collection.
91
+ # config.collection_label_methods = [ :to_label, :name, :title, :to_s ]
92
+
93
+ # Series of attempts to detect a default value method for collection.
94
+ # config.collection_value_methods = [ :id, :to_s ]
95
+
96
+ # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none.
97
+ # config.collection_wrapper_tag = nil
98
+
99
+ # You can define the class to use on all collection wrappers. Defaulting to none.
100
+ # config.collection_wrapper_class = nil
101
+
102
+ # You can wrap each item in a collection of radio/check boxes with a tag,
103
+ # defaulting to :span.
104
+ # config.item_wrapper_tag = :span
105
+
106
+ # You can define a class to use in all item wrappers. Defaulting to none.
107
+ # config.item_wrapper_class = nil
108
+
109
+ # How the label text should be generated altogether with the required text.
110
+ # config.label_text = lambda { |label, required, explicit_label| "#{required} #{label}" }
111
+
112
+ # You can define the class to use on all labels. Default is nil.
113
+ # config.label_class = nil
114
+
115
+ # You can define the default class to be used on forms. Can be overriden
116
+ # with `html: { :class }`. Defaulting to none.
117
+ # config.default_form_class = nil
118
+
119
+ # You can define which elements should obtain additional classes
120
+ # config.generate_additional_classes_for = [:wrapper, :label, :input]
121
+
122
+ # Whether attributes are required by default (or not). Default is true.
123
+ # config.required_by_default = true
124
+
125
+ # Tell browsers whether to use the native HTML5 validations (novalidate form option).
126
+ # These validations are enabled in SimpleForm's internal config but disabled by default
127
+ # in this configuration, which is recommended due to some quirks from different browsers.
128
+ # To stop SimpleForm from generating the novalidate option, enabling the HTML5 validations,
129
+ # change this configuration to true.
130
+ config.browser_validations = false
131
+
132
+ # Custom mappings for input types. This should be a hash containing a regexp
133
+ # to match as key, and the input type that will be used when the field name
134
+ # matches the regexp as value.
135
+ # config.input_mappings = { /count/ => :integer }
136
+
137
+ # Custom wrappers for input types. This should be a hash containing an input
138
+ # type as key and the wrapper that will be used for all inputs with specified type.
139
+ # config.wrapper_mappings = { string: :prepend }
140
+
141
+ # Namespaces where SimpleForm should look for custom input classes that
142
+ # override default inputs.
143
+ # config.custom_inputs_namespaces << "CustomInputs"
144
+
145
+ # Default priority for time_zone inputs.
146
+ # config.time_zone_priority = nil
147
+
148
+ # Default priority for country inputs.
149
+ # config.country_priority = nil
150
+
151
+ # When false, do not use translations for labels.
152
+ # config.translate_labels = true
153
+
154
+ # Automatically discover new inputs in Rails' autoload path.
155
+ # config.inputs_discovery = true
156
+
157
+ # Cache SimpleForm inputs discovery
158
+ # config.cache_discovery = !Rails.env.development?
159
+
160
+ # Default class for inputs
161
+ # config.input_class = nil
162
+
163
+ # Define the default class of the input wrapper of the boolean input.
164
+ config.boolean_label_class = 'checkbox'
165
+
166
+ # Defines if the default input wrapper class should be included in radio
167
+ # collection wrappers.
168
+ # config.include_default_input_wrapper_class = true
169
+
170
+ # Defines which i18n scope will be used in Simple Form.
171
+ # config.i18n_scope = 'simple_form'
172
+
173
+ # Defines validation classes to the input_field. By default it's nil.
174
+ # config.input_field_valid_class = 'is-valid'
175
+ # config.input_field_error_class = 'is-invalid'
176
+ end
@@ -0,0 +1,31 @@
1
+ en:
2
+ simple_form:
3
+ "yes": 'Yes'
4
+ "no": 'No'
5
+ required:
6
+ text: 'required'
7
+ mark: '*'
8
+ # You can uncomment the line below if you need to overwrite the whole required html.
9
+ # When using html, text and mark won't be used.
10
+ # html: '<abbr title="required">*</abbr>'
11
+ error_notification:
12
+ default_message: "Please review the problems below:"
13
+ # Examples
14
+ # labels:
15
+ # defaults:
16
+ # password: 'Password'
17
+ # user:
18
+ # new:
19
+ # email: 'E-mail to sign in.'
20
+ # edit:
21
+ # email: 'E-mail.'
22
+ # hints:
23
+ # defaults:
24
+ # username: 'User name to sign in.'
25
+ # password: 'No special characters, please.'
26
+ # include_blanks:
27
+ # defaults:
28
+ # age: 'Rather not say'
29
+ # prompts:
30
+ # defaults:
31
+ # age: 'Select your age'
@@ -3,4 +3,5 @@ require 'effective_datatables'
3
3
  require 'haml-rails'
4
4
  require 'chartkick'
5
5
  require 'view_component'
6
+ require 'simple_form'
6
7
  require 'olivander'
@@ -1,6 +1,6 @@
1
1
  module Olivander
2
2
  class ApplicationContext
3
- attr_accessor :name, :logo, :company, :menu_items
3
+ attr_accessor :name, :logo, :company, :menu_items, :route_builder
4
4
 
5
5
  def self.default
6
6
  ctx = ApplicationContext.new
@@ -1,3 +1,3 @@
1
1
  module Olivander
2
- VERSION = "0.1.2.1"
2
+ VERSION = "0.1.2.3"
3
3
  end
@@ -0,0 +1,8 @@
1
+ = simple_form_for(@resource) do |f|
2
+ =f.error_notification}
3
+ =f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present?}
4
+ .form-inputs
5
+ - attributes.each do |attribute|
6
+ = f.send(attribute.reference? ? :association : :input, attribute.name)
7
+ .form-actions
8
+ = f.button :submit
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: five-two-nw-olivander
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2.1
4
+ version: 0.1.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Dennis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-03 00:00:00.000000000 Z
11
+ date: 2023-07-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chartkick
@@ -171,21 +171,21 @@ files:
171
171
  - app/assets/stylesheets/olivander/application.css
172
172
  - app/components/olivander/components/menu_item_component.html.haml
173
173
  - app/components/olivander/components/menu_item_component.rb
174
+ - app/controllers/concerns/olivander/resources/auto_form_attributes.rb
175
+ - app/controllers/concerns/olivander/resources/route_builder.rb
174
176
  - app/controllers/olivander/application_controller.rb
175
- - app/controllers/olivander/resources/crud_chain.rb
176
- - app/controllers/olivander/resources/crud_controller.rb
177
- - app/controllers/olivander/resources/default_crud_chain.rb
178
- - app/controllers/olivander/test_controller.rb
179
177
  - app/datatables/olivander/datatable.rb
180
178
  - app/datatables/test_datatable.rb
181
179
  - app/helpers/olivander/application_helper.rb
182
180
  - app/jobs/olivander/application_job.rb
183
181
  - app/mailers/olivander/application_mailer.rb
184
182
  - app/models/olivander/application_record.rb
183
+ - app/views/application/_form.html.haml
185
184
  - app/views/application/edit.html.haml
186
185
  - app/views/application/index.html.haml
187
186
  - app/views/application/new.html.haml
188
187
  - app/views/application/show.html.haml
188
+ - app/views/effective/resource/_actions_dropleft.html.haml
189
189
  - app/views/layouts/olivander/adminlte/_content.html.haml
190
190
  - app/views/layouts/olivander/adminlte/_content_kanban.html.haml
191
191
  - app/views/layouts/olivander/adminlte/_control_sidebar.html.haml
@@ -199,6 +199,8 @@ files:
199
199
  - app/views/layouts/olivander/adminlte/main.html.haml
200
200
  - app/views/layouts/olivander/application.html.haml
201
201
  - config/initializers/effective_datatables.rb.old
202
+ - config/initializers/simple_form.rb
203
+ - config/locales/simple_form.en.yml
202
204
  - config/routes.rb
203
205
  - lib/five-two-nw-olivander.rb
204
206
  - lib/olivander.rb
@@ -208,6 +210,7 @@ files:
208
210
  - lib/olivander/menus/menu_item.rb
209
211
  - lib/olivander/version.rb
210
212
  - lib/tasks/olivander_tasks.rake
213
+ - lib/templates/erb/scaffold/_form.html.haml
211
214
  homepage: https://rubygems.org/gems/olivander
212
215
  licenses:
213
216
  - MIT
@@ -1,119 +0,0 @@
1
- module Olivander
2
- module Resources
3
- class CrudChain
4
- attr_accessor :controller
5
-
6
- def initialize(controller)
7
- @controller = controller
8
- end
9
-
10
- def links
11
- @links ||= {
12
- authorize_action: nil,
13
- before_load: nil, load_resource: nil, after_load: nil,
14
- authorize_resource: nil,
15
- before_assign: nil, assign: nil, after_assign: nil,
16
- update_if: nil,
17
- before_update: nil, update: nil, after_update: nil,
18
- update_success: nil, update_failure: nil,
19
- render_success: nil, render_failure: nil
20
- }
21
- end
22
-
23
- def on(chain_link, &block)
24
- raise "Invalid Link: #{chain_link}" unless links.keys.include?(chain_link)
25
-
26
- links[chain_link] = block
27
- self
28
- end
29
-
30
- def skip_load
31
- clear_keys(%i[before_load load_resource after_load])
32
- self
33
- end
34
-
35
- def skip_assign
36
- clear_keys(%i[before_assign assign after_assign])
37
- self
38
- end
39
-
40
- def skip_update
41
- update_if { false }
42
- self
43
- end
44
-
45
- def skip_render
46
- clear_keys(%i[render_success render_failure])
47
- self
48
- end
49
-
50
- def execute
51
- execute_link_keys(%i[authorize_action before_load load_resource after_load authorize_resource before_assign assign after_assign])
52
- success = perform_update
53
- # we may not do any update - in which case we assume success
54
- success = true if success.nil?
55
- execute_link_key(success ? :render_success : :render_failure)
56
- success
57
- end
58
-
59
- # def self.test
60
- # CrudChain.new('string')
61
- # .before_load { puts "we did a before load from within this action: #{self}" }
62
- # .before_update { puts "we are doing a before_update on a controller named: #{self.class.name}" }
63
- # .execute
64
- # end
65
-
66
- def clear_keys(keys)
67
- keys.each { |k| clear_key(k) }
68
- end
69
-
70
- def clear_keys_except(keys)
71
- (links.keys - keys).each { |k| clear_key(k) }
72
- end
73
-
74
- def clear_key(key)
75
- links[key] = nil
76
- end
77
-
78
- private
79
-
80
- def perform_update
81
- perform_update = execute_link_key(:update_if)
82
- perform_update = true if perform_update.nil?
83
- return false unless perform_update
84
-
85
- execute_link_key(:before_update)
86
- success = execute_link_key(:update)
87
- execute_link_key(:after_update)
88
- execute_link_key(success ? :update_success : :update_failure)
89
- success
90
- end
91
-
92
- def execute_link_keys(keys)
93
- keys.each do |k|
94
- execute_link_key(k)
95
- end
96
- end
97
-
98
- def execute_link_key(key)
99
- block = links[key]
100
- return if block.nil?
101
-
102
- @controller.instance_exec(&block)
103
- end
104
-
105
- def respond_to_missing?(method_name, _include_private = false)
106
- links.keys.include?(method_name.to_sym)
107
- end
108
-
109
- # syntax sugar to allow direct assignment of a chain link
110
- def method_missing(m, *args, &block)
111
- if respond_to_missing?(m)
112
- send(:on, m, &block)
113
- else
114
- super
115
- end
116
- end
117
- end
118
- end
119
- end
@@ -1,55 +0,0 @@
1
- module Olivander
2
- module Resources
3
- module CrudController
4
- def index
5
- execute_crud_chain(crud_action: :index)
6
- end
7
-
8
- def new
9
- execute_crud_chain(crud_action: :new)
10
- end
11
-
12
- def create
13
- execute_crud_chain(crud_action: :create)
14
- end
15
-
16
- def show
17
- execute_crud_chain(crud_action: :show)
18
- end
19
-
20
- def edit
21
- execute_crud_chain(crud_action: :edit)
22
- end
23
-
24
- def update
25
- execute_crud_chain(crud_action: :update)
26
- end
27
-
28
- def destroy
29
- execute_crud_chain(crud_action: :destroy)
30
- end
31
-
32
- def execute_crud_chain(crud_action: action_name, only: [], skip: [], &block)
33
- chain = default_crud_chain(crud_action)
34
- chain.clear_keys_except(only) if only.size.positive?
35
- chain.clear_keys(skip) if skip.size.positive?
36
- yield(chain) if block_given?
37
- chain.execute
38
- end
39
-
40
- def default_crud_chain(crud_action = '')
41
- chain = Olivander::Resources::CrudChain.new(self)
42
- chain.links.keys.each do |k|
43
- method_name = "crud_chain_#{crud_action}_#{k}"
44
- method_name = "crud_chain_#{k}" unless respond_to?(method_name)
45
- next unless respond_to?(method_name)
46
-
47
- chain.on(k) do
48
- send(method_name)
49
- end
50
- end
51
- chain
52
- end
53
- end
54
- end
55
- end
@@ -1,48 +0,0 @@
1
- module Olivander
2
- module Resources
3
- module DefaultCrudChain
4
- def crud_chain_index_authorize_action
5
- puts 'default crud chain: index_authorize_action'
6
- end
7
-
8
- def crud_chain_index_load_resource
9
- puts 'default crud chain: index_load_resource'
10
- end
11
-
12
- def crud_chain_load_resource
13
- puts 'default crud chain: load_resource'
14
- end
15
-
16
- def crud_chain_authorize_resource
17
- raise 'Unauthorized' unless true
18
- puts 'default crud chain: authorize_resource'
19
- end
20
-
21
- def crud_chain_assign
22
- puts 'default crud chain: assign'
23
- end
24
-
25
- def crud_chain_update_if
26
- puts 'default crud chain: update_if'
27
- return true if %w[create update destroy].include?(action_name)
28
- return false if %w[index new show edit].include?(action_name)
29
- return false if request.method == 'GET'
30
-
31
- true
32
- end
33
-
34
- def crud_chain_update
35
- puts 'default crud chain: update'
36
- true
37
- end
38
-
39
- def crud_chain_render_success
40
- puts 'default crud chain: render_success'
41
- end
42
-
43
- def crud_chain_render_failure
44
- puts 'default crud chain: render_failure'
45
- end
46
- end
47
- end
48
- end
@@ -1,35 +0,0 @@
1
- module Olivander
2
- class TestController < ApplicationController
3
- include Olivander::Resources::CrudController
4
- include Olivander::Resources::DefaultCrudChain
5
-
6
- def index
7
- execute_crud_chain(crud_action: :index) do |c|
8
- c.authorize_resource { puts 'block: authorize_resource'; true }
9
- .update { puts 'block: update'; true }
10
- .before_assign { puts 'block: before assign' }
11
- .after_assign { puts 'block: after assign' }
12
- end
13
- end
14
-
15
- # def crud_chain_update
16
- # puts 'controller: update'
17
- # end
18
-
19
- # def crud_chain_index_update
20
- # puts 'controller: index_update'
21
- # end
22
-
23
- # def crud_chain_before_load
24
- # puts 'controller: before_load'
25
- # end
26
-
27
- # def crud_chain_after_update
28
- # puts 'controller: after_update'
29
- # end
30
-
31
- # def crud_chain_index_after_update
32
- # puts 'controller: index_after_update'
33
- # end
34
- end
35
- end