dokno 1.2.1 → 1.4.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.
@@ -11,6 +11,11 @@
11
11
  </optgroup>
12
12
  </select>
13
13
  </div>
14
+
15
+ <script>
16
+ // Client-side select of cached select list
17
+ selectOption('category', '<%= j @category&.code %>');
18
+ </script>
14
19
  <% end %>
15
20
 
16
21
  <% if Dokno::Article.exists? %>
@@ -22,8 +27,4 @@
22
27
  <% end %>
23
28
  </div>
24
29
 
25
- <script>
26
- // Client-side select of cached select list
27
- selectOption('category', '<%= j @category&.code %>');
28
- enableSearchHotkey();
29
- </script>
30
+ <script> enableSearchHotkey(); </script>
@@ -20,7 +20,7 @@
20
20
  <% end %>
21
21
 
22
22
  <div class="text-gray-500 bg-gray-700 p-5 pr-10 rounded <%= 'cursor-pointer' if log.diff_left != log.diff_right %> flex items-center" onclick="toggleVisibility('article-diff-<%= log.id %>');" title="Show / Hide Diff">
23
- <div class="w-4/5">
23
+ <div class="w-<%= log.diff_left != log.diff_right ? '11/12' : 'full' %>">
24
24
  <%= time_ago_in_words log.created_at %> ago
25
25
  <% if log.username.present? %>
26
26
  by <%= log.username %>
@@ -31,9 +31,11 @@
31
31
  <% end %>
32
32
  </div>
33
33
 
34
- <div class="w-1/5 text-right toggle-visibility-indicator-container article-diff-<%= log.id %>">
35
- <% if log.diff_left != log.diff_right %><i data-feather="chevron-left" class="inline toggle-visibility-indicator article-diff-<%= log.id %>"></i><% end %>
36
- </div>
34
+ <% if log.diff_left != log.diff_right %>
35
+ <div class="w-1/12 text-right toggle-visibility-indicator-container article-diff-<%= log.id %>">
36
+ <i data-feather="chevron-left" class="inline toggle-visibility-indicator article-diff-<%= log.id %>"></i>
37
+ </div>
38
+ <% end %>
37
39
  </div>
38
40
 
39
41
  <% if log.diff_left != log.diff_right %>
@@ -1,28 +1,31 @@
1
- <span class="mr-5">
2
- <% if @page > 1 %>
3
- <span class="mr-1 inline-block"><a href="?search_term=<%= CGI.escape @search_term.to_s %>&order=<%= @order %>&page=<%= (@page - 1) %>"><i data-feather="arrow-left" class="h-5 inline-block" title="Previous page"></i></a></span>
4
- <% end %>
1
+ <% if @total_pages > 1 %>
2
+ <span class="mr-5">
3
+ <% if @page > 1 %>
4
+ <span class="mr-1 inline-block"><a href="?search_term=<%= CGI.escape @search_term.to_s %>&order=<%= @order %>&page=<%= (@page - 1) %>"><i data-feather="arrow-left" class="h-5 inline-block" title="Previous page"></i></a></span>
5
+ <% end %>
5
6
 
6
- <span class="mr-1 inline-block">Page</span>
7
+ <span class="mr-1 inline-block">Page</span>
7
8
 
8
- <%= form_with(url: article_index_path(@category&.code), method: :get, class: 'inline') do %>
9
- <input type="hidden" name="search_term" value="<%= @search_term %>">
10
- <input type="hidden" name="order" value="<%= @order %>">
11
- <input aria-label="Page" type="text" name="page" value="<%= @page %>" onclick="this.select();" class="w-10 text-center bg-gray-200 rounded" />
9
+ <%= form_with(url: article_index_path(@category&.code), method: :get, class: 'inline') do %>
10
+ <input type="hidden" name="search_term" value="<%= @search_term %>">
11
+ <input type="hidden" name="order" value="<%= @order %>">
12
+ <input aria-label="Page" type="text" name="page" value="<%= @page %>" onclick="this.select();" class="w-10 text-center bg-gray-200 rounded" />
12
13
 
13
- <span class="mx-1 inline-block">of</span>
14
- <span class="text-center inline-block"><%= @total_pages %></span>
15
- <% end %>
14
+ <span class="mx-1 inline-block">of</span>
15
+ <span class="text-center inline-block"><%= @total_pages %></span>
16
+ <% end %>
16
17
 
