dokno 1.1.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -6
  3. data/app/assets/javascripts/dokno.js +67 -31
  4. data/app/assets/stylesheets/dokno/application.css +1 -1
  5. data/app/controllers/dokno/application_controller.rb +1 -1
  6. data/app/controllers/dokno/articles_controller.rb +19 -11
  7. data/app/controllers/dokno/categories_controller.rb +10 -7
  8. data/app/controllers/dokno/pagination_concern.rb +5 -5
  9. data/app/controllers/dokno/user_concern.rb +6 -4
  10. data/app/helpers/dokno/application_helper.rb +1 -1
  11. data/app/models/dokno/application_record.rb +3 -0
  12. data/app/models/dokno/article.rb +91 -42
  13. data/app/models/dokno/category.rb +24 -45
  14. data/app/views/dokno/_article_formatting.html.erb +17 -18
  15. data/app/views/dokno/_article_panel.html.erb +10 -19
  16. data/app/views/dokno/_panel_formatting.html.erb +47 -57
  17. data/app/views/dokno/articles/_article_form.html.erb +49 -10
  18. data/app/views/dokno/articles/show.html.erb +48 -45
  19. data/app/views/dokno/categories/_category_form.html.erb +18 -7
  20. data/app/views/dokno/categories/index.html.erb +59 -40
  21. data/app/views/layouts/dokno/application.html.erb +36 -35
  22. data/app/views/partials/_category_header.html.erb +30 -0
  23. data/app/views/partials/_form_errors.html.erb +0 -1
  24. data/app/views/partials/_logs.html.erb +7 -5
  25. data/app/views/partials/_pagination.html.erb +20 -18
  26. data/config/routes.rb +1 -1
  27. data/db/migrate/20201203190330_baseline.rb +4 -4
  28. data/db/migrate/20201211192306_add_review_due_at_to_articles.rb +6 -0
  29. data/db/migrate/20201213165700_add_starred_to_article.rb +5 -0
  30. data/lib/dokno/config/config.rb +53 -40
  31. data/lib/dokno/engine.rb +5 -5
  32. data/lib/dokno/version.rb +1 -1
  33. data/lib/generators/dokno/templates/config/initializers/dokno.rb +18 -5
  34. metadata +82 -11
@@ -1,34 +1,37 @@
1
1
  <%= render 'dokno/article_formatting' %>
2
2
 
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>
3
+ <% if @category.present? %>
4
+ <div class="no-print text-gray-500 mb-5">
5
+ <div>
6
+ <% if request.referrer&.include? article_index_path %>
7
+ <a class="fixed left-0 ml-6" title="Back" href="javascript:history.back();"><i data-feather="chevrons-left" class="text-gray-300 h-5 align-text-bottom inline"></i></a>
8
8
  <% end %>
9
+ <span class="text-gray-500 mr-1">Under</span> <%= @category.breadcrumb(search_term: @search_term, order: @order) %>
9
10
  </div>
10
- <% end %>
11
+ </div>
12
+ <% end %>
11
13
 
14
+ <%= render 'partials/category_header' %>
15
+
16
+ <div class="my-10 no-print"><hr /></div>
17
+
18
+ <section>
12
19
  <div class="flex">
13
20
  <div id="dokno-article-sidebar" class="w-2/5 pr-10">
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">
15
- <i data-feather="alert-circle" class="inline-block mr-2"></i> This article is no longer active
16
- </div>
17
-
18
- <h1 class="dokno-article-content-highlight text-4xl mb-10 leading-tight font-light"><%= @article.title %></h1>
21
+ <h1 class="dokno-article-content-highlight text-4xl mb-8 leading-tight font-light">
22
+ <%= @article.title %>
23
+ <% if @article.starred %><i title="Starred article" data-feather="star" class="inline align-middle"></i><% end %>
24
+ </h1>
19
25
 
20
26
  <div>
