five-two-nw-olivander 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 804923f3e2c0757a3477f96abbeb27d83230e0cb57be24c0943ed72ac270ca73
4
- data.tar.gz: c5117164723c492667ac149891e2ef2619688074a63e8a387b2c7701a2e85b4a
3
+ metadata.gz: dc6de8b38d444eb9b91d348d755b9f98d49a11496cb6a1a94af7ec8f20e4623a
4
+ data.tar.gz: ab9f6ff9469281da90f5dfcbad98b0827046506aa869cb8ce0bee5e480521143
5
5
  SHA512:
6
- metadata.gz: e8c3e1a18f2cc7d51605a5522445684e2ddbb39acb8767816983106d8d7dfce85a8e4321034d5d4605021790d5719288c361f67f359964ca53db98277863568e
7
- data.tar.gz: 3c14a579d133cea6d03239af43390de369d7d023a590c17e5e29ebbc213126e8a6be8bfe82daa3d26cbce1947501d1be6a6217417693c1f5b67cfaadc3e416cf
6
+ metadata.gz: 8b4d04a662d71f34f11078d7a1b45a6c7b21b6179ac49b848c9e506d1236b63322c39e13b31b9b928976f0be724e5f60a8bb60a707a93bcd9fd26882e48a2ee1
7
+ data.tar.gz: 5cb41955375fddc24bce230f16d6c383b8e3848f967be90343f009140c7a243ec416d0cbb329ac4997a83c5c94a5e7b55c788bbc04c29a26f0509c119314db68
@@ -18,6 +18,7 @@
18
18
  *= require 'adminlte/plugins/daterangepicker/daterangepicker'
19
19
  *= require 'adminlte/plugins/summernote/summernote-bs4.min'
20
20
  *= require 'adminlte/plugins/fontawesome-free/css/all.min'
21
+ *= require effective_datatables
21
22
  *= require_tree .
22
23
  *= require_self
23
24
  */
@@ -0,0 +1,19 @@
1
+ - if menu_item.visible
2
+ - if menu_item.href
3
+ %li.nav-item
4
+ %a.nav-link{href: menu_item.href}
5
+ - if menu_item.icon_class
6
+ %i.nav-icon{class: menu_item.icon_class}
7
+ %p
8
+ = menu_item.text
9
+ - if menu_item.submenu_items.size.positive?
10
+ %i.fas.fa-angle-left.right
11
+ - menu_item.badges.each do |badge|
12
+ %span.badge.right{ class: "badge-#{badge.badge_class}" }
13
+ = badge.text
14
+ - if menu_item.submenu_items.size.positive?
15
+ %ul.nav.nav-treeview
16
+ - menu_item.submenu_items.each do |item|
17
+ = render Olivander::Components::MenuItemComponent.new(item)
18
+ - else
19
+ %li.nav-header= menu_item.text.upcase
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Olivander::Components::MenuItemComponent < ViewComponent::Base
4
+ attr_reader :menu_item
5
+
6
+ def initialize(menu_item)
7
+ super
8
+ @menu_item = menu_item
9
+ end
10
+ end
@@ -0,0 +1,119 @@
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
@@ -0,0 +1,55 @@
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
@@ -0,0 +1,48 @@
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
@@ -0,0 +1,35 @@
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
@@ -1,7 +1,16 @@
1
1
  module Olivander
2
2
  module ApplicationHelper
3
3
  def page_title
4
- 'foo'
4
+ return @page_title if @page_title
5
+
6
+ cf = content_for(:title)
7
+ return cf unless cf.blank?
8
+
9
+ controller_key = controller.class.name.underscore
10
+ key = "page_titles.#{controller_key}.#{action_name}"
11
+ return I18n.t(key) if I18n.exists?(key)
12
+
13
+ "#{controller_name}: #{action_name}".titleize
5
14
  end
6
15
 
7
16
  def user_image_path(user)
@@ -2,7 +2,11 @@
2
2
  %section.content-header
3
3
  .container-fluid
4
4
  .row.mb-2
5
- %h1= page_title
5
+ .col-sm-6
6
+ %h1= page_title
7
+ .col-sm-6
8
+ %ol.breadcrumb.float-sm-right
9
+ = content_for(:breadcrumb)
6
10
  %section.content
7
11
  .container-fluid
8
12
  = content
@@ -2,8 +2,10 @@
2
2
  %strong
3
3
  Copyright © #{Date.current.year}
4
4
  = succeed "." do
5
- %a{:href => "https://adminlte.io"} AdminLTE.io
5
+ = link_to @context.company.name, @context.company.url
6
6
  All rights reserved.
7
7
  .float-right.d-none.d-sm-inline-block
8
- %b Version
9
- 3.2.0
8
+ .text-small
9
+ Powered by
10
+ = link_to '5&2 Northwest', 'https://www.5and2northwest.com'
11
+ %b Olivander v#{Olivander::VERSION}
@@ -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
@@ -5,10 +5,9 @@
5
5
  %li.nav-item
