diff --git a/app/controllers/content_controller.rb b/app/controllers/content_controller.rb index 4725bcf9..d287866e 100644 --- a/app/controllers/content_controller.rb +++ b/app/controllers/content_controller.rb @@ -47,7 +47,7 @@ class ContentController < ApplicationController ).order(:tag) @filtered_page_tags = [] if params.key?(:slug) - @filtered_page_tags = @page_tags.where(slug: params[:slug]) + @filtered_page_tags = @page_tags.where(slug: params[:slug]).uniq(&:slug) @content.select! { |content| @filtered_page_tags.pluck(:page_id).include?(content.id) } end @page_tags = @page_tags.uniq(&:tag) @@ -450,6 +450,26 @@ class ContentController < ApplicationController @serialized_content = ContentSerializer.new(@content) return redirect_to(root_path, notice: "You don't have permission to view that content.") unless @content.updatable_by?(current_user || User.new) + # Generate changelog statistics and data + @stats = ChangelogStatsService.new(@content) + @change_intensity = @stats.change_intensity_by_week + + # Get paginated change events first, then group them + page = params[:page] || 1 + per_page = 20 # 20 change events per page + + # Get the base query for change events (without the .last() limit) + change_events_query = ContentChangeEvent.where( + content_id: Attribute.where( + entity_type: @content.class.name, + entity_id: @content.id + ), + content_type: "Attribute" + ).includes(:user).order('created_at DESC') + + @paginated_events = change_events_query.paginate(page: page, per_page: per_page) + @grouped_changes = group_events_by_date(@paginated_events) + if user_signed_in? @navbar_actions << { label: @serialized_content.name, @@ -792,6 +812,20 @@ class ContentController < ApplicationController private + def group_events_by_date(events) + # Group events by date for timeline display + grouped = events.group_by { |event| event.created_at.to_date } + + grouped.map do |date, date_events| + { + date: date, + events: date_events, + total_field_changes: date_events.sum { |event| event.changed_fields.keys.length }, + users: date_events.map(&:user).compact.uniq + } + end.sort_by { |group| group[:date] }.reverse + end + def update_page_tags tag_list = field_params.fetch('value', '').split(PageTag::SUBMISSION_DELIMITER) current_tags = @content.page_tags.pluck(:tag) diff --git a/app/services/changelog_stats_service.rb b/app/services/changelog_stats_service.rb new file mode 100644 index 00000000..4a784e14 --- /dev/null +++ b/app/services/changelog_stats_service.rb @@ -0,0 +1,148 @@ +# frozen_string_literal: true + +class ChangelogStatsService + def initialize(content) + @content = content + @change_events = content.attribute_change_events + end + + def total_changes + @change_events.sum { |event| event.changed_fields.keys.length } + end + + def active_days + @change_events.map { |event| event.created_at.to_date }.uniq.length + end + + def most_recent_activity + @change_events.first&.created_at + end + + def creation_date + @content.created_at + end + + def days_since_creation + (Date.current - creation_date.to_date).to_i + end + + def most_active_field + field_counts = Hash.new(0) + + @change_events.each do |event| + event.changed_fields.keys.each do |field_key| + field_counts[field_key] += 1 + end + end + + return nil if field_counts.empty? + + most_frequent_field_id = field_counts.max_by { |_, count| count }.first + find_field_by_id(most_frequent_field_id) + end + + def change_intensity_by_week + # Group changes by week for the past 12 weeks + weeks = [] + (0..11).each do |i| + week_start = i.weeks.ago.beginning_of_week + week_end = week_start.end_of_week + + changes_this_week = @change_events.select do |event| + event.created_at >= week_start && event.created_at <= week_end + end + + weeks << { + week_start: week_start, + week_end: week_end, + change_count: changes_this_week.sum { |event| event.changed_fields.keys.length }, + event_count: changes_this_week.length + } + end + + weeks.reverse + end + + def changes_by_day_of_week + day_counts = Hash.new(0) + + @change_events.each do |event| + day_name = event.created_at.strftime('%A') + day_counts[day_name] += event.changed_fields.keys.length + end + + # Return in week order + %w[Monday Tuesday Wednesday Thursday Friday Saturday Sunday].map do |day| + { day: day, count: day_counts[day] } + end + end + + def biggest_single_update + biggest_event = @change_events.max_by { |event| event.changed_fields.keys.length } + return nil unless biggest_event + + { + event: biggest_event, + field_count: biggest_event.changed_fields.keys.length, + date: biggest_event.created_at + } + end + + def writing_streaks + # Find consecutive days with changes + change_dates = @change_events.map { |event| event.created_at.to_date }.uniq.sort.reverse + + return [] if change_dates.empty? + + streaks = [] + current_streak = [change_dates.first] + + change_dates.each_cons(2) do |current_date, next_date| + if (current_date - next_date).to_i == 1 + current_streak << next_date + else + streaks << current_streak if current_streak.length > 1 + current_streak = [next_date] + end + end + + streaks << current_streak if current_streak.length > 1 + streaks.sort_by(&:length).reverse + end + + def longest_writing_streak + streaks = writing_streaks + return nil if streaks.empty? + + longest = streaks.first + { + length: longest.length, + start_date: longest.last, + end_date: longest.first + } + end + + def grouped_changes_by_date + # Group changes by date for timeline display + grouped = @change_events.group_by { |event| event.created_at.to_date } + + grouped.map do |date, events| + { + date: date, + events: events, + total_field_changes: events.sum { |event| event.changed_fields.keys.length }, + users: events.map(&:user).compact.uniq + } + end.sort_by { |group| group[:date] }.reverse + end + + private + + def find_field_by_id(field_id) + # Get related attribute and field information + related_attribute = Attribute.find_by(id: @change_events.map(&:content_id).uniq) + return nil unless related_attribute + + AttributeField.find_by(id: related_attribute.attribute_field_id) + end +end \ No newline at end of file diff --git a/app/views/content/changelog.html.erb b/app/views/content/changelog.html.erb index 4b5a108e..de0aea24 100644 --- a/app/views/content/changelog.html.erb +++ b/app/views/content/changelog.html.erb @@ -1,20 +1,13 @@ -<%= content_for :full_width_page_header do %> - <%= render partial: 'content/display/image_card_header' %> -<% end %> - -<%= render partial: 'content/display/changelog', locals: { content: @serialized_content } %> - - +
+ + + <%= render partial: 'content/changelog/header' %> + + + <%= render partial: 'content/changelog/timeline' %> +
---> \ No newline at end of file + + + \ No newline at end of file diff --git a/app/views/content/changelog/_date_changes.html.erb b/app/views/content/changelog/_date_changes.html.erb new file mode 100644 index 00000000..091f01a7 --- /dev/null +++ b/app/views/content/changelog/_date_changes.html.erb @@ -0,0 +1,129 @@ + +<% + # Process the events to get organized change data + changed_attributes = Attribute.where(id: events.select { |event| event.content_type == 'Attribute' }.map(&:content_id)) + changed_fields = AttributeField.where(id: changed_attributes.pluck(:attribute_field_id)).includes([:attribute_category]) +%> + +
+ <% events.reverse.each_with_index do |change_event, event_index| %> + <% + # Skip events without users (old data) + next if change_event.user.nil? + %> + + +
+
+
+ <% if change_event.user.avatar.attached? %> + <%= image_tag change_event.user.avatar, class: "w-full h-full rounded-full object-cover" %> + <% else %> + person + <% end %> +
+ <%= change_event.user.display_name %> + + <%= change_event.created_at.strftime('%I:%M %p') %> +
+ + <%= pluralize(change_event.changed_fields.keys.length, 'change') %> + +
+ + +
+ <% change_event.changed_fields.each do |field_key, change| %> + <% + related_attribute = changed_attributes.detect { |attribute| attribute.id == change_event.content_id } + next unless related_attribute + + related_field = changed_fields.detect { |field| field.id == related_attribute.attribute_field_id } + next unless related_field + + related_category = related_field.attribute_category + + # Skip if value didn't actually change + next if change.first == change.second + next if change.first.blank? && change.second.blank? + next if ContentChangeEvent::FIELD_IDS_TO_EXCLUDE.include?(field_key) + + # Handle privacy and blank values + old_value = change.first.blank? ? ContentChangeEvent::BLANK_PLACEHOLDER : change.first.to_s + new_value = change.second.blank? ? ContentChangeEvent::BLANK_PLACEHOLDER : change.second.to_s + + # Privacy check + visible_change = true + if related_field.label.start_with?('Private') + visible_change = user_signed_in? && ( + (content.raw_model.is_a?(Universe) && content.user == current_user) || + (content.respond_to?(:universe) && content.universe && content.universe.user == current_user) || + (content.respond_to?(:universe) && content.universe.nil? && content.user == current_user) + ) + end + + unless visible_change + old_value = ContentChangeEvent::PRIVATE_PLACEHOLDER + new_value = ContentChangeEvent::PRIVATE_PLACEHOLDER + end + + # Special handling for privacy field + if related_field.label.downcase == 'privacy' + old_value = 'private' if old_value == ContentChangeEvent::BLANK_PLACEHOLDER + new_value = 'private' if new_value == ContentChangeEvent::BLANK_PLACEHOLDER + end + %> + + +
+ +
+
+
+ <%= related_category.icon %> +
+
+