21
- <div class="mb-10 no-print">
22
- <button title="Email article" class="bg-gray-600 text-gray-300 hover:text-white rounded mr-3 py-2 px-3 font-bold text-xs" onclick="window.open('mailto:?subject=<%= CGI.escape(@article.title) %>&body=<%= CGI.escape(article_url(@article.slug)) %>');"><i data-feather="send" class="inline h-4"></i> EMAIL THIS</button>
23
- <button title="Print article" class="bg-gray-600 text-gray-300 hover:text-white rounded mr-3 py-2 px-3 font-bold text-xs" onclick="window.print();"><i data-feather="printer" class="inline h-4"></i> PRINT THIS</button>
24
-
25
- <% if can_edit? %>
26
- <button title="Edit article" class="bg-blue-900 text-gray-300 hover:text-white rounded py-2 px-3 font-bold text-xs" onclick="location.href='<%= edit_article_path(@article.slug) %>';"><i data-feather="edit" class="inline h-4"></i> EDIT THIS</button>
27
- <% end %>
27
+ <div class="mb-8 no-print">
28
+ <button title="Copy link" class="bg-gray-600 text-gray-300 hover:text-white rounded my-2 mr-2 py-2 px-3 font-bold text-sm" onclick="copyToClipboard('<%= @article.permalink(request.base_url) %>');"><i data-feather="clipboard" class="inline h-5"></i> COPY</button>
29
+ <button title="Email article" class="bg-gray-600 text-gray-300 hover:text-white rounded my-2 mr-2 py-2 px-3 font-bold text-sm" onclick="window.open('mailto:?subject=<%= CGI.escape(@article.title.to_s) %>&body=<%= CGI.escape(article_url(@article.slug)) %>');"><i data-feather="send" class="inline h-5"></i> EMAIL</button>
30
+ <button title="Print article" class="bg-gray-600 text-gray-300 hover:text-white rounded my-2 py-2 px-3 font-bold text-sm" onclick="window.print();"><i data-feather="printer" class="inline h-5"></i> PRINT</button>
28
31
  </div>
29
32
 
30
33
  <div class="flex">
31
- <div class="no-print w-8"><i data-feather="clock" class="inline-block h-5"></i></div>
34
+ <div class="no-print w-8"><i data-feather="clock" class="inline-block h-5 mr-2"></i></div>
32
35
  <div class="w-full">
33
36
  Last updated:<br />
34
37
  <%= time_ago_in_words @article.updated_at %> ago
@@ -38,8 +41,8 @@
38
41
  </div>
39
42
  </div>
40
43
 
41
- <div class="mt-5 flex">
42
- <div class="no-print w-8"><i data-feather="eye" class="inline-block h-5"></i></div>
44
+ <div class="mt-5 flex no-print">
45
+ <div class="no-print w-8"><i data-feather="eye" class="inline-block h-5 mr-2"></i></div>
43
46
  <div class="w-full">
44
47
  Views:<br />
45
48
  <%= number_with_delimiter(@article.views, delimiter: ',') %>
@@ -48,7 +51,7 @@
48
51
 
49
52
  <% if @article.contributors.present? %>
50
53
  <div class="mt-5 flex">
51
- <div class="no-print w-8"><i data-feather="user-check" class="inline-block h-5"></i></div>
54
+ <div class="no-print w-8"><i data-feather="user-check" class="inline-block h-5 mr-2"></i></div>
52
55
  <div class="w-full">
53
56
  Contributors:<br />
54
57
  <%= @article.contributors %>
@@ -57,8 +60,8 @@
57
60
  <% end %>
58
61
 
59
62
  <% if @article.reading_time.present? %>
60
- <div class="mt-5 flex">
61
- <div class="no-print w-8"><i data-feather="watch" class="inline-block h-5"></i></div>
63
+ <div class="mt-5 flex no-print">
64
+ <div class="no-print w-8"><i data-feather="watch" class="inline-block h-5 mr-2"></i></div>
62
65
  <div class="w-full">
63
66
  Reading time:<br />
64
67
  <%= @article.reading_time %>
@@ -67,7 +70,7 @@
67
70
  <% end %>
68
71
 
69
72
  <div class="mt-5 flex">
70
- <div class="no-print w-8"><i data-feather="link" class="inline-block h-5"></i></div>
73
+ <div class="no-print w-8"><i data-feather="link" class="inline-block h-5 mr-2"></i></div>
71
74
  <div class="w-full">
72
75
  Permalink:<br />
