dokno 1.0.0 → 1.1.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: '08352501c3a71f5edef7bd7bf311d8459dc5d38adc20dff5540f755bf04033b6'
4
- data.tar.gz: 19aedf91902b6fc6e30378074740578c347041702d849999a7c62c4a0fff53cd
3
+ metadata.gz: df8bbd2d17e134f0298f31fc97d049b245c4830e9d44655a8c4659507c6ebe6f
4
+ data.tar.gz: bdeb9513295036198a8f30a476a1ea8a4c34d35330c9e6e75e2364aadddf0b3b
5
5
  SHA512:
6
- metadata.gz: f44728981b2004cb703d75641f72f02dc0cf4e92b697ae10d8ef69f1e1b099aa536499c139ae6931748331bbfe3c77bbcbeb3395e59b7fa99398aaeb45b25761
7
- data.tar.gz: 32a8b4f6cbf26d8ef35a6894e3d668f10b81f085c47b65fa44abba17fec7fa337c7e917a532af45bf258c80ecdf869c3ec48cdd6386f96e3e029e3100ee84776
6
+ metadata.gz: 97c1353f3c85e9a6e40de60a0947101978bb101b0dc85be48945ee7e54bb13596fd0f1afbd011113f538c5dfe0ed8784c09c87643b5813e5021292c49244273b
7
+ data.tar.gz: 1bfda031b688b21b65fc8b43fd550e006fec2d5b5f1fd50d4f536db9724ef4853ed47f49e8b2e3ed3329f9ecd6092eb2d678dc6562fa1c07d092da0412ff1e12
@@ -61,6 +61,17 @@ function deleteArticle(id) {
61
61
  sendRequest(dokno__base_path + 'articles/' + id, {}, callback, 'DELETE');
62
62
  }
63
63
 
