plok 0.2.12 → 1.0.0

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: 4dd177c85c560cc54c99970b9f7bba447ac49b407edd4f92c3bf19eba003a4d6
4
- data.tar.gz: 1567126c937dc4cdaa090c3617a091f63980da34d09452250d7d76518c48d80d
3
+ metadata.gz: 8824645af9b5b16c2e3540eb298a43be8df6b0e1539d2274bf833d62a4ee2c9b
4
+ data.tar.gz: 53298ba35f0393728429121aeb7ace1ebafca3b744bb3f47e584478eea6ae6e3
5
5
  SHA512:
6
- metadata.gz: 8d6f225251275ffe58c79f2b812647de21fd5b7522da704901bb23b30906f5137d7a4c5160ab4ef97be1ce4669c1b3258f9366279746171599ae17148d732f0d
7
- data.tar.gz: e0043cc3f281b3e658b653823b0e338c78221b7f4797d8e51e3485206de84bdd02ed6b002b0e490f5609bc8e2322369ca5cdfbfcc30922ea990722a484d44cca
6
+ metadata.gz: 54f0aec7e6af22ec5f1e9d988880ebf03e110a5c8f619169c1ad1a5a82188c11f9da0b28a71189cd9aac21824921223e035cc718d0c2de7e661812cc715d7576
7
+ data.tar.gz: 4a274b94c88692dadd40061cd90778a7c0c2d7c5d931ef0c123e2b1a6e13ead58331f60e26d3c8c14fdeb709a414b7d93d44be072e3b4b85b74710c8a2f959cd
@@ -0,0 +1,66 @@
1
+ var sidebar = {
2
+ init: () => {
3
+ sidebar.bind_mouse_events();
4
+ $('#hamburger').on('click', sidebar.toggle_hamburger_click_listener)
5
+ $(document).on('click', sidebar.document_click_listener)
6
+ },
7
+
8
+ bind_mouse_events: () => {
9
+ $('.wrapper.compact ul li.top-level')
10
+ .on('mouseenter', sidebar.list_item_mouseenter_listener)
11
+ .on('mouseleave', sidebar.list_item_mouseleave_listener)
12
+ },
13
+
14
+ close_all_submenus: () => {
15
+ $('[id^="nav-"]').each((_i, item) => { $(item).removeClass('show') })
16
+ $('a.top-level-anchor').each((_i, item) => { $(item).removeClass('bg-secondary') })
17
+ },
18
+
19
+ document_click_listener: (e) => {
20
+ if($('.compact:visible').length == 0) return
21
+ if($(e.target).closest('.sidebar-menu').length === 0)
22
+ sidebar.close_all_submenus();
23
+ },
24
+
25
+ list_item_mouseenter_listener: (e) => {
26
+ sidebar.list_item_mouseleave_listener(e)
27
+
28
+ let anchor = $(e.target)
29
+ if(!anchor.hasClass('top-level-anchor')) return
30
+ anchor.addClass('bg-secondary')
31
+ $(anchor.attr('href')).addClass('show')
32
+ },
33
+
34
+ list_item_mouseleave_listener: (e) => {
35
+ let anchor = $(e.target)
36
+ if(!anchor.hasClass('top-level-anchor')) return
37
+ sidebar.close_all_submenus();
38
+ },
39
+
40
+ toggle_hamburger_click_listener: e => {
41
+ e.preventDefault()
42
+ $('.wrapper').toggleClass('compact')
43
+
44
+ $('[id^="nav-"]').each((index, item) => {
45
+ if($('.wrapper').hasClass('compact')) {
46
+ $(item).removeClass('show')
47
+ }
48
+ })
49
+
50
+ if($('.wrapper').hasClass('compact')) {
51
+ sidebar.bind_mouse_events()
52
+ $('.sidebar-menu').removeClass('overflow-auto')
53
+ } else {
54
+ sidebar.unbind_mouse_events()
55
+ $('.sidebar-menu').addClass('overflow-auto')
56
+ }
57
+ },
58
+
59
+ unbind_mouse_events: () => {
60
+ $('.wrapper ul li.top-level')
61
+ .off('mouseenter')
62
+ .off('mouseleave')
63
+ }
64
+ }
65
+
66
+ $(() => { sidebar.init() })
@@ -0,0 +1,86 @@
1
+ .sidebar-menu {
2
+ bottom: 0;
3
+ position: fixed;
4
+ top: 0;
5
+ width: var(--sidebar-width);
6
+ transition: .5s;
7
+ z-index: 10;
8
+
9
+ a.logo {
10
+ display: block;
11
+ letter-spacing: 0.1em;
12
+ line-height: 45px;
13
+ text-decoration: none;
14
+ text-transform: uppercase;
15
+ }
16
+
17
+ a.home-icon {
18
+ display: none !important;
19
+ }
20
+
21
+ ul {
22
+ list-style-type: none;
23
+ padding-left: 0;
24
+
25
+ li {
26
+ cursor: pointer;
27
+
28
+ a {
29
+ color: #fff; // $color-contrast-light from the Bootstrap gem.
30
+ display: block;
31
+ font-size: 1rem;
32
+ padding: 10px;
33
+ padding-left: var(--sidebar-menu-item-left-margin);
34
+ text-decoration: none !important;
35
+
36
+ &:hover {
37
+ background-color: #6c757d; // $secondary from the Bootstrap gem.
38
+ }
39
+ }
40
+
41
+ &.top-level {
42
+ letter-spacing: .05em;
43
+ position: relative;
44
+
45
+ .fa {
46
+ font-size: 14px;
47
+ width: var(--sidebar-icon-width);
48
+ }
49
+
50
+ .text {
51
+ cursor: default;
52
+ font-size: 0.8rem;
53
+ padding: 16px 0 12px 0;
54
+ pointer-events: none;
55
+ text-transform: uppercase;
56
+ }
57
+
58
+ div[id^=nav-] {
59
+ h4 {
60
+ display: none;
61
+ }
62
+
63
+ ul li {
64
+ position: relative;
65
+
66
+ &::before {
67
+ content: '\25A1';
68
+ font-size: 0.4rem;
69
+ left: calc(var(--sidebar-menu-item-left-margin) + 15px);
70
+ position: absolute;
71
+ top: 15px;
72
+ }
73
+
74
+ a {
75
+ font-size: 0.8rem;
76
+ padding-left: calc(var(--sidebar-menu-item-left-margin) + var(--sidebar-icon-width) + 10px);
77
+ text-transform: uppercase;
78
+ }
79
+ }
80
+ }
81
+
82
+ }
83
+ }
84
+ }
85
+
86
+ }
@@ -0,0 +1,66 @@
1
+ .wrapper.compact {
2
+ .content {
3
+ margin-left: var(--sidebar-compact-width);
4
+
5
+ @include media-breakpoint-down(md) {
6
+ margin-left: 0;
7
+ }
8
+ }
9
+
10
+ .sidebar-menu {
11
+ width: var(--sidebar-compact-width);
12
+
13
+ @include media-breakpoint-down(md) {
14
+ width: 0;
15
+ }
16
+
17
+ a.logo {
18
+ display: none !important;
19
+ }
20
+
21
+ a.home-icon {
22
+ display: block !important;
23
+ }
24
+
25
+ ul li.top-level {
26
+ > a { // The icons in the compact view.
27
+ padding: 10px 0;
28
+ text-align: center;
29
+ }
30
+
31
+ h4 {
32
+ cursor: default;
33
+ display: inline-block;
34
+ font-size: .9rem;
35
+ padding: 13px 0 0 5px;
36
+ vertical-align: middle;
37
+ text-transform: uppercase;
38
+ }
39
+
40
+ ul li {
41
+ &::before {
42
+ left: calc(var(--sidebar-icon-width) - 5px);
43
+ }
44
+
45
+ a {
46
+ padding-left: calc(var(--sidebar-icon-width) + 10px);
47
+
48
+ &:hover {
49
+ background-color: $primary;
50
+ }
51
+ }
52
+ }
53
+
54
+ .fa { font-size: 20px; }
55
+ .text { display: none; }
56
+
57
+ .collapse {
58
+ background-color: $secondary;
59
+ left: var(--sidebar-compact-width);
60
+ position: absolute;
61
+ top: 0;
62
+ width: 240px;
63
+ }
64
+ }
65
+ }
66
+ }
@@ -0,0 +1,23 @@
1
+ def class_exists?(class_name)
2
+ klass = Module.const_get(class_name)
3
+ return klass.is_a?(Class)
4
+ rescue NameError
5
+ return false
6
+ end
7
+
8
+ class Module
9
+ def takes(*arg_names)
10
+ define_method(:initialize) do |*arg_values|
11
+ arg_names.zip(arg_values).each do |name, value|
12
+ if name.is_a?(Hash)
13
+ name, default_value = name.to_a.flatten
14
+ value = default_value if value.blank?
15
+ end
16
+
17
+ instance_variable_set(:"@#{name}", value)
18
+ end
19
+ end
20
+ end
21
+
22
+ alias_method :let, :define_method
23
+ end
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Explain the generator
3
+
4
+ Example:
5
+ bin/rails generate plok/sidebar
6
+
7
+ This will create:
8
+ what/will/it/create
@@ -0,0 +1,114 @@
1
+ require 'rails/generators/base'
2
+
3
+ class Plok::SidebarGenerator < Rails::Generators::Base
4
+ source_root File.expand_path('templates', __dir__)
5
+ class_option :css_framework, type: :string, default: 'bs5'
6
+
7
+ def install
8
+ copy_sidebar_files('wrapper', 'menu_items', 'menu_item', 'offcanvas_menu')
9
+ add_scss_imports_to_application
10
+ add_js_imports_to_application
11
+ inject_wrapper_block_into_application_layout
12
+ say("\nAll done! Remember to reboot your server so the new assets can load.\n\n")
13
+ end
14
+
15
+ private
16
+
17
+ def add_js_imports_to_application
18
+ if application_file(:js)
19
+ unless file_contains?(application_file(:js), /\/\/= require plok\/sidebar/)
20
+ append_to_file application_file(:js), "//= require plok/sidebar"
21
+ end
22
+ else
23
+ say("\nWARNING: No suitable application.js file found.\n")
24
+ say("Please add the following import to your backend application.js file:\n\n")
25
+ say("//= require plok/sidebar\n\n")
26
+ end
27
+ end
28
+
29
+ def add_scss_imports_to_application
30
+ if application_file(:scss)
31
+ unless file_contains?(application_file(:scss), /@import 'plok\/sidebar'/)
32
+ append_to_file application_file(:scss), "@import 'plok/sidebar';\n"
33
+ end
34
+
35
+ unless file_contains?(application_file(:scss), /@import 'plok\/sidebar_compact'/)
36
+ append_to_file application_file(:scss), "@import 'plok/sidebar_compact';\n"
37
+ end
38
+ else
39
+ say("\nWARNING: No suitable application.scss file found.\n")
40
+ say("Please add the following imports to your backend application.scss file:\n\n")
41
+ say("@import 'plok/sidebar';\n")
42
+ say("@import 'plok/sidebar_compact';\n")
43
+ end
44
+ end
45
+
46
+ def inject_wrapper_block_into_application_layout
47
+ # The sidebar wrapper already exists, so stop here.
48
+ return if file_contains?(application_layout_file, /sidebar\/wrapper/)
49
+
50
+ # The wrapper is missing, but we *need* a suitable spot for a closing tag.
51
+ unless file_contains?(application_layout_file, /yield\(:javascripts_early\)/)
52
+ say("\nWARNING: The generator could not inject the sidebar wrapper.\n")
53
+ say("You will have to wrap your backend application markup in this block:\n\n")
54
+ say("# #{application_layout_file}\n")
55
+ say("<%= render 'backend/#{options.css_framework}/sidebar/wrapper', brand_name: '#{app_name}' do %>\n")
56
+ say(" # ...your backend application markup here...\n")
57
+ say("<% end %>\n")
58
+ return
59
+ end
60
+
61
+ gsub_file(
62
+ application_layout_file,
63
+ /<body(.*)>\n/,
64
+ "<body\\1>\n <%= render 'backend/#{options.css_framework}/sidebar/wrapper', brand_name: '#{app_name}' do %>\n"
65
+ )
66
+
67
+ gsub_file(
68
+ application_layout_file,
69
+ /\n(.*)<%= yield\(:javascripts_early\) %>/,
70
+ " <% end %>\n\n\\1<%= yield(:javascripts_early) %>"
71
+ )
72
+ end
73
+
74
+ def app_name
75
+ Rails.application.class.name.split('::').first
76
+ end
77
+
78
+ def copy_sidebar_files(*partials)
79
+ partials.each do |partial_name|
80
+ copy_file "_#{partial_name}.html.erb", sidebar_partial_path(partial_name)
81
+ end
82
+ end
83
+
84
+ def sidebar_partial_path(partial_name)
85
+ "app/views/backend/#{options.css_framework}/sidebar/_#{partial_name}.html.erb"
86
+ end
87
+
88
+ def file_contains?(file, content)
89
+ File.readlines(file).grep(content).any?
90
+ end
91
+
92
+ def application_layout_file
93
+ if File.exists?("app/views/layouts/backend/#{options.css_framework}/application.html.erb")
94
+ return "app/views/layouts/backend/#{options.css_framework}/application.html.erb"
95
+ end
96
+
97
+ if File.exists?('app/views/layouts/backend/application.html.erb')
98
+ return 'app/views/layouts/backend/application.html.erb'
99
+ end
100
+ end
101
+
102
+ def application_file(type)
103
+ namespace = 'stylesheets'
104
+ namespace = 'javascripts' if type.to_s == 'js'
105
+
106
+ if File.exists?("app/assets/#{namespace}/backend/#{options.css_framework}/application.#{type}")
107
+ return "app/assets/#{namespace}/backend/#{options.css_framework}/application.#{type}"
108
+ end
109
+
110
+ if File.exists?("app/assets/#{namespace}/backend/application.#{type}")
111
+ return "app/assets/#{namespace}/backend/application.#{type}"
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,16 @@
1
+ <% lbl ||= t("b.#{name}") %>
2
+ <% href ||= defined?(path) ? path : "#nav-#{name}" %>
3
+
4
+ <%= content_tag :li, class: 'top-level' do %>
5
+ <%= link_to href, class: 'top-level-anchor link-light', data: { bs_toggle: ('collapse' unless defined?(path)) } do %>
6
+ <%= fa_icon icon, class: 'fa-fw' %>
7
+ <%= content_tag :span, lbl, class: 'text' %>
8
+ <% end %>
9
+
10
+ <% unless defined?(path) %>
11
+ <%= content_tag :div, id: "nav-#{name}", class: 'collapse' do %>
12
+ <h4><%= lbl %></h4>
13
+ <%= yield %>
14
+ <% end %>
15
+ <% end %>
16
+ <% end %>
@@ -0,0 +1,9 @@
1
+ <ul class="justify-content-center">
2
+ <%= render 'backend/bs5/sidebar/menu_item', name: 'admins', icon: 'user-secret-o' do %>
3
+ <ul>
4
+ <%= content_tag :li do %>
5
+ <%= link_to t('b.overview'), backend_admins_path %>
6
+ <% end %>
7
+ </ul>
8
+ <% end %>
9
+ </ul>
@@ -0,0 +1,11 @@
1
+ <div class="offcanvas offcanvas-start bg-dark text-light" tabindex="-1" id="navigation-offcanvas">
2
+ <div class="offcanvas-header">
3
+ <h5 class="offcanvas-title"><%= brand_name %></h5>
4
+ <button type="button" class="btn-close btn-close-white" data-bs-dismiss="offcanvas" aria-label="Close"></button>
5
+ </div>
6
+ <div class="offcanvas-body">
7
+ <div class="sidebar-menu position-static">
8
+ <%= render 'backend/bs5/sidebar/menu_items' %>
9
+ </div>
10
+ </div>
11
+ </div>
@@ -0,0 +1,19 @@
1
+ <div class="wrapper">
2
+ <div class="sidebar-menu text-light bg-dark overflow-auto">
3
+ <%= link_to backend_path, class: 'text-center navbar-brand logo text-light me-0' do %>
4
+ <%= brand_name %>
5
+ <% end %>
6
+
7
+ <%= link_to fa_icon(:'home'), backend_path, class: 'text-center navbar-brand home-icon text-light fs-2 me-0' %>
8
+
9
+ <nav class="mt-3">
10
+ <%= render 'backend/bs5/sidebar/menu_items' %>
11
+ </nav>
12
+ </div>
13
+
14
+ <div class="content">
15
+ <%= yield %>
16
+ </div>
17
+ </div>
18
+
19
+ <%= render 'backend/bs5/sidebar/offcanvas_menu', brand_name: brand_name %>
data/lib/plok/engine.rb CHANGED
@@ -19,6 +19,9 @@ module Plok
19
19
  g.test_framework :rspec