<%= related_field.label %>

+

<%= related_category.label %>

+
+
+ + <%= change_event.action %> + +
+ + +
+ <%= render partial: "content/changelog/field_change/#{related_field.field_type}", + locals: { + old_value: old_value, + new_value: new_value, + field: related_field, + change_type: change_event.action + } %> +
+ + +
+ <% unless old_value == ContentChangeEvent::BLANK_PLACEHOLDER || old_value == ContentChangeEvent::PRIVATE_PLACEHOLDER %> + + <% end %> + <% unless new_value == ContentChangeEvent::BLANK_PLACEHOLDER || new_value == ContentChangeEvent::PRIVATE_PLACEHOLDER %> + + <% end %> +
+
+ <% end %> +
+ <% end %> +
\ No newline at end of file diff --git a/app/views/content/changelog/_header.html.erb b/app/views/content/changelog/_header.html.erb new file mode 100644 index 00000000..18615a80 --- /dev/null +++ b/app/views/content/changelog/_header.html.erb @@ -0,0 +1,150 @@ + +
+
+ + + + + +
+
+
+ <%= @serialized_content.class_icon %> +
+
+

+ Your Creative Journey +

+

+ Every change you've made to <%= @serialized_content.name %> +

+
+
+
+ + +
+ +
+
+
+ edit +
+
+
<%= pluralize(@stats.total_changes, 'change') %>
+
Total
+
+
+
+ + +
+
+
+ calendar_today +
+
+
<%= pluralize(@stats.active_days, 'day') %>
+
Active
+
+
+
+ + +
+
+
+ schedule +
+
+
<%= pluralize(@stats.days_since_creation, 'day') %>
+
Old
+
+
+
+ + +
+
+
+ trending_up +
+
+ <% biggest_update = @stats.biggest_single_update %> + <% field_count = biggest_update ? biggest_update[:field_count] : 0 %> +
+ <%= pluralize(field_count, 'change') %> +
+
Biggest Edit Session
+
+
+
+
+ + +
+