73
76
  <a class="inline-block mt-1 -ml-2 px-2 py-1 bg-blue-100 rounded" title="Copy to clipboard" href="javascript:;" onclick="copyToClipboard('<%= @article.permalink(request.base_url) %>');"><%= @article.permalink(request.base_url) %></a>
@@ -75,8 +78,8 @@
75
78
  </div>
76
79
 
77
80
  <% if can_edit? %>
78
- <div class="mt-5 flex">
79
- <div class="no-print w-8"><i data-feather="crosshair" class="inline-block h-5"></i></div>
81
+ <div class="mt-5 flex no-print">
82
+ <div class="no-print w-8"><i data-feather="crosshair" class="inline-block h-5 mr-2"></i></div>
80
83
  <div class="w-full">
81
84
  Unique slug:<br />
82
85
  <a class="inline-block mt-1 -ml-2 px-2 py-1 bg-blue-100 rounded" title="Copy to clipboard" href="javascript:;" onclick="copyToClipboard('<%= j @article.slug %>');"><%= @article.slug %></a>
@@ -93,12 +96,11 @@
93
96
  </div>
94
97
  <% end %>
95
98
 
96
- <% if @article.categories.exists? %>
97
- <div class="mt-5 flex">
98
- <div class="no-print w-8"><i data-feather="folder" class="inline-block h-5"></i></div>
99
+ <% if (category_name_list = @article.category_name_list(context_category_id: @category&.id)).present? %>
100
+ <div class="mt-5 flex no-print">
101
+ <div class="no-print w-8"><i data-feather="folder" class="inline-block h-5 mr-2"></i></div>
99
102
  <div class="w-full">
100
- <%= 'Category'.pluralize @article.categories.count %>:<br />
101
- <%= @article.category_name_list.split(':').last.html_safe %>
103
+ <%= category_name_list.sub(':', ':<br />').html_safe %>
102
104
  </div>
103
105
  </div>
104
106
  <% end %>
@@ -118,21 +120,22 @@
118
120
  <% if @article.summary.blank? && @article.markdown.blank? %>
119
121
  <div class="mb-10">No content</div>
120
122
  <% end %>
121
-
122
- <% if can_edit? %>
123
- <div class="no-print">
124
- <hr class="mt-5" />
125
- <div class="mt-10 text-right">
126
- <button title="Deactivate article" id="article-deactivate-button" class="bg-yellow-700 text-gray-300 hover:text-white rounded mr-3 py-2 px-3 font-bold text-xs <% if !@article.active %>hidden<% end %>" onclick="deactiveArticle('<%= @article.slug %>');"><i data-feather="sunset" class="inline h-4"></i> DEACTIVATE THIS</button>
127
- <button title="Re-activate article" id="article-activate-button" class="bg-green-700 text-gray-300 hover:text-white rounded mr-3 py-2 px-3 font-bold text-xs <% if @article.active %>hidden<% end %>" onclick="activeArticle('<%= @article.slug %>');"><i data-feather="sunrise" class="inline h-4"></i> RE-ACTIVATE THIS</button>
128
- <button title="Permanently delete article" class="bg-red-700 text-gray-300 hover:text-white rounded py-2 px-3 font-bold text-xs" onclick="deleteArticle('<%= @article.id %>');"><i data-feather="trash" class="inline h-4"></i> DELETE THIS</button>
129
- </div>
130
- </div>
131
- <% end %>
132
123
  </div>
133
124
  </div>
134
125
  </section>
135
126
 