17
- <% if @page < @total_pages %>
18
- <span class="ml-1 inline-block"><a href="?search_term=<%= CGI.escape @search_term.to_s %>&order=<%= @order %>&page=<%= (@page + 1) %>"><i data-feather="arrow-right" class="h-5 inline-block" title="Next page"></i></a></span>
19
- <% end %>
20
- </span>
18
+ <% if @page < @total_pages %>
19
+ <span class="ml-1 inline-block"><a href="?search_term=<%= CGI.escape @search_term.to_s %>&order=<%= @order %>&page=<%= (@page + 1) %>"><i data-feather="arrow-right" class="h-5 inline-block" title="Next page"></i></a></span>
20
+ <% end %>
21
+ </span>
22
+ <% end %>
21
23
 
22
24
  <span class="text-gray-400">
23
25
  <%= @total_records %>
24
- <%= 'uncategorized' if @category.blank? && @search_term.blank? %>
26
+ <%= 'uncategorized' if !current_page?(up_for_review_path) && @category.blank? && @search_term.blank? %>
25
27
  <%= 'article'.pluralize(@total_records) %>
28
+ <%= 'up for review' if current_page?(up_for_review_path) %>
26
29
 
27
30
  <% if @search_term.present? %>
28
31
  containing <span class="font-serif">&ldquo;</span><%= @search_term %><span class="font-serif">&rdquo;</span>
data/config/routes.rb CHANGED
@@ -3,6 +3,7 @@ Dokno::Engine.routes.draw do
3
3
  resources :articles
4
4
 
5
5
  get '/(:cat_code)', to: 'categories#index', as: :article_index
6
+ get '/up_for_review', to: 'categories#index', as: :up_for_review
6
7
  get 'article_panel/(:slug)', to: 'articles#panel', as: :panel
7
8
  post 'article_preview', to: 'articles#preview', as: :preview
8
9
  post 'article_status', to: 'articles#status', as: :status
@@ -13,12 +13,12 @@ class Baseline < ActiveRecord::Migration[6.0]
13
13
  t.string "slug"
14
14
  t.string "title"
15
15
  t.text "markdown"
16
- t.datetime "created_at", precision: 6, null: false
17
- t.datetime "updated_at", precision: 6, null: false
18
16
  t.text "summary"
19
17
  t.boolean "active", default: true
20
18
  t.bigint "views", default: 0
21
19
  t.datetime "last_viewed_at"
20
+ t.datetime "created_at", precision: 6, null: false
21
+ t.datetime "updated_at", precision: 6, null: false
22
22
  t.index ["slug"], name: "index_dokno_articles_on_slug", unique: true
23
23
  end
24
24
 
@@ -32,10 +32,10 @@ class Baseline < ActiveRecord::Migration[6.0]
32
32
 
33
33
  create_table "dokno_categories", force: :cascade do |t|
34
34
  t.string "name"
35
- t.datetime "created_at", precision: 6, null: false
36
- t.datetime "updated_at", precision: 6, null: false
37
35
  t.bigint "category_id"
38
36
  t.string "code", null: false
37
+ t.datetime "created_at", precision: 6, null: false
38
+ t.datetime "updated_at", precision: 6, null: false
39
39
  t.index ["category_id"], name: "index_dokno_categories_on_category_id"
40
40
  t.index ["code"], name: "index_dokno_categories_on_code", unique: true
41
41
  t.index ["name"], name: "index_dokno_categories_on_name", unique: true
@@ -0,0 +1,6 @@
1
+ class AddReviewDueAtToArticles < ActiveRecord::Migration[6.0]
2
+ def change
3
+ add_column :dokno_articles, :review_due_at, :datetime
4
+ add_index :dokno_articles, :review_due_at
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ class AddStarredToArticle < ActiveRecord::Migration[6.0]
2
+ def change
3
+ add_column :dokno_articles, :starred, :boolean, default: false
4
+ end
5
+ end
@@ -1,4 +1,10 @@
1
+ require 'active_support/time'
2
+
1
3
  module Dokno
4
+ module Error
5
+ class Config < StandardError; end
6
+ end
7
+
2
8
  def self.configure
3
9
  yield config
4
10
  config.validate
@@ -8,62 +14,71 @@ module Dokno
8
14
  @config ||= Config.new
9
15
  end
10
16
 
11
- def self.config=(val)
12
- @config = val
13
- end
14
-
15
17
  class Config