+ show_chart + Activity Over Time +

+ +
+ <% @change_intensity.each do |week_data| %> + <% + intensity_level = case week_data[:change_count] + when 0 then 'bg-gray-100' + when 1..3 then 'bg-green-200' + when 4..7 then 'bg-green-400' + when 8..15 then 'bg-green-600' + else 'bg-green-800' + end + %> +
+
+ <% end %> +
+ +
+ 12 weeks ago + Today +
+
+ + + <% longest_streak = @stats.longest_writing_streak %> + <% if longest_streak %> +
+
+
+ local_fire_department +
+
+

Your Longest Writing Streak

+

+ <%= longest_streak[:length] %> consecutive days + from <%= longest_streak[:start_date].strftime('%B %d') %> to <%= longest_streak[:end_date].strftime('%B %d, %Y') %> +

+
+
+
+ <% end %> + +
+
\ No newline at end of file diff --git a/app/views/content/changelog/_timeline.html.erb b/app/views/content/changelog/_timeline.html.erb new file mode 100644 index 00000000..d7bbf97c --- /dev/null +++ b/app/views/content/changelog/_timeline.html.erb @@ -0,0 +1,188 @@ + +
+ + +
+

Change Timeline

+

Your creative journey, day by day

+ <% if @paginated_events.total_pages > 1 %> +
+ Showing page <%= @paginated_events.current_page %> of <%= @paginated_events.total_pages %> + (<%= @paginated_events.total_entries %> total changes) +
+ <% end %> +
+ + +
+ +
+ + <% if @grouped_changes.empty? %> + +
+
+ history +
+