6
6
  %a.nav-link{"data-widget" => "pushmenu", :href => "#", :role => "button"}
7
7
  %i.fas.fa-bars
8
- %li.nav-item.d-none.d-sm-inline-block
9
- %a.nav-link{:href => "/foo"} Foo
10
- %li.nav-item.d-none.d-sm-inline-block
11
- %a.nav-link{:href => "/system"} System
8
+ - @context.visible_modules.each do |menu_item|
9
+ %li.nav-item.d-none.d-sm-inline-block
10
+ = link_to menu_item.text, menu_item.href, class: 'nav-link'
12
11
  / Right navbar links
13
12
  %ul.navbar-nav.ml-auto
14
13
  / Navbar Search
@@ -2,8 +2,8 @@
2
2
  %aside.main-sidebar.sidebar-dark-primary.elevation-4{ data: { controller: 'left-nav' }}
3
3
  / Brand Logo
4
4
  %a.brand-link.bg-info{:href => "/"}
5
- %img.brand-image.img-circle.elevation-3{:alt => @context.logo_alt, :src => 'image_path("logo.png")', :style => "opacity: .8"}/
6
- %span.brand-text.font-weight-light= @context.page_title
5
+ %img.brand-image.img-circle.elevation-3{:alt => @context.logo.alt, :src => @context.logo.url, :style => "opacity: .8"}/
6
+ %span.brand-text.font-weight-light= @context.name
7
7
  / Sidebar
8
8
  .sidebar
9
9
  / Sidebar user panel (optional)
@@ -22,3 +22,5 @@
22
22
  / Sidebar Menu
23
23
  %nav.mt-2
24
24
  %ul.nav.nav-pills.nav-sidebar.nav-compact.flex-column{"data-accordion" => "false", "data-widget" => "treeview", :role => "menu"}
25
+ - @context.menu_items.each do |menu_item|
26
+ = render Olivander::Components::MenuItemComponent.new(menu_item)
@@ -1,6 +1,6 @@
1
1
  !!!
2
2
  %html
3
- - @context = OpenStruct.new({ page_title: 'title', logo_alt: 'logo alt' })
3
+ - @context ||= Olivander::ApplicationContext.default
4
4
  = render partial: 'layouts/olivander/adminlte/head'
5
5
  - sidebar_collapse = cookies['lte.pushmenu.collapsed'] == 'true' ? 'sidebar-collapse' : ''
6
6
  %body.hold-transition.sidebar-mini.layout-fixed{ class: sidebar_collapse }
@@ -15,3 +15,4 @@
15
15
  = render partial: 'layouts/olivander/adminlte/flashes'
16
16
  = render partial: 'layouts/olivander/adminlte/footer'
17
17
  = render partial: 'layouts/olivander/adminlte/control_sidebar'
18
+ = content_for :javascript
@@ -2,4 +2,5 @@ require 'effective_resources'
2
2
  require 'effective_datatables'
3
3
  require 'haml-rails'
4
4
  require 'chartkick'
5
+ require 'view_component'
5
6
  require 'olivander'
