dokno 1.1.1 → 1.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -6
- data/app/assets/javascripts/dokno.js +48 -37
- data/app/assets/stylesheets/dokno/application.css +1 -1
- data/app/controllers/dokno/application_controller.rb +1 -1
- data/app/controllers/dokno/articles_controller.rb +19 -11
- data/app/controllers/dokno/categories_controller.rb +10 -7
- data/app/controllers/dokno/pagination_concern.rb +5 -5
- data/app/controllers/dokno/user_concern.rb +6 -4
- data/app/helpers/dokno/application_helper.rb +1 -1
- data/app/models/dokno/application_record.rb +3 -0
- data/app/models/dokno/article.rb +91 -42
- data/app/models/dokno/category.rb +20 -46
- data/app/views/dokno/_article_formatting.html.erb +12 -12
- data/app/views/dokno/articles/_article_form.html.erb +49 -10
- data/app/views/dokno/articles/show.html.erb +44 -41
- data/app/views/dokno/categories/_category_form.html.erb +17 -6
- data/app/views/dokno/categories/index.html.erb +54 -41
- data/app/views/layouts/dokno/application.html.erb +36 -33
- data/app/views/partials/_category_header.html.erb +30 -0
- data/app/views/partials/_form_errors.html.erb +0 -1
- data/app/views/partials/_logs.html.erb +7 -5
- data/app/views/partials/_pagination.html.erb +20 -17
- data/config/routes.rb +1 -1
- data/db/migrate/20201203190330_baseline.rb +4 -4
- data/db/migrate/20201211192306_add_review_due_at_to_articles.rb +6 -0
- data/db/migrate/20201213165700_add_starred_to_article.rb +5 -0
- data/lib/dokno/config/config.rb +53 -40
- data/lib/dokno/engine.rb +5 -5
- data/lib/dokno/version.rb +1 -1
- data/lib/generators/dokno/templates/config/initializers/dokno.rb +18 -5
- metadata +82 -11
@@ -1,41 +1,33 @@
|
|
1
1
|
module Dokno
|
2
2
|
class Category < ApplicationRecord
|
3
|
-
belongs_to :parent,
|
4
|
-
|
5
|
-
primary_key: 'id',
|
6
|
-
foreign_key: 'category_id',
|
7
|
-
optional: true,
|
8
|
-
inverse_of: :children
|
9
|
-
has_many :children,
|
10
|
-
class_name: 'Dokno::Category',
|
11
|
-
primary_key: 'id',
|
12
|
-
foreign_key: 'category_id',
|
13
|
-
dependent: :nullify,
|
14
|
-
inverse_of: :parent
|
3
|
+
belongs_to :parent, class_name: 'Dokno::Category', primary_key: 'id', foreign_key: 'category_id', inverse_of: :children, optional: true
|
4
|
+
has_many :children, class_name: 'Dokno::Category', primary_key: 'id', foreign_key: 'category_id', inverse_of: :parent, dependent: :nullify
|
15
5
|
|
16
6
|
has_and_belongs_to_many :articles
|
17
7
|
|
8
|
+
before_validation :set_code
|
18
9
|
validates :name, :code, presence: true, uniqueness: true
|
19
10
|
validate :circular_parent_check
|
20
11
|
|
21
|
-
before_validation :set_code
|
22
|
-
|
23
12
|
scope :alpha_order, -> { order(:name) }
|
24
13
|
|
25
|
-
|
26
|
-
|
27
|
-
crumbs = [name]
|
14
|
+
def breadcrumb(**args)
|
15
|
+
crumbs = [(category_link(self, args) unless args[:hide_self])]
|
28
16
|
parent_category_id = category_id
|
29
17
|
|
30
18
|
loop do
|
31
19
|
break if parent_category_id.blank?
|
32
20
|
|
33
|
-
parent_category =
|
34
|
-
crumbs.prepend parent_category
|
21
|
+
parent_category = Category.find(parent_category_id)
|
22
|
+
crumbs.prepend category_link(parent_category, args)
|
35
23
|
parent_category_id = parent_category.category_id
|
36
24
|
end
|
37
25
|
|
38
|
-
crumbs.join(
|
26
|
+
crumbs.compact.join(" > ").html_safe
|
27
|
+
end
|
28
|
+
|
29
|
+
def category_link(category, args={})
|
30
|
+
%(<a href="#{article_index_path(category.code)}?search_term=#{CGI.escape(args[:search_term].to_s)}&order=#{CGI.escape(args[:order].to_s)}">#{category.name}</a>)
|
39
31
|
end
|
40
32
|
|
41
33
|
# All Articles in the Category, including all child Categories
|
@@ -45,12 +37,7 @@ module Dokno
|
|
45
37
|
.joins(:categories)
|
46
38
|
.where(dokno_categories: { id: self.class.branch(parent_category_id: id).pluck(:id) })
|
47
39
|
|
48
|
-
records
|
49
|
-
records = records.newest_order if order == :newest
|
50
|
-
records = records.view_order if order == :views
|
51
|
-
records = records.alpha_order if order == :alpha
|
52
|
-
|
53
|
-
records
|
40
|
+
Article.apply_sort(records, order: order)
|
54
41
|
end
|
55
42
|
|
56
43
|
def branch
|
@@ -59,7 +46,7 @@ module Dokno
|
|
59
46
|
|
60
47
|
# Used to invalidate the fragment cache of the hierarchical category select options
|
61
48
|
def self.cache_key
|
62
|
-
maximum :updated_at
|
49
|
+
[maximum(:updated_at), Article.maximum(:updated_at)].compact.max
|
63
50
|
end
|
64
51
|
|
65
52
|
# The given Category and all child Categories. Useful for filtering associated articles.
|
@@ -78,26 +65,14 @@ module Dokno
|
|
78
65
|
categories.flatten
|
79
66
|
end
|
80
67
|
|
81
|
-
def self.select_option_markup(selected_category_codes: nil,
|
68
|
+
def self.select_option_markup(selected_category_codes: nil, context_category: nil, level: 0)
|
82
69
|
return '' if level.positive? && context_category.blank?
|
83
70
|
|
84
71
|
options = []
|
85
72
|
level_categories = where(category_id: context_category&.id).alpha_order
|
86
|
-
|
87
73
|
level_categories.each do |category|
|
88
|
-
options << option_markup(
|
89
|
-
|
90
|
-
selected_category_codes: selected_category_codes,
|
91
|
-
exclude_category_id: exclude_category_id,
|
92
|
-
level: level
|
93
|
-
)
|
94
|
-
|
95
|
-
options << select_option_markup(
|
96
|
-
selected_category_codes: selected_category_codes,
|
97
|
-
exclude_category_id: exclude_category_id,
|
98
|
-
context_category: category,
|
99
|
-
level: (level + 1)
|
100
|
-
)
|
74
|
+
options << option_markup(category: category, selected_category_codes: selected_category_codes, level: level)
|
75
|
+
options << select_option_markup(selected_category_codes: selected_category_codes, context_category: category, level: (level + 1))
|
101
76
|
end
|
102
77
|
|
103
78
|
options.join
|
@@ -105,11 +80,10 @@ module Dokno
|
|
105
80
|
|
106
81
|
private
|
107
82
|
|
108
|
-
def self.option_markup(category:, selected_category_codes:,
|
109
|
-
return '' if category.id == exclude_category_id
|
110
|
-
|
83
|
+
def self.option_markup(category:, selected_category_codes:, level: 0)
|
111
84
|
selected = selected_category_codes&.include?(category.code)
|
112
|
-
|
85
|
+
article_count = category.articles_in_branch.size
|
86
|
+
%(<option value="#{category.code}" #{'selected="selected"' if selected}>#{(' ' * level)}#{category.name}#{' (' + article_count.to_s + ')' if article_count.positive?}</option>)
|
113
87
|
end
|
114
88
|
|
115
89
|
# Never allow setting of parent to self
|
@@ -2,8 +2,8 @@
|
|
2
2
|
/* Article formatting */
|
3
3
|
.dokno-article-content-markup {
|
4
4
|
font-weight: 400;
|
5
|
-
line-height: 1.
|
6
|
-
font-size:
|
5
|
+
line-height: 1.75em;
|
6
|
+
font-size: 1em;
|
7
7
|
}
|
8
8
|
|
9
9
|
.dokno-article-content-markup code {
|
@@ -23,7 +23,7 @@
|
|
23
23
|
.dokno-article-content-markup ol,
|
24
24
|
.dokno-article-content-markup hr,
|
25
25
|
.dokno-article-content-markup table {
|
26
|
-
margin-bottom: 1.
|
26
|
+
margin-bottom: 1.25em;
|
27
27
|
}
|
28
28
|
|
29
29
|
.dokno-article-content-markup h1,
|
@@ -32,28 +32,28 @@
|
|
32
32
|
.dokno-article-content-markup h4,
|
33
33
|
.dokno-article-content-markup h5,
|
34
34
|
.dokno-article-content-markup h6 {
|
35
|
-
margin-bottom: 1.
|
35
|
+
margin-bottom: 1.25em;
|
36
36
|
font-weight: 600;
|
37
37
|
}
|
38
38
|
|
39
39
|
.dokno-article-content-markup h1 {
|
40
|
-
font-size: 1.
|
40
|
+
font-size: 1.625em;
|
41
41
|
}
|
42
42
|
|
43
43
|
.dokno-article-content-markup h2 {
|
44
|
-
font-size: 1.
|
44
|
+
font-size: 1.25em;
|
45
45
|
}
|
46
46
|
|
47
47
|
.dokno-article-content-markup h3,
|
48
48
|
.dokno-article-content-markup h4,
|
49
49
|
.dokno-article-content-markup h5,
|
50
50
|
.dokno-article-content-markup h6 {
|
51
|
-
font-size:
|
51
|
+
font-size: 1em;
|
52
52
|
}
|
53
53
|
|
54
54
|
.dokno-article-content-markup blockquote {
|
55
55
|
border-left: 4px solid #edf2f7;
|
56
|
-
padding-left: 1.
|
56
|
+
padding-left: 1.25em;
|
57
57
|
}
|
58
58
|
|
59
59
|
.dokno-article-content-markup ul,
|
@@ -75,10 +75,10 @@
|
|
75
75
|
|
76
76
|
.dokno-article-content-markup table th,
|
77
77
|
.dokno-article-content-markup table td {
|
78
|
-
padding-left:
|
79
|
-
padding-right:
|
80
|
-
padding-top: 0.
|
81
|
-
padding-bottom: 0.
|
78
|
+
padding-left: 1em;
|
79
|
+
padding-right: 1em;
|
80
|
+
padding-top: 0.5em;
|
81
|
+
padding-bottom: 0.5em;
|
82
82
|
font-weight: normal;
|
83
83
|
}
|
84
84
|
|
@@ -3,8 +3,31 @@
|
|
3
3
|
<section class="mb-10">
|
4
4
|
|
5
5
|
<div class="text-2xl mb-5 text-gray-500"><%= article.persisted? ? 'Edit' : 'New' %> Article</div>
|
6
|
-
<h1 class="text-4xl
|
7
|
-
<hr class="mb-
|
6
|
+
<h1 class="text-4xl leading-tight font-light"><%= article.title %></h1>
|
7
|
+
<hr class="mt-8 mb-10" />
|
8
|
+
|
9
|
+
<% if article.up_for_review? %>
|
10
|
+
<div class="bg-gray-800 text-gray-100 rounded mb-10">
|
11
|
+
<h2 class="bg-gray-900 p-10 rounded-t text-2xl leading-tight font-light">Review for Accuracy / Relevance</h2>
|
12
|
+
|
13
|
+
<div class="flex p-10">
|
14
|
+
<div class="w-1/2 pr-5">
|
15
|
+
<div>
|
16
|
+
<span class="text-lg font-semibold"><label for="reset_review_date">Reset the next review date?</label></span>
|
17
|
+
<input onchange="setReviewForm();" type="checkbox" name="reset_review_date" id="reset_review_date" value="true" class="ml-2 text-lg" <%= "checked='checked'" if @reset_review_date %> />
|
18
|
+
</div>
|
19
|
+
<div class="text-gray-400">
|
20
|
+
<%= article.review_due_days_string %>.
|
21
|
+
Check the box above to mark this article as reviewed and reset the next review date to <span class="px-2 py-1 bg-gray-900 rounded text-white font-semibold"><%= "#{Date.today + Dokno.config.article_review_period}" %></span>
|
22
|
+
</div>
|
23
|
+
</div>
|
24
|
+
<div class="w-1/2">
|
25
|
+
<div class="text-lg font-semibold"><label for="review_notes">Reviewer Notes</label></div>
|
26
|
+
<textarea placeholder="Any review notes here will be added to the change history for this article" name="review_notes" id="review_notes" class="rounded text-xl shadow-inner bg-gray-100 p-3 mt-2 w-full text-gray-900" rows="2"><%= @review_notes %></textarea>
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
<% end %>
|
8
31
|
|
9
32
|
<div class="mb-5">
|
10
33
|
<div class="text-lg font-semibold"><label for="slug">Slug</label></div>
|
@@ -13,9 +36,9 @@
|
|
13
36
|
</div>
|
14
37
|
|
15
38
|
<% if Dokno::Category.exists? %>
|
16
|
-
<div class="mb-5">
|
17
|
-
<div class="text-lg font-semibold"><label for="
|
18
|
-
<select name="category_code[]" id="category_code" multiple="multiple" size="<%= (cat_count = Dokno::Category.count) <=
|
39
|
+
<div class="mb-5 w-2/3">
|
40
|
+
<div class="text-lg font-semibold"><label for="category_code"><%= 'Category'.pluralize article.categories.count %></label></div>
|
41
|
+
<select name="category_code[]" id="category_code" multiple="multiple" size="<%= (cat_count = Dokno::Category.count) <= 9 ? (cat_count + 1).to_s : '10' %>" class="rounded text-xl shadow-inner bg-gray-100 p-2 w-full mt-2 w-full max-w-full">
|
19
42
|
<option></option>
|
20
43
|
<%= Dokno::Category.select_option_markup(selected_category_codes: @category_codes).html_safe %>
|
21
44
|
</select>
|
@@ -27,7 +50,7 @@
|
|
27
50
|
</div>
|
28
51
|
<% end %>
|
29
52
|
|
30
|
-
<hr class="
|
53
|
+
<hr class="my-10" />
|
31
54
|
|
32
55
|
<div class="mb-5">
|
33
56
|
<div class="text-lg font-semibold"><label for="title">Title</label></div>
|
@@ -47,16 +70,32 @@
|
|
47
70
|
<a id="markdown_write_link" href="javascript:;" onclick="writeArticleToggle();" class="float-right hidden"><i data-feather="pen-tool" class="inline"></i> Write</a>
|
48
71
|
<a id="markdown_preview_link" href="javascript:;" onclick="previewArticleToggle();" class="float-right"><i data-feather="eye" class="inline"></i> Preview</a>
|
49
72
|
</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="
|
73
|
+
<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="20"><%= article.persisted? ? article.markdown : (article.markdown.presence || @template) %></textarea>
|
51
74
|
<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
75
|
<div class="text-gray-500 mt-2">Detailed documentation of the described topic. Basic HTML & <a target="_blank" href="https://commonmark.org/help/" title="Markdown formatting examples">markdown</a> OK.</div>
|
53
76
|
</div>
|
54
77
|
|
55
|
-
<div class="
|
78
|
+
<div class="mb-5">
|
79
|
+
<div>
|
80
|
+
<span class="text-lg font-semibold"><label for="starred">Starred article?</label></span>
|
81
|
+
<input type="hidden" name="starred" value="false" />
|
82
|
+
<input type="checkbox" name="starred" id="starred" value="true" class="ml-2 text-lg" <%= "checked='checked'" if article.starred %> />
|
83
|
+
</div>
|
84
|
+
<div class="text-gray-400">
|
85
|
+
Starred articles are always listed first when browsing.
|
86
|
+
</div>
|
87
|
+
</div>
|
88
|
+
|
89
|
+
<hr class="my-10" />
|
90
|
+
|
91
|
+
<div class="text-right">
|
92
|
+
<span class="text-lg mr-5"><a class="no-underline" href="<%= article.persisted? ? article_path(article.slug) : root_path %>">Cancel</a></span>
|
56
93
|
<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
94
|
</div>
|
59
95
|
|
60
96
|
</section>
|
61
97
|
|
62
|
-
<script>
|
98
|
+
<script>
|
99
|
+
elem('input#slug').focus();
|
100
|
+
setReviewForm();
|
101
|
+
</script>
|
@@ -1,34 +1,37 @@
|
|
1
1
|
<%= render 'dokno/article_formatting' %>
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
<div
|
6
|
-
<%
|
7
|
-
<
|
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
|
-
|
11
|
+
</div>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<%= render 'partials/category_header' %>
|
15
|
+
|
16
|
+
<div class="my-10 no-print"><hr /></div>
|
11
17
|
|
18
|
+
<section>
|
12
19
|
<div class="flex">
|
13
20
|
<div id="dokno-article-sidebar" class="w-2/5 pr-10">
|
14
|
-
<
|
15
|
-
|
16
|
-
|
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-
|
22
|
-
<button title="
|
23
|
-
<button title="
|
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
|
@@ -39,7 +42,7 @@
|
|
39
42
|
</div>
|
40
43
|
|
41
44
|
<div class="mt-5 flex no-print">
|
42
|
-
<div class="no-print w-8"><i data-feather="eye" class="inline-block h-5"></i></div>
|
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 %>
|
@@ -58,7 +61,7 @@
|
|
58
61
|
|
59
62
|
<% if @article.reading_time.present? %>
|
60
63
|
<div class="mt-5 flex no-print">
|
61
|
-
<div class="no-print w-8"><i data-feather="watch" class="inline-block h-5"></i></div>
|
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>
|
@@ -76,7 +79,7 @@
|
|
76
79
|
|
77
80
|
<% if can_edit? %>
|
78
81
|
<div class="mt-5 flex no-print">
|
79
|
-
<div class="no-print w-8"><i data-feather="crosshair" class="inline-block h-5"></i></div>
|
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.
|
99
|
+
<% if (category_name_list = @article.category_name_list(context_category_id: @category&.id)).present? %>
|
97
100
|
<div class="mt-5 flex no-print">
|
98
|
-
<div class="no-print w-8"><i data-feather="folder" class="inline-block h-5"></i></div>
|
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
|
-
<%= '
|
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
|
137
|
-
<
|
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
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
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.
|
@@ -35,4 +42,8 @@
|
|
35
42
|
</div>
|
36
43
|
</section>
|
37
44
|
|
38
|
-
<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>
|