No Changes Yet

+

Start editing your <%= @serialized_content.class_name.downcase %> to see your creative journey unfold here.

+
+ <% else %> + +
+ <% @grouped_changes.each_with_index do |group, index| %> +
+ +
+ + +
+ + + + +
+ +
+ <%= render partial: 'content/changelog/date_changes', + locals: { + events: group[:events], + content: @serialized_content, + date: group[:date] + } %> +
+
+
+
+ <% end %> +
+ <% end %> + + +
+ +
+ + +
+
+
+ star +
+
+

The Beginning

+

+ <%= @serialized_content.name %> was created + <% if @content.user.present? %> + by <%= link_to @content.user.display_name, @content.user, class: "font-medium text-green-700 hover:text-green-800" %> + <% end %> + + <%= distance_of_time_in_words(@content.created_at, Time.current) %> ago + (<%= @content.created_at.strftime('%B %d, %Y at %I:%M %p') %>) + +

+
+
+
+
+ + + <% if @paginated_events.total_pages > 1 %> +
+
+
+ <% if @paginated_events.previous_page %> + <%= link_to url_for(params.permit(:page).merge(page: @paginated_events.previous_page)), + class: "flex items-center px-4 py-2 bg-gray-100 hover:bg-gray-200 rounded-lg transition-colors text-gray-700" do %> + chevron_left + Previous + <% end %> + <% end %> + +
+ Page <%= @paginated_events.current_page %> of <%= @paginated_events.total_pages %> +
+ + <% if @paginated_events.next_page %> + <%= link_to url_for(params.permit(:page).merge(page: @paginated_events.next_page)), + class: "flex items-center px-4 py-2 bg-gray-100 hover:bg-gray-200 rounded-lg transition-colors text-gray-700" do %> + Next + chevron_right + <% end %> + <% end %> +
+
+
+ <% end %> + +
+
\ No newline at end of file diff --git a/app/views/content/changelog/field_change/_name.html.erb b/app/views/content/changelog/field_change/_name.html.erb index bb43a455..0bf5f99c 100644 --- a/app/views/content/changelog/field_change/_name.html.erb +++ b/app/views/content/changelog/field_change/_name.html.erb @@ -1,14 +1,41 @@ -
-
- <%= simple_format ContentFormatterService.show( - text: old_value, - viewing_user: current_user - ) %> + +
+ +
+ From: + + <% if old_value == ContentChangeEvent::BLANK_PLACEHOLDER %> + Empty + <% elsif old_value == ContentChangeEvent::PRIVATE_PLACEHOLDER %> + Private + <% else %> + <%= simple_format ContentFormatterService.show( + text: old_value, + viewing_user: current_user + ) %> + <% end %> +
-
- <%= simple_format ContentFormatterService.show( - text: new_value, - viewing_user: current_user - ) %> + + +
+ arrow_forward +
+ + +
+ To: + + <% if new_value == ContentChangeEvent::BLANK_PLACEHOLDER %> + Empty + <% elsif new_value == ContentChangeEvent::PRIVATE_PLACEHOLDER %> + Private + <% else %> + <%= simple_format ContentFormatterService.show( + text: new_value, + viewing_user: current_user + ) %> + <% end %> +
\ No newline at end of file diff --git a/app/views/content/changelog/field_change/_tags.html.erb b/app/views/content/changelog/field_change/_tags.html.erb index 2e9a7a91..f938fdae 100644 --- a/app/views/content/changelog/field_change/_tags.html.erb +++ b/app/views/content/changelog/field_change/_tags.html.erb @@ -1,41 +1,66 @@ -
- -
-
- <% old_value.split(PageTag::SUBMISSION_DELIMITER).each do |tag| %> - <% if user_signed_in? && @content.user == current_user %> - <%= - link_to send( - "page_tag_#{@content.class.name.downcase.pluralize}_path", - slug: PageTagService.slug_for(tag) - ) do - %> - + +
+ +
+
+
+ Previous Tags +
+
+ <% if old_value == ContentChangeEvent::BLANK_PLACEHOLDER %> + No tags + <% elsif old_value == ContentChangeEvent::PRIVATE_PLACEHOLDER %> + Private field + <% else %> +
+ <% old_value.split(PageTag::SUBMISSION_DELIMITER).each do |tag| %> + <% if user_signed_in? && @content.user == current_user %> + <%= link_to send("page_tag_#{@content.class.name.downcase.pluralize}_path", slug: PageTagService.slug_for(tag)), + class: "inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-red-100 text-red-800 hover:bg-red-200 transition-colors" do %> + tag + <%= tag %> + <% end %> + <% else %> + + tag + <%= tag %> + + <% end %> <% end %> - <% else %> - - <% end %> +
<% end %>
-
-
- <% new_value.split(PageTag::SUBMISSION_DELIMITER).each do |tag| %> - <% if user_signed_in? && @content.user == current_user %> - <%= - link_to send( - "page_tag_#{@content.class.name.downcase.pluralize}_path", - slug: PageTagService.slug_for(tag) - ) do - %> - + +
+
+
+ Current Tags +
+
+ <% if new_value == ContentChangeEvent::BLANK_PLACEHOLDER %> + No tags + <% elsif new_value == ContentChangeEvent::PRIVATE_PLACEHOLDER %> + Private field + <% else %> +
+ <% new_value.split(PageTag::SUBMISSION_DELIMITER).each do |tag| %> + <% if user_signed_in? && @content.user == current_user %> + <%= link_to send("page_tag_#{@content.class.name.downcase.pluralize}_path", slug: PageTagService.slug_for(tag)), + class: "inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-green-100 text-green-800 hover:bg-green-200 transition-colors" do %> + tag + <%= tag %> + <% end %> + <% else %> + + tag + <%= tag %> + + <% end %> <% end %> - <% else %> - - <% end %> +
<% end %>
-
\ No newline at end of file diff --git a/app/views/content/changelog/field_change/_text_area.html.erb b/app/views/content/changelog/field_change/_text_area.html.erb index bb43a455..3b5f1571 100644 --- a/app/views/content/changelog/field_change/_text_area.html.erb +++ b/app/views/content/changelog/field_change/_text_area.html.erb @@ -1,14 +1,74 @@ -
-
- <%= simple_format ContentFormatterService.show( - text: old_value, - viewing_user: current_user - ) %> + +
+ +
+
+
+ Previous + <% if old_value != ContentChangeEvent::BLANK_PLACEHOLDER && old_value != ContentChangeEvent::PRIVATE_PLACEHOLDER %> + + <%= old_value.to_s.split.length %> words + + <% end %> +
+
+ <% if old_value == ContentChangeEvent::BLANK_PLACEHOLDER %> + Empty + <% elsif old_value == ContentChangeEvent::PRIVATE_PLACEHOLDER %> + Private field + <% else %> +
+ <%= simple_format ContentFormatterService.show( + text: old_value, + viewing_user: current_user + ) %> +
+ <% end %> +
-
- <%= simple_format ContentFormatterService.show( - text: new_value, - viewing_user: current_user - ) %> + + +
+
+
+ Current + <% if new_value != ContentChangeEvent::BLANK_PLACEHOLDER && new_value != ContentChangeEvent::PRIVATE_PLACEHOLDER %> + + <%= new_value.to_s.split.length %> words + + <% end %> +
+
+ <% if new_value == ContentChangeEvent::BLANK_PLACEHOLDER %> + Empty + <% elsif new_value == ContentChangeEvent::PRIVATE_PLACEHOLDER %> + Private field + <% else %> +
+ <%= simple_format ContentFormatterService.show( + text: new_value, + viewing_user: current_user + ) %> +
+ <% end %> +
-
\ No newline at end of file +
+ + +<% if old_value != ContentChangeEvent::BLANK_PLACEHOLDER && old_value != ContentChangeEvent::PRIVATE_PLACEHOLDER && + new_value != ContentChangeEvent::BLANK_PLACEHOLDER && new_value != ContentChangeEvent::PRIVATE_PLACEHOLDER %> + <% + old_word_count = old_value.to_s.split.length + new_word_count = new_value.to_s.split.length + word_diff = new_word_count - old_word_count + %> + <% if word_diff != 0 %> +
+ + <%= word_diff > 0 ? 'add' : 'remove' %> + <%= word_diff.abs %> <%= 'word'.pluralize(word_diff.abs) %> <%= word_diff > 0 ? 'added' : 'removed' %> + +
+ <% end %> +<% end %> \ No newline at end of file diff --git a/app/views/content/changelog/field_change/_universe.html.erb b/app/views/content/changelog/field_change/_universe.html.erb index 01087843..8b87c856 100644 --- a/app/views/content/changelog/field_change/_universe.html.erb +++ b/app/views/content/changelog/field_change/_universe.html.erb @@ -1,22 +1,47 @@ -
-
- <% if old_value.blank? %> -