16
- # (String) Host application name for display within the mounted dashboard
17
- attr_accessor :app_name
18
+ # Dokno configuration options
19
+ #
20
+ # app_name (String)
21
+ # Host app name for display within the mounted dashboard
22
+ # tag_whitelist (Enumerable)
23
+ # Determines which HTML tags are allowed in Article markdown
24
+ # attr_whitelist (Enumerable)
25
+ # Determines which HTML attributes are allowed in Article markdown
26
+ # app_user_object (String)
27
+ # Host app's user object
28
+ # app_user_auth_method (Symbol)
29
+ # Host app's user object method to be used for edit authorization.
30
+ # Should return boolean
31
+ # app_user_name_method (Symbol)
32
+ # Host app's user object method that returns the authenticated user's name or other
33
+ # identifier that will be included in change log events.
34
+ # Should return a string
35
+ # article_review_period (ActiveSupport::Duration)
36
+ # The amount of time before articles should be reviewed for accuracy/relevance
37
+ # article_review_prompt_days (Integer)
38
+ # The number of days prior to an article being up for review that users should be prompted
18
39
 
19
- # (Enumerable) Determines which HTML tags are allowed in Article markdown
40
+ attr_accessor :app_name
20
41
  attr_accessor :tag_whitelist
21
-
22
- # (Enumerable) Determines which HTML attributes are allowed in Article markdown
23
42
  attr_accessor :attr_whitelist
24
-
25
- # (String) Host application's user object
26
43
  attr_accessor :app_user_object
27
-
28
- # (Symbol) Host application's user object method that should be used to authorize users to edit Dokno data
29
- # Should return boolean.
30
44
  attr_accessor :app_user_auth_method
31
-
32
- # (Symbol) Host application's user object method that should return the authenticated user's name or other
33
- # identifier that will be included in change log events. Should return a string.
34
45
  attr_accessor :app_user_name_method
46
+ attr_accessor :article_review_period
47
+ attr_accessor :article_review_prompt_days
35
48
 
36
49
  # Defaults
37
- TAG_WHITELIST = %w[code img h1 h2 h3 h4 h5 h6 a em u i b strong ol ul li table thead tbody tfoot tr th td blockquote hr br p]
38
- ATTR_WHITELIST = %w[src alt title href target]
39
- APP_USER_OBJECT = 'current_user'
40
- APP_USER_AUTH_METHOD = 'admin?'
41
- APP_USER_NAME_METHOD = 'name'
50
+ TAG_WHITELIST = %w[code img h1 h2 h3 h4 h5 h6 a em u i b strong ol ul li table thead tbody tfoot tr th td blockquote hr br p]
51
+ ATTR_WHITELIST = %w[src alt title href target]
52
+ APP_USER_OBJECT = 'current_user'
53
+ APP_USER_AUTH_METHOD = :admin?
54
+ APP_USER_NAME_METHOD = :name
55
+ ARTICLE_REVIEW_PERIOD = 1.year
56
+ ARTICLE_REVIEW_PROMPT_DAYS = 30
42
57
 
43
58
  def initialize
44
- self.app_name = Rails.application.class.module_parent.name.underscore.humanize.upcase
45
- self.tag_whitelist = TAG_WHITELIST
46
- self.attr_whitelist = ATTR_WHITELIST
47
- self.app_user_object = APP_USER_OBJECT
48
- self.app_user_auth_method = APP_USER_AUTH_METHOD
49
- self.app_user_name_method = APP_USER_NAME_METHOD
59
+ self.app_name = Rails.application.class.module_parent.name.underscore.humanize.upcase
60
+ self.tag_whitelist = TAG_WHITELIST
61
+ self.attr_whitelist = ATTR_WHITELIST
62
+ self.app_user_object = APP_USER_OBJECT
63
+ self.app_user_auth_method = APP_USER_AUTH_METHOD
64
+ self.app_user_name_method = APP_USER_NAME_METHOD
65
+ self.article_review_period = ARTICLE_REVIEW_PERIOD
66
+ self.article_review_prompt_days = ARTICLE_REVIEW_PROMPT_DAYS
50
67
  end
51
68
 
52
69
  def validate
53
- validate_tag_whitelist
54
- validate_attr_whitelist
70
+ validate_config_option(option: 'tag_whitelist', expected_class: Enumerable, example: '%w[a p strong]')
71
+ validate_config_option(option: 'attr_whitelist', expected_class: Enumerable, example: '%w[class href]')
72
+ validate_config_option(option: 'app_user_object', expected_class: String, example: 'current_user')
73
+ validate_config_option(option: 'app_user_auth_method', expected_class: Symbol, example: ':admin?')
74
+ validate_config_option(option: 'app_user_name_method', expected_class: Symbol, example: ':name')
75
+ validate_config_option(option: 'article_review_period', expected_class: ActiveSupport::Duration, example: '1.year')
76
+ validate_config_option(option: 'article_review_prompt_days', expected_class: Integer, example: '30')
55
77
  end