136
- <% if @search_term.present? %>
137
- <script>highlightTerm(['<%= j @search_term.strip %>'], 'dokno-article-content-highlight');</script>
127
+ <% if can_edit? %>
128
+ <div class="no-print">
129
+ <hr class="mt-5 mb-10" />
130
+ <div class="text-right">
131
+ <button title="Edit article" class="bg-blue-900 text-gray-300 hover:text-white rounded mr-5 py-2 px-3 font-bold text-sm" onclick="location.href='<%= edit_article_path(@article.slug) %>';"><i data-feather="edit-2" class="inline h-5"></i> EDIT</button>
132
+
133
+ <% if @article.active %>
134
+ <button title="Deactivate article" id="article-deactivate-button" class="bg-yellow-700 text-gray-300 hover:text-white rounded mr-5 py-2 px-3 font-bold text-base" onclick="setArticleStatus('<%= @article.slug %>', false);"><i data-feather="file-minus" class="inline h-5"></i> DEACTIVATE</button>
135
+ <% else %>
136
+ <button title="Re-activate article" id="article-activate-button" class="bg-green-700 text-gray-300 hover:text-white rounded mr-5 py-2 px-3 font-bold text-base" onclick="setArticleStatus('<%= @article.slug %>', true);"><i data-feather="file-plus" class="inline h-5"></i> RE-ACTIVATE</button>
137
+ <% end %>
138
+ <button title="Permanently delete article" class="bg-red-700 text-gray-300 hover:text-white rounded py-2 px-3 font-bold text-base" onclick="deleteArticle('<%= @article.id %>');"><i data-feather="slash" class="inline h-5"></i> DELETE</button>
139
+ </div>
140
+ </div>
138
141
  <% end %>
@@ -10,13 +10,20 @@
10
10
  </div>
11
11
 
12
12
  <% if Dokno::Category.exists? %>
13
- <div class="mb-5">
13
+ <div class="mb-5 w-1/2">
14
14
  <div class="text-lg font-semibold"><label for="parent_category_code">Parent Category</label></div>
15
- <select name="parent_category_code" id="parent_category_code" class="rounded text-xl shadow-inner bg-gray-100 p-2 mt-2 w-1/2 max-w-full">
16
- <option></option>
17
- <%= Dokno::Category.select_option_markup(selected_category_codes: [@parent_category_code], exclude_category_id: category.id).html_safe %>
15
+
16
+ <select name="parent_category_code" id="parent_category_code" size="1" class="rounded text-xl shadow-inner bg-gray-100 p-2 w-full max-w-full">
17
+ <option value="">No Parent Category</option>
18
+
19
+ <optgroup label="Categories">
20
+ <% cache Dokno::Category do %>
21
+ <%= Dokno::Category.select_option_markup.html_safe %>
22
+ <% end %>
23
+ </optgroup>
18
24
  </select>
19
- <div class="text-gray-500 mt-2 w-1/2">
25
+
26
+ <div class="text-gray-500 mt-2">
20
27
  The existing category to which this category belongs.
21
28
  <% if (article_count = category.articles.count).positive? %>
22
29
  There <%= article_count > 1 ? "are #{article_count} articles" : 'is an article' %> currently in this category.
@@ -31,8 +38,12 @@
31
38
  <% if category.persisted? %>
32
39
  <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
40
  <% end %>
34
- <span class="text-lg ml-5"><a class="no-underline" href="<%= category.persisted? ? "#{root_path}?id=#{category.id}" : root_path %>">Cancel</a></span>
41
+ <span class="text-lg ml-5"><a class="no-underline" href="<%= category.persisted? ? "#{dokno.article_index_path(category.code)}" : root_path %>">Cancel</a></span>
35
42
  </div>
36
43
  </section>
37
44
 
38
- <script> elem('input#name').focus(); </script>
45
+ <script>
46
+ // Client-side select of cached select list
47
+ selectOption('parent_category_code', '<%= j @parent_category_code %>');
48
+ elem('input#name').focus();
49
+ </script>
@@ -1,25 +1,33 @@
1
+ <% if !current_page?(up_for_review_path) && (@category.blank? || @search_term.present?) %>
2
+ <div class="text-center m-auto mb-10 w-full max-w-screen-xl">
3
+ <% if @search_term.present? %>
4
+ <div class="text-gray-600 text-2xl uppercase">
5
+ <%= @total_records.positive? ? "#{@total_records} #{'article'.pluralize(@total_records)}" : 'No articles' %>
6
+ found containing the search term
7
+ <div class="text-4xl leading-tight"><span class="font-serif">&ldquo;</span> <%= @search_term %> <span class="font-serif">&rdquo;</span> </div>
8
+ </div>
9
+ <% else %>
10
+ <div class="text-gray-600 text-2xl">
11
+ Browse or search
12
+ <% if (article_count = Dokno::Article.count) > 1 %>
13
+ <%= number_with_delimiter(article_count, delimiter: ',') %> articles in
14
+ <% end %>
15
+ the
16
+ </div>
17
+ <div class="text-gray-800 text-4xl leading-tight uppercase"><%= Dokno.config.app_name %> knowledgebase</div>
18
+ <% end %>
19
+ </div>
20
+ <% end %>
21
+
1
22
  <% if @category&.parent.present? %>
