dokno 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.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +130 -0
  4. data/Rakefile +22 -0
  5. data/app/assets/config/dokno_manifest.js +3 -0
  6. data/app/assets/javascripts/dokno.js +144 -0
  7. data/app/assets/javascripts/dokno/application.js +15 -0
  8. data/app/assets/javascripts/feather.min.js +13 -0
  9. data/app/assets/javascripts/init.js +5 -0
  10. data/app/assets/stylesheets/dokno/application.css +137 -0
  11. data/app/assets/stylesheets/dokno/tailwind.min.css +1 -0
  12. data/app/controllers/dokno/application_controller.rb +7 -0
  13. data/app/controllers/dokno/articles_controller.rb +115 -0
  14. data/app/controllers/dokno/categories_controller.rb +63 -0
  15. data/app/controllers/dokno/pagination_concern.rb +15 -0
  16. data/app/controllers/dokno/user_concern.rb +38 -0
  17. data/app/helpers/dokno/application_helper.rb +17 -0
  18. data/app/models/dokno/application_record.rb +5 -0
  19. data/app/models/dokno/article.rb +215 -0
  20. data/app/models/dokno/article_slug.rb +7 -0
  21. data/app/models/dokno/category.rb +100 -0
  22. data/app/models/dokno/log.rb +7 -0
  23. data/app/views/dokno/_article_formatting.html.erb +89 -0
  24. data/app/views/dokno/_article_panel.html.erb +112 -0
  25. data/app/views/dokno/_panel_formatting.html.erb +95 -0
  26. data/app/views/dokno/_reset_formatting.html.erb +55 -0
  27. data/app/views/dokno/articles/_article_form.html.erb +60 -0
  28. data/app/views/dokno/articles/edit.html.erb +7 -0
  29. data/app/views/dokno/articles/new.html.erb +7 -0
  30. data/app/views/dokno/articles/show.html.erb +130 -0
  31. data/app/views/dokno/categories/_category_form.html.erb +33 -0
  32. data/app/views/dokno/categories/edit.html.erb +7 -0
  33. data/app/views/dokno/categories/index.html.erb +96 -0
  34. data/app/views/dokno/categories/new.html.erb +7 -0
  35. data/app/views/layouts/dokno/application.html.erb +100 -0
  36. data/app/views/partials/_form_errors.html.erb +18 -0
  37. data/app/views/partials/_logs.html.erb +52 -0
  38. data/app/views/partials/_pagination.html.erb +35 -0
  39. data/config/routes.rb +11 -0
  40. data/db/migrate/20201203190330_baseline.rb +62 -0
  41. data/lib/dokno.rb +4 -0
  42. data/lib/dokno/config/config.rb +73 -0
  43. data/lib/dokno/engine.rb +27 -0
  44. data/lib/dokno/version.rb +3 -0
  45. data/lib/generators/dokno/install/install_generator.rb +13 -0
  46. data/lib/generators/dokno/templates/config/dokno_template.md +5 -0
  47. data/lib/generators/dokno/templates/config/initializers/dokno.rb +14 -0
  48. data/lib/tasks/dokno_tasks.rake +4 -0
  49. metadata +253 -0