56
78
 
57
- def validate_tag_whitelist
58
- return unless !tag_whitelist.is_a?(Enumerable)
59
-
60
- raise "#{config_error_prefix} tag_whitelist must be Enumerable"
61
- end
62
-
63
- def validate_attr_whitelist
64
- return unless !attr_whitelist.is_a?(Enumerable)
65
-
66
- raise "#{config_error_prefix} attr_whitelist must be Enumerable"
79
+ def validate_config_option(option:, expected_class:, example:)
80
+ return unless !send(option.to_sym).is_a? expected_class
81
+ raise Error::Config, "#{config_error_prefix} #{option} must be #{expected_class}, e.g. #{example}"
67
82
  end
68
83
 
69
84
  def config_error_prefix
data/lib/dokno/engine.rb CHANGED
@@ -4,10 +4,6 @@ module Dokno
4
4
  class Engine < ::Rails::Engine
5
5
  isolate_namespace Dokno
6
6
 
7
- initializer 'Dokno precompile', group: :all do |app|
8
- app.config.assets.precompile << "dokno_manifest.js"
9
- end
10
-
11
7
  config.generators do |g|
12
8
  g.test_framework :rspec
13
9
  end
@@ -18,8 +14,12 @@ module Dokno
18
14
  end
19
15
  end
20
16
 
17
+ initializer 'Dokno precompile', group: :all do |app|
18
+ app.config.assets.precompile << "dokno_manifest.js"
19
+ end
20
+
21
21
  initializer 'local_helper.action_controller' do
22
- ActiveSupport.on_load :action_controller do
22
+ ActiveSupport.on_load :action_controller_base do
23
23
  helper Dokno::ApplicationHelper
24
24
  end
25
25
  end
data/lib/dokno/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Dokno
2
- VERSION = '1.2.1'
2
+ VERSION = '1.4.3'
3
3
  end
@@ -1,14 +1,27 @@
1
1
  Dokno.configure do |config|
2
- config.tag_whitelist = Dokno::Config::TAG_WHITELIST
3
- config.attr_whitelist = Dokno::Config::ATTR_WHITELIST
2
+ # To control the permitted HTML tags and attributes within articles,
3
+ # uncomment and change the defaults.
4
+ # (Enumerable) tag_whitelist
5
+ # (Enumerable) attr_whitelist
6
+ # config.tag_whitelist = %w[code img h1 h2 h3 h4 h5 h6 a em u i b strong ol ul li table thead tbody tfoot tr th td blockquote hr br p]
7
+ # config.attr_whitelist = %w[src alt title href target]
4
8
 
5
9
  # To restrict Dokno data modification and include indentifying information
6
10
  # in change log entries, provide the appropriate user values for your app below.
7
11
  # (String) app_user_object
8
12
  # (Symbol) app_user_auth_method
9
13
  # (Symbol) app_user_name_method
14
+ # config.app_user_object = 'current_user'
15
+ # config.app_user_auth_method = :admin?
16
+ # config.app_user_name_method = :name
10
17
 
11
- # config.app_user_object = 'current_user'
12
- # config.app_user_auth_method = :admin?
13
- # config.app_user_name_method = :name
18
+ # To control the amount of time before a created/updated article is flagged
19
+ # for accuracy/relevance review, uncomment and change the default.
20
+ # (ActiveSupport::Duration) article_review_period
21
+ # config.article_review_period = 1.year
22
+
23
+ # To control the number of days prior to an article being up for review
24
+ # that users should be prompted to re-review, uncomment and change the default.
25
+ # (Integer) article_review_prompt_days
26
+ # config.article_review_prompt_days = 30
14
27
  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.2.1
4
+ version: 1.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Courtney Payne
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-08 00:00:00.000000000 Z
11
+ date: 2021-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: diffy
@@ -134,54 +134,54 @@ dependencies:
134
134
  requirements:
135
135
  - - "~>"
136
136
  - !ruby/object:Gem::Version
137
- version: '5.1'
137
+ version: 5.3.0
138
138
  type: :development
139
139
  prerelease: false
140
140
  version_requirements: !ruby/object:Gem::Requirement
141
141
  requirements:
142
142
  - - "~>"
143
143
  - !ruby/object:Gem::Version
144
- version: '5.1'
144
+ version: 5.3.0
145
145
  - !ruby/object:Gem::Dependency
146
146
  name: rails
147
147
  requirement: !ruby/object:Gem::Requirement
148
148
  requirements:
149
149
  - - "~>"