20
20
  end
21
21
 
22
+ # Autoload classes from the lib dir
23
+ config.autoload_paths << File.expand_path('../..', __FILE__)
24
+
22
25
  def class_exists?(class_name)
23
26
  klass = Module.const_get(class_name.to_s)
24
27
  klass.is_a?(Class)
data/lib/plok/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Plok
2
- VERSION = '0.2.12'
2
+ VERSION = '1.0.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plok
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.12
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Davy Hellemans
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-05-12 00:00:00.000000000 Z
12
+ date: 2022-06-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -78,12 +78,15 @@ files:
78
78
  - MIT-LICENSE
79
79
  - Rakefile
80
80
  - app/assets/config/plok_manifest.js
81
+ - app/assets/javascripts/plok/sidebar.js
82
+ - app/assets/stylesheets/plok/_sidebar.scss
83
+ - app/assets/stylesheets/plok/_sidebar_compact.scss
81
84
  - app/controllers/catch_all_controller.rb
82
85
  - app/controllers/plok/version_controller.rb
83
86
  - app/models/concerns/plok/loggable.rb
84
87
  - app/models/log.rb
85
88
  - app/models/queued_task.rb
86
- - config/plok.yml
89
+ - config/initializers/module.rb
87
90
  - config/routes.rb
88
91
  - db/migrate/20211008130809_create_plok_logs.rb