@@ -0,0 +1,60 @@
1
+ <%= render 'dokno/article_formatting' %>
2
+
3
+ <section class="mb-10">
4
+
5
+ <div class="text-2xl mb-5 text-gray-500"><%= article.persisted? ? 'Edit' : 'New' %> Article</div>
6
+ <h1 class="text-4xl mb-5 leading-tight font-light"><%= article.title %></h1>
7
+ <hr class="mb-5" />
8
+
9
+ <div class="mb-5">
10
+ <div class="text-lg font-semibold"><label for="slug">Slug</label></div>
11
+ <input placeholder="Article unique identifier" type="text" name="slug" id="slug" value="<%= article.slug %>" class="rounded text-xl shadow-inner bg-gray-100 p-2 mt-2 w-1/3" />
12
+ <div class="text-gray-500 mt-2">Unique identifier for this article (required) (2-20 alphanumeric chars)</div>
13
+ </div>
14
+
15
+ <% if Dokno::Category.exists? %>
16
+ <div class="mb-5">
17
+ <div class="text-lg font-semibold"><label for="category_id"><%= 'Category'.pluralize article.categories.count %></label></div>
18
+ <select name="category_code[]" id="category_code" multiple="multiple" size="<%= (cat_count = Dokno::Category.count) <= 4 ? (cat_count + 1).to_s : '5' %>" class="rounded text-xl shadow-inner bg-gray-100 p-2 w-full mt-2 w-full max-w-full">
19
+ <option></option>
20
+ <%= Dokno::Category.select_option_markup(selected_category_codes: @category_codes).html_safe %>
21
+ </select>
22
+ <div class="text-gray-500 mt-2">
23
+ If applicable, select one or more categories to which this article will belong (optional). CTRL/CMD to select multiple.
24
+ Articles will be automatically included in parent categories. Uncategorized articles
25
+ are displayed on the landing page.
26
+ </div>
27
+ </div>
28
+ <% end %>
29
+
30
+ <hr class="mb-5" />
31
+
32
+ <div class="mb-5">
33
+ <div class="text-lg font-semibold"><label for="title">Title</label></div>
34
+ <input placeholder="Article title" type="text" name="title" id="title" value="<%= article.title %>" class="rounded text-xl shadow-inner bg-gray-100 p-2 mt-2 w-1/2" />
35
+ <div class="text-gray-500 mt-2">Descriptive article title (required) (5-255 alphanumeric chars)</div>
36
+ </div>
37
+
38
+ <div class="mb-5">
39
+ <div class="text-lg font-semibold"><label for="summary">Summary</label></div>
40
+ <input placeholder="Brief article summary" type="text" name="summary" id="summary" value="<%= article.summary %>" class="rounded text-xl shadow-inner bg-gray-100 p-2 mt-2 w-full" />
41
+ <div class="text-gray-500 mt-2">Brief summary of the described topic (text only)</div>
42
+ </div>
43
+
44
+ <div class="mb-5">
45
+ <div class="text-lg font-semibold">
46
+ <label for="markdown">Content</label>
47
+ <a id="markdown_write_link" href="javascript:;" onclick="writeArticleToggle();" class="float-right hidden"><i data-feather="pen-tool" class="inline"></i> Write</a>
48
+ <a id="markdown_preview_link" href="javascript:;" onclick="previewArticleToggle();" class="float-right"><i data-feather="eye" class="inline"></i> Preview</a>
49
+ </div>
50
+ <textarea placeholder="Full article content" name="markdown" id="markdown" class="rounded text-xl shadow-inner bg-gray-100 p-3 mt-2 w-full" rows="10"><%= article.persisted? ? article.markdown : (article.markdown.presence || @template) %></textarea>
51
+ <div id="markdown_preview" class="dokno-article-content-markup hidden text-lg overflow-hidden overflow-y-auto rounded p-10 mt-2 bg-gray-100 shadow-inner"></div>
52
+ <div class="text-gray-500 mt-2">Detailed documentation of the described topic. Basic HTML &amp; <a target="_blank" href="https://commonmark.org/help/" title="Markdown formatting examples">markdown</a> OK.</div>
53
+ </div>
54
+
55
+ <div class="mt-10">
56
+ <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 ARTICLE</button>
57
+ <span class="text-lg ml-5"><a class="no-underline" href="<%= article.persisted? ? article_path(article.slug) : root_path %>">Cancel</a></span>
58
+ </div>
59
+
60
+ </section>
@@ -0,0 +1,7 @@
1
+ <%= form_with(model: @article, local: true) do |form| %>
2
+ <% if @article.errors.any? %>
3
+ <%= render 'partials/form_errors', errors: @article.errors %>
4
+ <% end %>
5
+
6
+ <%= render 'article_form', article: @article %>
7
+ <% end %>
@@ -0,0 +1,7 @@
1
+ <%= form_with(url: articles_path) do %>
2
+ <% if @article.errors.any? %>
3
+ <%= render 'partials/form_errors', errors: @article.errors %>
4
+ <% end %>
5
+
6
+ <%= render 'article_form', article: @article %>
7
+ <% end %>
@@ -0,0 +1,130 @@
1
+ <%= render 'dokno/article_formatting' %>
2
+
3
+ <section>
4
+ <div class="flex">
5
+ <div id="dokno-article-sidebar" class="w-2/5 pr-10">
6
+ <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">
7
+ <i data-feather="alert-circle" class="inline-block mr-2"></i> This article is no longer active
8
+ </div>
9
+
10
+ <h1 class="dokno-article-content-highlight text-4xl mb-10 leading-tight font-light"><%= @article.title %></h1>
11
+
12
+ <div>
13
+ <div class="mb-10 no-print">
14
+ <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>
15
+ <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>
16
+
17
+ <% if can_edit? %>
18
+ <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>
19
+ <% end %>
20
+ </div>
21
+
22
+ <div class="flex">
23
+ <div class="no-print w-8"><i data-feather="clock" class="inline-block h-5"></i></div>
24
+ <div class="w-full">
25
+ Last updated:<br />
26
+ <%= time_ago_in_words @article.updated_at %> ago
27
+ <% if (editor_username = @article.logs.first&.username).present? %>
28
+ by <%= editor_username %>
29
+ <% end %>
30
+ </div>
31
+ </div>
32
+
33
+ <div class="mt-5 flex">
34
+ <div class="no-print w-8"><i data-feather="eye" class="inline-block h-5"></i></div>
35
+ <div class="w-full">
36
+ Views:<br />
37
+ <%= number_with_delimiter(@article.views, delimiter: ',') %>
38
+ </div>
39
+ </div>
40
+
41
+ <% if @article.contributors.present? %>
42
+ <div class="mt-5 flex">
43
+ <div class="no-print w-8"><i data-feather="user-check" class="inline-block h-5"></i></div>
44
+ <div class="w-full">
45
+ Contributors:<br />
46
+ <%= @article.contributors %>
47
+ </div>
48
+ </div>
49
+ <% end %>
50
+
51
+ <% if @article.reading_time.present? %>
52
+ <div class="mt-5 flex">
53
+ <div class="no-print w-8"><i data-feather="watch" class="inline-block h-5"></i></div>
54
+ <div class="w-full">
55
+ Reading time:<br />
56
+ <%= @article.reading_time %>
57
+ </div>
58
+ </div>
59
+ <% end %>
60
+
61
+ <div class="mt-5 flex">
62
+ <div class="no-print w-8"><i data-feather="link" class="inline-block h-5"></i></div>
63
+ <div class="w-full">
64
+ Permalink:<br />
65
+ <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>
66
+ </div>
67
+ </div>
68
+
69
+ <% if can_edit? %>
70
+ <div class="mt-5 flex">
71
+ <div class="no-print w-8"><i data-feather="crosshair" class="inline-block h-5"></i></div>
72
+ <div class="w-full">
73
+ Unique slug:<br />
74
+ <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>
75
+
76
+ <% if (old_slugs = @article.article_slugs).present? %>
77
+ <div class="text-gray-500 mt-5">
78
+ Editor note:<br />
79
+ This article is still accessible via previous
80
+ <%= 'slug'.pluralize(old_slugs.count) %>
81
+ <%= old_slugs.map(&:slug).reject { |slug| slug == @article.slug }.to_sentence %>
82
+ </div>
83
+ <% end %>
84
+ </div>
85
+ </div>
86
+ <% end %>
87
+
88
+ <% if @article.categories.exists? %>
89
+ <div class="mt-5 flex">
90
+ <div class="no-print w-8"><i data-feather="folder" class="inline-block h-5"></i></div>
91
+ <div class="w-full">
92
+ <%= 'Category'.pluralize @article.categories.count %>:<br />
93
+ <%= @article.category_name_list.split(':').last.html_safe %>
94
+ </div>
95
+ </div>
96
+ <% end %>
97
+ </div>
98
+ </div>
99
+ <div id="dokno-article-content" class="dokno-article-content-highlight w-3/5">
100
+ <% if @article.summary.present? %>
101
+ <div class="text-2xl mb-8 text-gray-700 font-light"><%= simple_format @article.summary %></div>
102
+ <% end %>
103
+
104
+ <% if @article.markdown.present? %>
105
+ <div id="dokno-article-content-markup" class="dokno-article-content-markup text-gray-800 font-light mb-10 bg-gray-100 p-10 rounded">
106
+ <%= @article.markdown_parsed %>
107
+ </div>
108
+ <% end %>
109
+
110
+ <% if @article.summary.blank? && @article.markdown.blank? %>
111
+ <div class="mb-10">No content</div>
112
+ <% end %>
113
+
114
+ <% if can_edit? %>
115
+ <div class="no-print">
116
+ <hr class="mt-5" />
117
+ <div class="mt-10 text-right">
118
+ <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>
119
+ <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>
120
+ <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>
121
+ </div>
122
+ </div>
123
+ <% end %>
124
+ </div>
125
+ </div>
126
+ </section>
127
+
128
+ <% if @search_term.present? %>
129
+ <script>highlightTerm(['<%= j @search_term.strip %>'], 'dokno-article-content-highlight');</script>
130
+ <% end %>
@@ -0,0 +1,33 @@
1
+ <section class="mb-10">
2
+
3
+ <div class="text-2xl mb-5 text-gray-500"><%= category.persisted? ? 'Edit' : 'New' %> Category</div>
4
+ <hr class="mb-5" />
5
+
6
+ <div class="mb-5">
7
+ <div class="text-lg font-semibold"><label for="name">Category Name</label></div>
8
+ <input type="text" name="name" id="name" value="<%= category.name %>" class="rounded text-xl shadow-inner bg-gray-100 p-2 mt-2 w-1/3" />
9
+ <div class="text-gray-500 mt-2">Unique name for this category (required)</div>
10
+ </div>
11
+
12
+ <% if Dokno::Category.exists? %>
13
+ <div class="mb-5">
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 %>
18
+ </select>
19
+ <div class="text-gray-500 mt-2 w-1/2">
20
+ The existing category to which this category belongs.
21
+ <% if (article_count = category.articles.count).positive? %>
22
+ There <%= article_count > 1 ? "are #{article_count} articles" : 'is an article' %> currently in this category.
23
+ Changing the parent category will move <%= article_count > 1 ? 'them' : 'it' %> as well.
24
+ <% end %>
25
+ </div>
26
+ </div>
27
+ <% end %>
28
+
29
+ <div class="mt-10">
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
+ <span class="text-lg ml-5"><a class="no-underline" href="<%= category.persisted? ? "#{root_path}?id=#{category.id}" : root_path %>">Cancel</a></span>
32
+ </div>
33
+ </section>
@@ -0,0 +1,7 @@
1
+ <%= form_with(model: @category, local: true) do |form| %>
2
+ <% if @category.errors.any? %>
3
+ <%= render 'partials/form_errors', errors: @category.errors %>
4
+ <% end %>
5
+
6
+ <%= render 'category_form', category: @category %>
7
+ <% end %>
@@ -0,0 +1,96 @@
1
+
2
+ <div class="flex items-center mb-10">
3
+ <% if Dokno::Category.exists? %>
4
+ <div class="w-1/2 pr-5">
5
+ <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 %>';">
6
+ <option value="">Select a category</option>
7
+ <%= Dokno::Category.select_option_markup(selected_category_codes: [@category&.code]).html_safe %>
8
+ </select>
9
+ </div>
10
+ <% end %>
11
+ <div class="w-<%= Dokno::Category.exists? ? '1/2 pl-5' : 'full' %>">
12
+ <%= form_with(url: article_index_path(@category&.code), method: :get) do %>
13
+ <input type="hidden" name="order" value="<%= @order %>">
14
+ <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" />
15
+ <% end %>
16
+ </div>
17
+ </div>
18
+
19
+ <% if @articles.blank? %>
20
+
21
+ <section class="border-t border-gray-300 py-10 text-xl">
22
+ <% if Dokno::Category.exists? %>
23
+ <% if @search_term.present? %>
24
+ No articles found <% if @category.present? %>in this category<% end %> matching the given search criteria
25
+ <% elsif @category.present? %>
26
+ No articles found in this category
27
+ <% else %>
28
+ No uncategorized articles
29
+ <% end %>
30
+ <% elsif can_edit? %>
31
+ <a href="<%= new_category_path(@category&.id) %>">Add your first category</a>
32
+ <% end %>
33
+ </section>
34
+
35
+ <% else %>
36
+
37
+ <div id="dokno-article-list-controls-top" class="flex mb-10">
38
+ <div class="w-2/3">
39
+ <%= render 'partials/pagination' %>
40
+ </div>
41
+ <div class="w-1/3 text-right">
42
+ <i data-feather="corner-right-down" class="h-5 inline-block" title="Sort order"></i>
43
+ <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>
44
+ <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>
45
+ <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>
46
+ <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>
47
+ </div>
48
+ </div>
49
+
50
+ <div id="dokno-article-list">
51
+ <% @articles.each_with_index do |article, i| %>
52
+ <section class="border-t border-gray-300 py-10 text-xl flex">
53
+ <div class="w-1/3 pr-10">
54
+ <div class="flex">
55
+ <div class="no-print w-10 text-gray-300"><i data-feather="chevron-right" class="inline-block"></i></div>
56
+ <div class="w-full">
57
+ <a class="" href="<%= article_path article.slug %>?search_term=<%= @search_term %>" title="View article"><%= article.title %></a>
58
+ </div>
59
+ </div>
60
+ </div>
61
+ <div class="dokno-article-summary w-2/3 <% unless article.active %>text-gray-500 italic<% end %>">
62
+ <% unless article.active %>
63
+ <div class="bg-yellow-700 p-4 mb-5 rounded text-lg border-t-4 border-yellow-900 text-white font-base not-italic">
64
+ <i data-feather="alert-circle" class="inline-block"></i> This article is no longer active
65
+ </div>
66
+ <% end %>
67
+
68
+ <span class="dokno-article-content-highlight"><%= article.summary.presence || 'No summary provided' %></span>
69
+
70
+ <div class="text-base mt-2">
71
+ <div class="text-gray-500"><%= article.category_name_list(context_category_id: @category&.id, order: @order, search_term: @search_term) %></div>
72
+
73
+ <% if @order == 'views' %>
74
+ <div class="text-gray-500">Viewed <%= number_with_delimiter(article.views, delimiter: ',') %> <%= 'time'.pluralize(article.views) %></div>
75
+ <% elsif @order == 'updated' %>
76
+ <div class="text-gray-500">Last updated <%= time_ago_in_words article.updated_at %> ago</div>
77
+ <% elsif @order == 'newest' %>
78
+ <div class="text-gray-500">Added <%= time_ago_in_words article.created_at %> ago</div>
79
+ <% end %>
80
+ </div>
81
+ </div>
82
+ </section>
83
+ <% end %>
84
+ </div>
85
+
86
+ <div id="dokno-article-list-controls-bottom" class="flex mt-10">
87
+ <div class="w-2/3">
88
+ <%= render 'partials/pagination' %>
89
+ </div>
90
+ <div class="w-1/3 text-right"></div>
91
+ </div>
92
+ <% end %>
93
+
94
+ <% if @search_term.present? %>
95
+ <script>highlightTerm(['<%= j @search_term.strip %>'], 'dokno-article-content-highlight');</script>
96
+ <% end %>
@@ -0,0 +1,7 @@
1
+ <%= form_with(url: categories_path) do %>
2
+ <% if @category.errors.any? %>
3
+ <%= render 'partials/form_errors', errors: @category.errors %>
4
+ <% end %>
5
+
6
+ <%= render 'category_form', category: @category %>
7
+ <% end %>
@@ -0,0 +1,100 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= Dokno.config.app_name %> KNOWLEDGEBASE</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= stylesheet_link_tag "dokno/application", media: "all" %>
9
+ <%= javascript_include_tag 'dokno/application' %>
10
+
11
+ <script>
12
+ var dokno__base_path = '<%= root_path %>';
13
+ </script>
14
+ </head>
15
+ <body class="bg-white font-sans font-light subpixel-antialiased">
16
+
17
+ <nav id="dokno-nav-container" class="bg-blue-900 text-white py-10 px-16 text-lg">
18
+ <div class="flex items-center m-auto w-full max-w-screen-xl">
19
+ <div class="w-1/3">
20
+ <a href="<%= root_path %>">
21
+ <span class="font-semibold uppercase"><%= Dokno.config.app_name %> KNOWLEDGEBASE</span>
22
+ </a>
23
+ </div>
24
+ <div class="w-2/3 text-right">
25
+ <% if can_edit? %>
26
+ <% 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>
29
+ <% end %>
30
+
31
+ <% 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>
33
+ <% end %>
34
+ <% end %>
35
+
36
+ <% if action_name != 'edit' %>
37
+ <button class="bg-green-700 text-gray-300 hover:text-white hover:bg-green-800 rounded ml-3 py-2 px-3 font-bold text-base" onclick="window.open('/');"><i data-feather="log-out" class="inline h-5"></i> GO TO APP</button>
38
+ <% end %>
39
+ </div>
40
+ </div>
41
+ </nav>
42
+
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
+
65
+ <div id="dokno-content-container" class="w-full max-w-screen-xl m-auto print-this">
66
+ <%= yield %>
67
+ </div>
68
+ </main>
69
+
70
+ <footer id="dokno-footer-container">
71
+ <% if @article.present? && action_name == 'show' %>
72
+ <div id="dokno-article-log-container" data-category-id="<%= @category&.id %>" data-article-id="<%= @article&.id %>">
73
+ <%= render 'partials/logs', category: @category, article: @article %>
74
+ </div>
75
+ <% end %>
76
+
77
+
78
+ <div class="py-10 px-16 text-gray-400 bg-blue-900">
79
+ <div class="w-full max-w-screen-xl m-auto flex">
80
+ <div class="w-1/2">
81
+ <a target="_blank" href="https://github.com/cpayne624/dokno" title="Knowledgebase">dokno</a>
82
+ </div>
83
+ <div class="w-1/2 text-right">
84
+ <% if user.present? %>
85
+ <span title="<%= Dokno.config.app_name %> Authenticated User" class="mr-10">
86
+ <i data-feather="user<%= '-check' if can_edit? %>" class="inline-block h-5"></i> <span class="text-white"><%= username %></span>
87
+ (<%= can_edit? ? 'Editor' : 'Read Only' %>)
88
+ </span>
89
+ <% end %>
90
+
91
+ <a href="/" target="_blank" title="Go to the app" class="font-semibold"><%= Dokno.config.app_name %></a>
92
+ </div>
93
+ </div>
94
+ </div>
95
+
96
+ </footer>
97
+
98
+ <%= javascript_include_tag 'init' %>
99
+ </body>
100
+ </html>