64
+ function deleteCategory(id) {
65
+ if (!confirm('Delete Category\n\nThis will remove this category. Any articles in this category will become uncategorized and appear on the home page until re-categorized.')) {
66
+ return true;
67
+ }
68
+
69
+ const callback = function(_data) {
70
+ location.href = dokno__base_path;
71
+ }
72
+ sendRequest(dokno__base_path + 'categories/' + id, {}, callback, 'DELETE');
73
+ }
74
+
64
75
  function previewArticleToggle() {
65
76
  const markdown = elem('div#dokno-content-container textarea#markdown').value;
66
77
  const callback = function(data) {
@@ -1,7 +1,10 @@
1
1
  module Dokno
2
2
  class ApplicationController < ::ApplicationController
3
3
  protect_from_forgery with: :exception
4
+
4
5
  include UserConcern
5
6
  include PaginationConcern
7
+
8
+ add_flash_types :green, :yellow, :red
6
9
  end
7
10
  end
@@ -27,9 +27,11 @@ module Dokno
27
27
  set_editor_username
28
28
 
29
29
  if @article.save
30
+ flash[:green] = 'Article was created'
30
31
  @article.categories = Category.where(code: params[:category_code]) if params[:category_code].present?
31
32
  redirect_to article_path @article.slug
32
33
  else
34
+ flash.now[:red] = 'Article could not be created'
33
35
  @category_codes = params[:category_code]
34
36
  render :new
35
37
  end
@@ -42,9 +44,11 @@ module Dokno
42
44
  set_editor_username
43
45
 
44
46
  if @article.update(article_params)
47
+ flash[:green] = 'Article was updated'
45
48
  @article.categories = Category.where(code: params[:category_code])
46
49
  redirect_to article_path @article.slug
47
50
  else
51
+ flash.now[:red] = 'Article could not be updated'
48
52
  @category_codes = params[:category_code]
49
53
  render :edit
50
54
  end
@@ -52,6 +56,8 @@ module Dokno
52
56
 
53
57
  def destroy
54
58
  Article.find(params[:id].to_i).destroy!
59
+
60
+ flash[:green] = 'Article was deleted'
55
61
  render json: {}, layout: false
56
62
  end
57
63
 
@@ -35,8 +35,10 @@ module Dokno
35
35
  @category = Category.new(name: params[:name], parent: Category.find_by(code: params[:parent_category_code]))
36
36
 
37
37
  if @category.save
38
+ flash[:green] = 'Category was created'
38
39
  redirect_to article_index_path(@category.code)
39
40
  else
41
+ flash.now[:red] = 'Category could not be created'
40
42
  @parent_category_code = params[:parent_category_code]
41
43
  render :new
42
44
  end
@@ -46,13 +48,22 @@ module Dokno
46
48
  return redirect_to root_path if @category.blank?
47
49
 
48
50
  if @category.update(name: params[:name], parent: Category.find_by(code: params[:parent_category_code]))
51
+ flash[:green] = 'Category was updated'
49
52
  redirect_to article_index_path(@category.code)
50
53
  else
54
+ flash.now[:red] = 'Category could not be updated'
51
55
  @parent_category_code = params[:parent_category_code]
52
56
  render :edit
53
57
  end
54
58
  end
55
59
 
60
+ def destroy
61
+ Category.find(params[:id].to_i).destroy!
62
+
63
+ flash[:green] = 'Category was deleted'
64
+ render json: {}, layout: false
65
+ end
66
+
56
67
  private
57
68
 
58
69
  def fetch_category
@@ -9,9 +9,7 @@ module Dokno
9
9
 
10
10
  return "Dokno article slug '#{slug}' not found" if article.blank?
11
11
 
12
- %Q(
13
- <a href="javascript:;" onclick="doknoOpenPanel('#{j article.slug}');">#{link_text.presence || article.title}</a>
14
- ).html_safe
12
+ %Q(<a href="javascript:;" onclick="doknoOpenPanel('#{j article.slug}');">#{link_text.presence || article.title}</a>).html_safe
15
13
  end
16
14
  end
17
15
  end
@@ -20,6 +20,8 @@ module Dokno
20
20
 
21
21
  before_validation :set_code
22
22
 
23
+ scope :alpha_order, -> { order(:name) }
24
+
23
25
  # The display breadcrumb for the Category
24
26
  def breadcrumb
25
27
  crumbs = [name]
@@ -71,19 +73,40 @@ module Dokno
71
73
  categories.flatten
72
74
  end
73
75
 
74
- # HTML markup for Category SELECT field OPTION lists
75
- def self.select_option_markup(selected_category_codes: nil, exclude_category_id: nil)
76
- breadcrumbs = all
77
- .reject { |category| category.id == exclude_category_id.to_i }
78
- .map { |category| { code: category.code, name: category.breadcrumb } }
79
- breadcrumbs.sort_by { |category_hash| category_hash[:name] }.map do |category_hash|
80
- selected = selected_category_codes&.include?(category_hash[:code])
81
- %(<option value="#{category_hash[:code]}" #{'selected="selected"' if selected}>#{category_hash[:name]}</option>)
82
- end.join
76
+ def self.select_option_markup(selected_category_codes: nil, exclude_category_id: nil, context_category: nil, level: 0)
77
+ return '' if level.positive? && context_category.blank?
78
+
79
+ options = []
80
+ level_categories = where(category_id: context_category&.id).alpha_order
81
+
82
+ level_categories.each do |category|
83
+ options << option_markup(
84
+ category: category,
85
+ selected_category_codes: selected_category_codes,
86
+ exclude_category_id: exclude_category_id,
87
+ level: level
88
+ )
89
+
90
+ options << select_option_markup(
91
+ selected_category_codes: selected_category_codes,
92
+ exclude_category_id: exclude_category_id,
93
+ context_category: category,
94
+ level: (level + 1)
95
+ )
96
+ end
97
+
98
+ options.join
83
99
  end
84
100
 
85
101
  private
86
102
 
103
+ def self.option_markup(category:, selected_category_codes:, exclude_category_id:, level: 0)
104
+ return '' if category.id == exclude_category_id
105
+
106
+ selected = selected_category_codes&.include?(category.code)
107
+ %(<option value="#{category.code}" #{'selected="selected"' if selected}>#{('&nbsp;&nbsp;' * level)}#{category.name}</option>)
108
+ end
109
+
87
110
  # Never allow setting of parent to self
88
111
  def circular_parent_check
89
112
  return unless persisted? && id.to_i == category_id.to_i
@@ -67,6 +67,7 @@
67
67
 
68
68
  // Close on escape
69
69
  document.addEventListener('keydown', dokno__keydown_listener, false);
70
+ document.addEventListener('click', dokno__click_listener, false);
70
71
  }
71
72
  };
72
73
 
@@ -78,6 +79,7 @@
78
79
  dokno__panel.classList.remove('open');
79
80
  document.body.classList.remove('dokno-no-scroll');
80
81
  document.removeEventListener('keydown', dokno__keydown_listener, false);
82
+ document.removeEventListener('click', dokno__click_listener, false);
81
83
 
82
84
  dokno__slug = null;
83
85
  }
@@ -106,6 +108,11 @@
106
108
  if (e.key === 'Escape') { doknoClosePanel(); }
107
109
  }
108
110
 
111
+ const dokno__click_listener = function(e) {
112
+ var isClickInside = dokno__panel.contains(e.target);
113
+ if (!isClickInside) { doknoClosePanel(); }
114
+ }
115
+
109
116
  dokno__close.onclick = function() { doknoClosePanel(); }
110
117
 
111
118
  var dokno__id, dokno__slug;
@@ -58,3 +58,5 @@
58
58
  </div>
59
59
 
60
60
  </section>
61
+
62
+ <script> elem('input#slug').focus(); </script>
@@ -1,6 +1,14 @@
1
1
  <%= render 'dokno/article_formatting' %>
2
2
 
3
3
  <section>
4
+ <% if @article.categories.present? %>
5
+ <div class="text-gray-500 mb-5">
6
+ <% @article.categories.each do |category| %>
7
+ <div><a href="<%= article_index_path(category.code) %>"><%= category.breadcrumb %></a></div>
8
+ <% end %>
9
+ </div>
10
+ <% end %>
11
+
4
12
  <div class="flex">
5
13
  <div id="dokno-article-sidebar" class="w-2/5 pr-10">
6
14
  <div id="article-deprecated-alert" class="<%= 'hidden' if @article.active %> bg-yellow-700 p-4 mb-5 rounded text-lg border-t-4 border-yellow-900 text-white font-base">
@@ -28,6 +28,11 @@
28
28
 
29
29
  <div class="mt-10">
30
30
  <button type="submit" class="bg-gray-700 text-gray-300 hover:bg-gray-900 hover:text-white rounded py-2 px-3 font-bold"><i data-feather="check" class="inline h-5"></i> SAVE CATEGORY</button>
31
+ <% if category.persisted? %>
32
+ <button type="button" class="bg-red-700 text-gray-300 hover:bg-red-900 hover:text-white rounded py-2 px-3 font-bold ml-5" onclick="deleteCategory('<%= category.id %>');"><i data-feather="trash" class="inline h-5"></i> DELETE</button>
33
+ <% end %>
31
34
  <span class="text-lg ml-5"><a class="no-underline" href="<%= category.persisted? ? "#{root_path}?id=#{category.id}" : root_path %>">Cancel</a></span>
32
35
  </div>
33
36
  </section>
37
+
38
+ <script> elem('input#name').focus(); </script>
@@ -1,3 +1,8 @@
1
+ <% if @category&.parent.present? %>
2
+ <div class="text-gray-500 mb-5">
3
+ <div><%= @category.breadcrumb %></div>
4
+ </div>
5
+ <% end %>
1
6
 
2
7
  <div class="flex items-center mb-10">
3
8
  <% if Dokno::Category.exists? %>
@@ -63,6 +63,13 @@
63
63
  <% end %>
64
64
 
65
65
  <div id="dokno-content-container" class="w-full max-w-screen-xl m-auto print-this">
66
+ <% flash.each do |color, msg| %>
67
+ <div class="bg-<%= color %>-700 p-4 mb-5 rounded text-lg border-t-4 border-<%= color %>-900 text-white font-base">
68
+ <i data-feather="<%= (color == 'green' ? 'check-circle' : (color == 'yellow' ? 'alert-circle' : 'x-circle')) %>" class="inline mr-2"></i>
69
+ <%= msg %>
70
+ </div>
71
+ <% end %>
72
+
66
73
  <%= yield %>
67
74
  </div>
68
75
  </main>
@@ -1,3 +1,3 @@
1
1
  module Dokno
2
- VERSION = '1.0.0'
2
+ VERSION = '1.1.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dokno
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Courtney Payne
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-03 00:00:00.000000000 Z
11
+ date: 2020-12-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: diffy
@@ -169,8 +169,7 @@ dependencies:
169
169
  - !ruby/object:Gem::Version
170
170
  version: '2.15'
171
171
  description: Dokno allows you to easily mount a self-contained knowledgebase / wiki
172
- / help system to your Rails app where you and your users can author articles relevant
173
- to your app.
172
+ / help system to your Rails app.
174
173
  email:
175
174
  - cpayne624@gmail.com
176
175
  executables: []