2
23
  <div class="text-gray-500 mb-5">
3
- <div><%= @category.breadcrumb %></div>
24
+ <div><span class="text-gray-500 mr-1">Under</span> <%= @category.breadcrumb(search_term: @search_term, order: @order, hide_self: true) %></div>
4
25
  </div>
5
26
  <% end %>
6
27
 
7
- <div class="flex items-center mb-10">
8
- <% if Dokno::Category.exists? %>
9
- <div class="w-1/2 pr-5">
10
- <select name="category" id="category" size="1" class="rounded text-xl shadow-inner bg-gray-100 p-2 w-full max-w-full" onchange="location.href='<%= article_index_path %>' + this.value + '?search_term=' + elem('#search_term').value + '&order=<%= @order %>';">
11
- <option value="">Select a category</option>
12
- <%= Dokno::Category.select_option_markup(selected_category_codes: [@category&.code]).html_safe %>
13
- </select>
14
- </div>
15
- <% end %>
16
- <div class="w-<%= Dokno::Category.exists? ? '1/2 pl-5' : 'full' %>">
17
- <%= form_with(url: article_index_path(@category&.code), method: :get) do %>
18
- <input type="hidden" name="order" value="<%= @order %>">
19
- <input placeholder="Search article content, titles, and slugs" type="text" name="search_term" id="search_term" value="<%= @search_term %>" class="rounded text-xl shadow-inner bg-gray-100 p-2 w-full" />
20
- <% end %>
21
- </div>
22
- </div>
28
+ <% if !current_page?(up_for_review_path) && (Dokno::Category.exists? || Dokno::Article.exists?) %>
29
+ <%= render 'partials/category_header' %>
30
+ <% end %>
23
31
 
24
32
  <% if @articles.blank? %>
25
33
 
@@ -45,44 +53,55 @@
45
53
  </div>
46
54
  <div class="w-1/3 text-right">
47
55
  <i data-feather="corner-right-down" class="h-5 inline-block" title="Sort order"></i>
48
- <a class="ml-3 pb-1 <%= 'border-b-2 border-blue-900' if @order == 'updated' %>" href="?search_term=<%= CGI.escape @search_term.to_s %>&order=updated">Updated</a>
49
- <a class="ml-3 pb-1 <%= 'border-b-2 border-blue-900' if @order == 'newest' %>" href="?search_term=<%= CGI.escape @search_term.to_s %>&order=newest">Newest</a>
50
- <a class="ml-3 pb-1 <%= 'border-b-2 border-blue-900' if @order == 'views' %>" href="?search_term=<%= CGI.escape @search_term.to_s %>&order=views">Views</a>
51
- <a class="ml-3 pb-1 <%= 'border-b-2 border-blue-900' if @order == 'alpha' %>" href="?search_term=<%= CGI.escape @search_term.to_s %>&order=alpha">Title</a>
56
+ <a id="dokno-order-link-updated" class="ml-3 pb-1 <%= 'border-b-2 border-blue-900' if @order == 'updated' %>" href="?search_term=<%= CGI.escape @search_term.to_s %>&order=updated">Updated</a>
57
+ <a id="dokno-order-link-newest" class="ml-3 pb-1 <%= 'border-b-2 border-blue-900' if @order == 'newest' %>" href="?search_term=<%= CGI.escape @search_term.to_s %>&order=newest">Newest</a>
58
+ <a id="dokno-order-link-views" class="ml-3 pb-1 <%= 'border-b-2 border-blue-900' if @order == 'views' %>" href="?search_term=<%= CGI.escape @search_term.to_s %>&order=views">Views</a>
59
+ <a id="dokno-order-link-alpha" class="ml-3 pb-1 <%= 'border-b-2 border-blue-900' if @order == 'alpha' %>" href="?search_term=<%= CGI.escape @search_term.to_s %>&order=alpha">Title</a>
52
60
  </div>
