plok 0.2.12 → 1.0.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.
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