89
92
  - db/migrate/20211015141837_create_plok_queued_tasks.rb
@@ -93,6 +96,12 @@ files:
93
96
  - db/migrate/20211203103118_add_file_to_logs.rb
94
97
  - db/migrate/20220512141814_add_log_indexes_to_category_type_and_id.rb
95
98
  - db/migrate/20220512142356_add_index_to_queued_task_weight.rb
99
+ - lib/generators/plok/sidebar/USAGE
100
+ - lib/generators/plok/sidebar/sidebar_generator.rb
101
+ - lib/generators/plok/sidebar/templates/_menu_item.html.erb
102
+ - lib/generators/plok/sidebar/templates/_menu_items.html.erb
103
+ - lib/generators/plok/sidebar/templates/_offcanvas_menu.html.erb
104
+ - lib/generators/plok/sidebar/templates/_wrapper.html.erb
96
105
  - lib/plok.rb
97
106
  - lib/plok/engine.rb
98
107
  - lib/plok/version.rb
@@ -120,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
120
129
  - !ruby/object:Gem::Version
121
130
  version: '0'
122
131
  requirements: []
123
- rubygems_version: 3.2.28
132
+ rubygems_version: 3.3.9
124
133
  signing_key:
125
134
  specification_version: 4
126
135
  summary: CMS basics
data/config/plok.yml DELETED
@@ -1,9 +0,0 @@
1
- development:
2
- modules:
3
- - flexible_content
4
- - snippets
5
- - settings
6
- - queued_tasks
7
- - email_templates
8
- - pages
9
- - redirects