53
61
  </div>
54
62
 
55
63
  <div id="dokno-article-list">
56
- <% @articles.each_with_index do |article, i| %>
64
+ <% @articles.each do |article| %>
57
65
  <section class="border-t border-gray-300 py-10 text-xl flex">
58
66
  <div class="w-1/3 pr-10">
59
67
  <div class="flex">
60
- <div class="no-print w-10 text-gray-300"><i data-feather="chevron-right" class="inline-block"></i></div>
68
+ <div title="<%= 'Starred article' if article.starred %>" class="no-print w-10 text-gray-300"><i data-feather="<%= article.starred ? 'star' : 'chevron-right' %>" class="inline-block"></i></div>
61
69
  <div class="w-full">
62
- <a class="" href="<%= article_path article.slug %>?search_term=<%= @search_term %>" title="View article"><%= article.title %></a>
70
+ <a class="dokno-article-title <% unless article.active %>text-gray-500 italic<% end %>" href="<%= article_path article.slug %>?search_term=<%= @search_term %>&cat_code=<%= @category&.code %>&order=<%= @order %>" title="View article"><%= article.title %></a>
63
71
  </div>
64
72
  </div>
65
73
  </div>
66
74
  <div class="dokno-article-summary w-2/3 <% unless article.active %>text-gray-500 italic<% end %>">
67
- <% unless article.active %>
68
- <div class="bg-yellow-700 p-4 mb-5 rounded text-lg border-t-4 border-yellow-900 text-white font-base not-italic">
69
- <i data-feather="alert-circle" class="inline-block"></i> This article is no longer active
75
+ <div class="dokno-article-content-highlight mb-2"><%= article.summary.presence || 'No summary provided' %></div>
76
+
77
+ <div class="text-base text-gray-500">
78
+ <%= article.category_name_list(context_category_id: @category&.id, order: @order, search_term: @search_term) %>
79
+ </div>
80
+
81
+ <% unless @order == 'alpha' %>
82
+ <div class="text-base">
83
+ <% if @order == 'views' %>
84
+ <div class="text-gray-500">This article was viewed <%= number_with_delimiter(article.views, delimiter: ',') %> <%= 'time'.pluralize(article.views) %></div>
85
+ <% elsif @order == 'updated' %>
86
+ <div class="text-gray-500">This article was last updated <%= time_ago_in_words article.updated_at %> ago</div>
87
+ <% elsif @order == 'newest' %>
88
+ <div class="text-gray-500">This article was added <%= time_ago_in_words article.created_at %> ago</div>
89
+ <% end %>
70
90
  </div>
71
91
  <% end %>
72
92
 
73
- <span class="dokno-article-content-highlight"><%= article.summary.presence || 'No summary provided' %></span>
93
+ <% if !article.active %>
94
+ <div class="bg-yellow-700 p-4 mt-5 rounded text-lg border-t-4 border-yellow-900 text-white font-base not-italic">
95
+ <i data-feather="info" class="inline-block mr-1"></i> This article is no longer active
96
+ </div>
97
+ <% end %>
74
98
 
75
- <div class="text-base mt-2">
76
- <div class="text-gray-500"><%= article.category_name_list(context_category_id: @category&.id, order: @order, search_term: @search_term) %></div>
99
+ <% if article.up_for_review? %>
100
+ <div class="bg-<%= article.review_due_days.negative? ? 'red' : 'gray' %>-800 p-4 mt-5 rounded text-lg border-t-4 border-<%= article.review_due_days.negative? ? 'red' : 'gray' %>-900 text-white font-base not-italic">
101
+ <i data-feather="bell" class="inline-block mr-1"></i> <%= article.review_due_days_string %>
102
+ </div>
103
+ <% end %>
77
104
 
78
- <% if @order == 'views' %>
79
- <div class="text-gray-500">Viewed <%= number_with_delimiter(article.views, delimiter: ',') %> <%= 'time'.pluralize(article.views) %></div>
80
- <% elsif @order == 'updated' %>
81
- <div class="text-gray-500">Last updated <%= time_ago_in_words article.updated_at %> ago</div>
82
- <% elsif @order == 'newest' %>
83
- <div class="text-gray-500">Added <%= time_ago_in_words article.created_at %> ago</div>
84
- <% end %>
85
- </div>
86
105
  </div>