@@ -0,0 +1,53 @@
1
+ module Olivander
2
+ class ApplicationContext
3
+ attr_accessor :name, :logo, :company, :menu_items
4
+
5
+ def self.default
6
+ ctx = ApplicationContext.new
7
+ ctx.company.name = 'Company Name'
8
+ ctx
9
+ end
10
+
11
+ def initialize(name: 'Application Name', logo: Logo.new, company: Company.new, menu_items: [])
12
+ self.name = name
13
+ self.logo = logo
14
+ self.company = company
15
+ self.menu_items = menu_items
16
+ end
17
+
18
+ def visible_modules
19
+ [].tap do |arr|
20
+ menu_items.each do |menu_item|
21
+ arr << visible_modules_for(menu_item)
22
+ end
23
+ end.flatten
24
+ end
25
+
26
+ def visible_modules_for(menu_item)
27
+ [].tap do |arr|
28
+ arr << menu_item if menu_item.module? && menu_item.visible
29
+ menu_item.submenu_items.each do |sub|
30
+ arr << visible_modules_for(sub)
31
+ end
32
+ end
33
+ end
34
+
35
+ class Logo
36
+ attr_accessor :url, :alt
37
+
38
+ def initialize(url: nil, alt: 'Logo')
39
+ self.url = url
40
+ self.alt = alt
41
+ end
42
+ end
43
+
44
+ class Company
45
+ attr_accessor :name, :url
46
+
47
+ def initialize(name: nil, url: nil)
48
+ self.url = url
49
+ self.name = name
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,106 @@
1
+ module Olivander
2
+ module Menus
3
+ class MenuItem
4
+ attr_reader :href
5
+
6
+ def initialize(key, href = nil, icon = nil, is_module: false)
7
+ @key = key
8
+ @href = href
9
+ @icon = icon
10
+ @submenu_items_blocks = []
11
+ @badges_blocks = []
12
+ @module = is_module
13
+ end
14
+
15
+ def module?
16
+ @module
17
+ end
18
+
19
+ def text
20
+ resolved_key(@key, "menus.#{@key}.text")
21
+ end
22
+
23
+ def icon_class
24
+ @icon || resolved_key(@key, "menus.#{@key}.icon", 'menus.default_icon')
25
+ end
26
+
27
+ def visible
28
+ @visible ||= evaluate_conditions_block
29
+ end
30
+
31
+ def with_condition(&block)
32
+ @conditions_block = block
33
+ self
34
+ end
35
+
36
+ def with_submenu_items(&block)
37
+ @submenu_items_blocks << block
38
+ self
39
+ end
40
+
41
+ def submenu_items
42
+ @submenu_items ||= [].tap do |arr|
43
+ if visible
44
+ @submenu_items_blocks.each do |block|
45
+ Rails.logger.debug "invoking submenu item block on #{@key}"
46
+ block.call.each { |item| arr << item if item.visible }
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ def with_badges(&block)
53
+ @badges_blocks << block
54
+ self
55
+ end
56
+
57
+ def badges
58
+ @badges ||= [].tap do |arr|
59
+ if visible
60
+ @badges_blocks.each do |block|
61
+ Rails.logger.debug "invoking badge block on #{@key}"
62
+ block.call.each { |badge| arr << badge }
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ private
69
+
70
+ def evaluate_conditions_block
71
+ if @conditions_block
72
+ Rails.logger.debug "invoking condition on #{@key}"
73
+ @conditions_block.call
74
+ else
75
+ true
76
+ end
77
+ end
78
+
79
+ def resolved_key(raw, key = nil, fallback = nil)
80
+ return nil unless raw
81
+
82
+ if key && I18n.exists?(key)
83
+ I18n.t(key)
84
+ elsif fallback && I18n.exists?(fallback)
85
+ I18n.t(fallback)
86
+ else
87
+ raw.titleize
88
+ end
89
+ end
90
+ end
91
+
92
+ class Badge
93
+ attr_accessor :text, :badge_class
94
+
95
+ def initialize(text = nil, badge_class = nil)
96
+ @text = text
97
+ @badge_class = badge_class
98
+ end
99
+
100
+ def with_proc
101
+ yield(self)
102
+ self
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1 @@
1
+ require 'olivander/menus/menu_item'
@@ -1,3 +1,3 @@
1
1
  module Olivander
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
data/lib/olivander.rb CHANGED
@@ -1,5 +1,7 @@
1
- require "olivander/version"
2
- require "olivander/engine"
1
+ require 'olivander/version'
2
+ require 'olivander/engine'
3
+ require 'olivander/application_context'
4
+ require 'olivander/menus'
3
5
 
4
6
  module Olivander
5
7
  # Your code goes here...
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.1
4
+ version: 0.1.2
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-03-09 00:00:00.000000000 Z
11
+ date: 2023-07-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chartkick
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: 3.2.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: view_component
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  description: Description of Olivander.
84
98
  email:
85
99
  - devops@5and2northwest.com
@@ -141,7 +155,13 @@ files:
141
155
  - app/assets/stylesheets/adminlte.css
142
156
  - app/assets/stylesheets/fa-fix.scss
143
157
  - app/assets/stylesheets/olivander/application.css
158
+ - app/components/olivander/components/menu_item_component.html.haml
159
+ - app/components/olivander/components/menu_item_component.rb
144
160
  - app/controllers/olivander/application_controller.rb
161
+ - app/controllers/olivander/resources/crud_chain.rb
162
+ - app/controllers/olivander/resources/crud_controller.rb
163
+ - app/controllers/olivander/resources/default_crud_chain.rb
164
+ - app/controllers/olivander/test_controller.rb
145
165
  - app/datatables/test_datatable.rb
146
166
  - app/helpers/olivander/application_helper.rb
147
167
  - app/jobs/olivander/application_job.rb
@@ -159,11 +179,14 @@ files:
159
179
  - app/views/layouts/olivander/adminlte/login.html.haml
160
180
  - app/views/layouts/olivander/adminlte/main.html.haml
161
181
  - app/views/layouts/olivander/application.html.haml
162
- - config/initializers/effective_datatables.rb
182
+ - config/initializers/effective_datatables.rb.old
163
183
  - config/routes.rb
164
184
  - lib/five-two-nw-olivander.rb
165
185
  - lib/olivander.rb
186
+ - lib/olivander/application_context.rb
166
187
  - lib/olivander/engine.rb
188
+ - lib/olivander/menus.rb
189
+ - lib/olivander/menus/menu_item.rb
167
190
  - lib/olivander/version.rb
168
191
  - lib/tasks/olivander_tasks.rake
169
192
  homepage: https://rubygems.org/gems/olivander