150
150
  - !ruby/object:Gem::Version
151
- version: 6.0.3
151
+ version: 6.1.3
152
152
  - - ">="
153
153
  - !ruby/object:Gem::Version
154
- version: 6.0.3.4
154
+ version: 6.1.3.2
155
155
  type: :development
156
156
  prerelease: false
157
157
  version_requirements: !ruby/object:Gem::Requirement
158
158
  requirements:
159
159
  - - "~>"
160
160
  - !ruby/object:Gem::Version
161
- version: 6.0.3
161
+ version: 6.1.3
162
162
  - - ">="
163
163
  - !ruby/object:Gem::Version
164
- version: 6.0.3.4
164
+ version: 6.1.3.2
165
165
  - !ruby/object:Gem::Dependency
166
166
  name: rspec-rails
167
167
  requirement: !ruby/object:Gem::Requirement
168
168
  requirements:
169
169
  - - "~>"
170
170
  - !ruby/object:Gem::Version
171
- version: '4.0'
171
+ version: '4.1'
172
172
  - - ">="
173
173
  - !ruby/object:Gem::Version
174
- version: 4.0.1
174
+ version: 4.1.2
175
175
  type: :development
176
176
  prerelease: false
177
177
  version_requirements: !ruby/object:Gem::Requirement
178
178
  requirements:
179
179
  - - "~>"
180
180
  - !ruby/object:Gem::Version
181
- version: '4.0'
181
+ version: '4.1'
182
182
  - - ">="
183
183
  - !ruby/object:Gem::Version
184
- version: 4.0.1
184
+ version: 4.1.2
185
185
  - !ruby/object:Gem::Dependency
186
186
  name: selenium-webdriver
187
187
  requirement: !ruby/object:Gem::Requirement
@@ -208,34 +208,34 @@ dependencies:
208
208
  requirements:
209
209
  - - "~>"
210
210
  - !ruby/object:Gem::Version
211
- version: 0.19.1
211
+ version: 0.21.2
212
212
  type: :development
213
213
  prerelease: false
214
214
  version_requirements: !ruby/object:Gem::Requirement
215
215
  requirements:
216
216
  - - "~>"
217
217
  - !ruby/object:Gem::Version
218
- version: 0.19.1
218
+ version: 0.21.2
219
219
  - !ruby/object:Gem::Dependency
220
220
  name: webdrivers
221
221
  requirement: !ruby/object:Gem::Requirement
222
222
  requirements:
223
223
  - - "~>"
224
224
  - !ruby/object:Gem::Version
225
- version: '4.4'
225
+ version: '4.6'
226
226
  - - ">="
227
227
  - !ruby/object:Gem::Version
228
- version: 4.4.1
228
+ version: 4.6.0
229
229
  type: :development
230
230
  prerelease: false
231
231
  version_requirements: !ruby/object:Gem::Requirement
232
232
  requirements:
233
233
  - - "~>"
234
234
  - !ruby/object:Gem::Version
235
- version: '4.4'
235
+ version: '4.6'
236
236
  - - ">="
237
237
  - !ruby/object:Gem::Version
238
- version: 4.4.1
238
+ version: 4.6.0
239
239
  description: Dokno allows you to easily mount a self-contained knowledgebase / wiki
240
240
  / help system to your Rails app.
241
241
  email:
@@ -284,6 +284,8 @@ files:
284
284
  - app/views/partials/_pagination.html.erb
285
285
  - config/routes.rb
286
286
  - db/migrate/20201203190330_baseline.rb
287
+ - db/migrate/20201211192306_add_review_due_at_to_articles.rb
288
+ - db/migrate/20201213165700_add_starred_to_article.rb
287
289
  - lib/dokno.rb
288
290
  - lib/dokno/config/config.rb
289
291
  - lib/dokno/engine.rb
@@ -298,7 +300,7 @@ licenses:
298
300
  metadata:
299
301
  bug_tracker_uri: https://github.com/cpayne624/dokno/issues
300
302
  changelog_uri: https://github.com/cpayne624/dokno/blob/master/CHANGELOG.md
301
- post_install_message:
303
+ post_install_message:
302
304
  rdoc_options: []
303
305
  require_paths:
304
306
  - lib
@@ -314,7 +316,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
314
316
  version: '0'
315
317
  requirements: []
316
318
  rubygems_version: 3.1.4
317
- signing_key:
319
+ signing_key:
318
320
  specification_version: 4
319
321
  summary: Dokno (dough-no) is a lightweight mountable Rails Engine for storing and
320
322
  managing your app's domain knowledge.