87
106
  </section>
88
107
  <% end %>
@@ -96,6 +115,6 @@
96
115
  </div>
97
116
  <% end %>
98
117
 
99
- <% if @search_term.present? %>
100
- <script>highlightTerm(['<%= j @search_term.strip %>'], 'dokno-article-content-highlight');</script>
118
+ <% if @search_term.present? && @articles.blank? %>
119
+ <script> handleSearchHotKey(); </script>
101
120
  <% end %>
@@ -2,6 +2,8 @@
2
2
  <html>
3
3
  <head>
4
4
  <title><%= Dokno.config.app_name %> KNOWLEDGEBASE</title>
5
+
6
+ <meta name="viewport" content="width=device-width,initial-scale=1">
5
7
  <%= csrf_meta_tags %>
6
8
  <%= csp_meta_tag %>
7
9
 
@@ -12,7 +14,8 @@
12
14
  var dokno__base_path = '<%= root_path %>';
13
15
  </script>
14
16
  </head>
15
- <body class="bg-white font-sans font-light subpixel-antialiased">
17
+ <body class="bg-white font-sans font-light subpixel-antialiased text-lg">
18
+
16
19
 
17
20
  <nav id="dokno-nav-container" class="bg-blue-900 text-white py-10 px-16 text-lg">
18
21
  <div class="flex items-center m-auto w-full max-w-screen-xl">
@@ -24,12 +27,12 @@
24
27
  <div class="w-2/3 text-right">
25
28
  <% if can_edit? %>
26
29
  <% if action_name != 'new' %>
27
- <button title="Add a new article" class="bg-gray-700 text-gray-300 hover:text-white hover:bg-gray-900 rounded ml-3 py-2 px-3 font-bold text-base" onclick="location.href='<%= new_article_path %>/?category_code=<%= @category&.code %>';"><i data-feather="plus-circle" class="inline h-5"></i> ARTICLE</button>
28
- <button title="Add a new category" class="bg-gray-700 text-gray-300 hover:text-white hover:bg-gray-900 rounded ml-3 py-2 px-3 font-bold text-base" onclick="location.href='<%= new_category_path %>/?parent_category_code=<%= @category&.code %>';"><i data-feather="plus-circle" class="inline h-5"></i> CATEGORY</button>
30
+ <button title="Add a new article" class="bg-gray-700 text-gray-300 hover:text-white hover:bg-gray-900 rounded ml-3 py-2 px-3 font-bold text-base" onclick="location.href='<%= new_article_path %>/?category_code=<%= @category&.code %>';"><i data-feather="plus" class="inline h-5"></i> ARTICLE</button>
31
+ <button title="Add a new category" class="bg-gray-700 text-gray-300 hover:text-white hover:bg-gray-900 rounded ml-3 py-2 px-3 font-bold text-base" onclick="location.href='<%= new_category_path %>/?parent_category_code=<%= @category&.code %>';"><i data-feather="plus" class="inline h-5"></i> CATEGORY</button>
29
32
  <% end %>
30
33
 
31
34
  <% if @category&.persisted? && action_name != 'edit' %>
32
- <button title="Edit this category" class="bg-gray-700 text-gray-100 hover:text-white hover:bg-gray-900 rounded ml-3 py-2 px-3 font-bold text-base" onclick="location.href='<%= edit_category_path(@category) %>';"><i data-feather="edit" class="inline h-5"></i> CATEGORY</button>
35
+ <button title="Edit this category" class="bg-gray-700 text-gray-100 hover:text-white hover:bg-gray-900 rounded ml-3 py-2 px-3 font-bold text-base" onclick="location.href='<%= edit_category_path(@category) %>';"><i data-feather="edit-2" class="inline h-5"></i> CATEGORY</button>
33
36
  <% end %>
34
37
  <% end %>
35
38
 
@@ -40,52 +43,47 @@
40
43
  </div>
41
44
  </nav>
42
45
 