(no universe)

- <% else %> - <%= simple_format ContentFormatterService.show( - text: "[[Universe-#{old_value}]]", - viewing_user: current_user - ) %> - <% end %> + +
+ +
+ From: +
+ public +
+ <% if old_value == ContentChangeEvent::BLANK_PLACEHOLDER %> + No universe + <% elsif old_value == ContentChangeEvent::PRIVATE_PLACEHOLDER %> + Private + <% else %> + <%= simple_format ContentFormatterService.show( + text: "[[Universe-#{old_value}]]", + viewing_user: current_user + ) %> + <% end %> +
+
-
- <% if new_value.blank? %> -

(no universe)

- <% else %> - <%= simple_format ContentFormatterService.show( - text: "[[Universe-#{new_value}]]", - viewing_user: current_user - ) %> - <% end %> + + +
+ arrow_forward +
+ + +
+ To: +
+ public +
+ <% if new_value == ContentChangeEvent::BLANK_PLACEHOLDER %> + No universe + <% elsif new_value == ContentChangeEvent::PRIVATE_PLACEHOLDER %> + Private + <% else %> + <%= simple_format ContentFormatterService.show( + text: "[[Universe-#{new_value}]]", + viewing_user: current_user + ) %> + <% end %> +
+
\ No newline at end of file diff --git a/app/views/content/display/_tailwind_foldered_index.html.erb b/app/views/content/display/_tailwind_foldered_index.html.erb index 1efd943d..5b2daa08 100644 --- a/app/views/content/display/_tailwind_foldered_index.html.erb +++ b/app/views/content/display/_tailwind_foldered_index.html.erb @@ -564,7 +564,7 @@ <% @filtered_page_tags.each do |page_tag| %> <%= page_tag.tag %> - <%= link_to(polymorphic_path(content_type_class, params.permit(:sort, :favorite_only).merge({ slug: params.fetch(:slug, []) - [page_tag.slug] }))) do %> + <%= link_to(polymorphic_path(content_type_class, params.permit(:sort, :favorite_only).merge({ slug: Array(params.fetch(:slug, [])) - [page_tag.slug] }))) do %> diff --git a/app/views/content/show.html.erb b/app/views/content/show.html.erb index 2eef0cb5..5dac276e 100644 --- a/app/views/content/show.html.erb +++ b/app/views/content/show.html.erb @@ -193,7 +193,7 @@ function showPageController() { init() { // Set initial view from URL hash if present const hash = window.location.hash.substring(1); - if (['overview', 'details', 'gallery', 'associations', 'collections', 'feedback'].includes(hash)) { + if (['overview', 'details', 'gallery', 'associations', 'collections', 'feedback', 'privacy'].includes(hash)) { this.currentView = hash; if (hash !== 'overview') { this.currentCategory = null; diff --git a/app/views/content/show/_dynamic_content.html.erb b/app/views/content/show/_dynamic_content.html.erb index 4a124ff4..fae713d7 100644 --- a/app/views/content/show/_dynamic_content.html.erb +++ b/app/views/content/show/_dynamic_content.html.erb @@ -105,6 +105,23 @@ } %>
+ +
+
+
+
+

Privacy & Sharing

+

Manage who can see and access this <%= content.class_name.downcase %>

+
+
+
+ + <%= render partial: 'content/show/privacy_view', locals: { + content: content, + raw_content: raw_content + } %> +
+
diff --git a/app/views/content/show/_navigation_sidebar.html.erb b/app/views/content/show/_navigation_sidebar.html.erb index fb431c2e..2dc064f0 100644 --- a/app/views/content/show/_navigation_sidebar.html.erb +++ b/app/views/content/show/_navigation_sidebar.html.erb @@ -153,7 +153,7 @@ <% if raw_content.respond_to?(:privacy) %>
Visibility -