43
- <main class="py-10 px-16">
44
- <% if @article.blank? && (@category.blank? || @search_term.present?) %>
45
- <div class="text-center m-auto mb-10 w-full max-w-screen-xl">
46
- <% if @search_term.present? %>
47
- <div class="text-gray-600 text-2xl uppercase">
48
- <%= (article_count = @articles.count).positive? ? "#{article_count} #{'article'.pluralize(article_count)}" : 'No articles' %>
49
- found containing the search term
50
- <div class="text-4xl leading-tight"><span class="font-serif">&ldquo;</span> <%= @search_term %> <span class="font-serif">&rdquo;</span> </div>
51
- </div>
52
- <% else %>
53
- <div class="text-gray-600 text-2xl">
54
- Browse or search
55
- <% if (article_count = Dokno::Article.count) > 1 %>
56
- <%= number_with_delimiter(article_count, delimiter: ',') %> articles in
57
- <% end %>
58
- the
59
- </div>
60
- <div class="text-gray-800 text-4xl leading-tight uppercase"><%= Dokno.config.app_name %> knowledgebase</div>
61
- <% end %>
62
- </div>
63
- <% end %>
64
46
 
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 %>
47
+ <% flash.each do |type, msg| %>
48
+ <div class="bg-<%= type %>-800 text-lg text-white font-base py-10 px-16 text-center">
49
+ <i data-feather="<%= (type == 'green' ? 'smile' : (type == 'yellow' ? 'info' : (type == 'gray' ? 'bell' : 'frown'))) %>" class="inline mr-1"></i>
50
+ <%= sanitize(msg, tags: %w[a], attributes: %w[href class]) %>
51
+ </div>
52
+ <% end %>
72
53
 
54
+
55
+ <main class="py-10 px-16">
56
+ <div id="dokno-content-container" class="w-full max-w-screen-xl m-auto print-this">
73
57
  <%= yield %>
74
58
  </div>
75
59
  </main>
76
60
 
61
+
77
62
  <footer id="dokno-footer-container">
78
63
  <% if @article.present? && action_name == 'show' %>
79
- <div id="dokno-article-log-container" data-category-id="<%= @category&.id %>" data-article-id="<%= @article&.id %>">
64
+ <div id="dokno-article-log-container" data-category-id="<%= @category&.id %>" data-article-id="<%= @article.id %>">
80
65
  <%= render 'partials/logs', category: @category, article: @article %>
81
66
  </div>
82
67
  <% end %>
83
68
 
69
+ <% if @show_up_for_review && (up_for_review_count = Dokno::Article.up_for_review.count).positive? %>
70
+ <div id="dokno-articles-up-for-review-container">
71
+ <div class="py-10 px-16 bg-gray-900">
72
+ <div class="w-full max-w-screen-xl m-auto">
73
+ <div class="text-xl text-white cursor-pointer" onclick="location.href='<%= up_for_review_path %>';">
74
+ <i data-feather="bell" class="inline mr-1"></i>
75
+ There <%= "#{up_for_review_count == 1 ? 'is' : 'are'} #{up_for_review_count}" %> <%= 'article'.pluralize(up_for_review_count) %> up for accuracy / relevance review
76
+ </div>
77
+ </div>
78
+ </div>
79
+ </div>
80
+ <% end %>
84
81
 
85
82
  <div class="py-10 px-16 text-gray-400 bg-blue-900">
86
83
  <div class="w-full max-w-screen-xl m-auto flex">
87
84
  <div class="w-1/2">
88
- <a target="_blank" href="https://github.com/cpayne624/dokno" title="Knowledgebase">dokno</a>
85
+ <i data-feather="github" class="inline mr-1"></i>
86
+ <a target="_blank" href="https://github.com/cpayne624/dokno" title="Dokno on GitHub">dokno</a>
89
87
  </div>
90
88
  <div class="w-1/2 text-right">
91
89
  <% if user.present? %>
@@ -99,9 +97,12 @@
99
97
  </div>
100
98
  </div>
101
99
  </div>
102
-
103
100
  </footer>
104
101
 
105
102
  <%= javascript_include_tag 'init' %>
103
+
104
+ <% if @search_term.present? %>
105
+ <script> highlightTerm(['<%= j @search_term.strip %>'], 'dokno-article-content-highlight'); </script>
106
+ <% end %>
106
107
  </body>
107
108
  </html>