Merge branch 'master' into image-opts

This commit is contained in:
Andrew Brown 2021-10-07 16:08:40 -07:00 committed by GitHub
commit 3ef0760f2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 179 additions and 50 deletions

View File

@ -104,13 +104,35 @@ $(document).ready(function () {
// Replace this element's content with the name of the page
var tag = $(this);
$.get(
'/api/internal/' + tag.data('klass') + '/' + tag.data('id') + '/name'
).done(function (response) {
tag.find('.name-container').text(response);
}).fail(function() {
tag.find('.name-conainer').text("Unknown " + tag.data('klass'));
});
// Instantiate a cache for all page lookup queries (if not already created)
window.load_page_name_cache = window.load_page_name_cache || {};
var page_name_key = tag.data('klass') + '/' + tag.data('id');
if (page_name_key in window.load_page_name_cache) {
// If we've already made a request for this klass+id, we can just insta-load the
// cached result instead of requesting it again.
tag.find('.name-container').text(window.load_page_name_cache[page_name_key]);
} else {
// If we haven't made a request for this klass+id, look it up and cache it
$.get(
'/api/internal/' + page_name_key + '/name'
).done(function (response) {
tag.find('.name-container').text(response);
window.load_page_name_cache[page_name_key] = response;
// Go ahead and pre-fill all tags on the page for this klass+id, too
$('.js-load-page-name[data-klass=' + tag.data('klass') + '][data-id=' + tag.data('id') + ']')
.find('.name-container')
.text(response);
}).fail(function() {
tag.find('.name-container').text("Unknown " + tag.data('klass'));
});
}
});
});

View File

@ -0,0 +1,3 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/

View File

@ -159,7 +159,7 @@ class ApplicationController < ActionController::Base
cache_current_user_content
@contributable_universe_ids ||= if user_signed_in?
current_user.contributable_universe_ids + @current_user_content.fetch('Universe', []).map(&:id)
current_user.contributable_universe_ids
else
[]
end

View File

@ -115,6 +115,10 @@ class DataController < ApplicationController
@content = current_user.content
end
def tags
@tags = current_user.page_tags
end
def discussions
@topics = Thredded::Topic.where(user_id: current_user.id)
@posts = Thredded::Post.where(user_id: current_user.id)

View File

@ -0,0 +1,23 @@
class PageTagsController < ApplicationController
# Remove a tag and all of its links to a page
def remove
# Params
# {"page_type"=>"Location", "slug"=>"mountains", "controller"=>"page_tags", "action"=>"remove"
return unless params.key?(:page_type) && params.key?(:slug)
PageTag.where(
page_type: params[:page_type],
slug: params[:slug],
user_id: current_user.id
).destroy_all
return redirect_back fallback_location: root_path, notice: 'Tag(s) deleted successfully.'
end
# Destroy a specific tag by ID
def destroy
PageTag.find_by(id: params[:id], user_id: current_user.id).destroy!
return redirect_back fallback_location: root_path, notice: 'Tag(s) deleted successfully.'
end
end

View File

@ -0,0 +1,2 @@
module PageTagsHelper
end

View File

@ -5,7 +5,6 @@
changed_fields = AttributeField.where(id: changed_attributes.pluck(:attribute_field_id)).includes([:attribute_category])
%>
<div class="row">
<div class="col s12 m12 l10 offset-l1">
<h1 class="flow-text grey-text">
@ -72,10 +71,14 @@
<span>
<%= link_to(change_event.user.display_name, change_event.user, class: "#{User.text_color}") %>
</span>
<div class="grey-text right"><%= time_ago_in_words change_event.created_at %> ago</div>
<div class="grey-text right">
<%= time_ago_in_words change_event.created_at %> ago
&middot;
<%= change_event.created_at.strftime('%B %d, %H:%M %Z') %>
</div>
</div>
</div>
<div style="margin-bottom: 4em">
<div style="margin-bottom: 4em" class="black-text">
<%=
render partial: "content/changelog/field_change/#{related_field.field_type}",
locals: { old_value: old_value, new_value: new_value }

View File

@ -2,10 +2,6 @@
TODO: everything here (probably) should move to the ContentSerializer so we don't have this
heavy logic in a random partial
%>
<%
relations = Rails.application.config.content_relations[content.class.name]
relations ||= []
%>
<div id="associations_panel" class="panel">
<%= render partial: 'notice_dismissal/messages/07' %>
@ -29,37 +25,5 @@
locals: { value: link_codes, content: content }
%>
<% end %>
<% if user_signed_in? %>
<div class="card-panel yellow lighten-5 black-text">
Notice: The newest Notebook.ai release is adding the ability to create your own link
fields, which includes a rather large migration of all existing link fields into a new linking system.
Links that haven't been migrated yet can be seen below this message; links on the new system appear above.
<br /><br />
Thank you for your patience during this large rewrite! This notice will automatically disappear after the
migration has completed for everyone.
<br /><br />
&mdash; Andrew
</div>
<% end %>
<%# TODO: remove these after finishing link migration script %>
<% relations.each do |name, params| %>
<%
results = params[:related_class].where("#{params[:through_relation].downcase}_id": content.id)
.map { |content| content.send(params[:inverse_class].downcase) }
.select { |content| content && content.readable_by?(current_user || User.new) }
%>
<% next unless results.any? %>
<div class="uppercase grey-text">
<%= params[:relation_text].to_s.titleize.downcase %> of
</div>
<%=
link_codes = results.map { |page| "#{page.page_type}-#{page.id}" }
render partial: "content/display/attribute_value/link",
locals: { value: link_codes, content: content }
%>
<% end %>
</div>
</div>

View File

@ -69,6 +69,20 @@
<% end %>
</div>
<div class="col s12 m12 l6">
<%= link_to tags_path, class: 'black-text' do %>
<div class="hoverable card purple lighten-5">
<div class="card-content">
<i class="material-icons right purple-text text-lighten-4"><%= PageTag.icon %></i>
<div class="card-title">Tag management</div>
<p>
Manage the tags you've used for your worldbuilding.
</p>
</div>
</div>
<% end %>
</div>
<div class="col s12 m12 l6">
<%= link_to notebook_export_path, class: 'black-text' do %>
<div class="hoverable card brown lighten-3">

View File

@ -0,0 +1,82 @@
<%
showed_any_tags = false
%>
<h2 class="grey-text" style="font-size: 2rem">Your Notebook.ai tags</h2>
<ul class="collapsible">
<% Rails.application.config.content_types[:all].each do |content_type| %>
<%
grouped_tags = PageTag.where(page_type: content_type.name, user_id: current_user).order('tag ASC').group_by(&:tag)
next if grouped_tags.values.length == 0
showed_any_tags = true
%>
<li>
<div class="collapsible-header">
<i class="material-icons <%= content_type.text_color %>"><%= content_type.icon %></i>
<%= content_type.name %> tags
<span class="badge"><%= grouped_tags.values.length %></span>
</div>
<div class="collapsible-body">
<% grouped_tags.each do |tag, page_list| %>
<div class="row" style="border-bottom: 1px solid #ccc; padding-bottom: 2em; margin-bottom: 2em">
<div class="col s12 m6 l4">
<div>
<%=
link_to send(
"#{content_type.name.downcase.pluralize}_path",
slug: PageTagService.slug_for(tag)
) do
%>
<span class="<%= content_type.color %> white-text" style="padding: 0.3em 0.4em; font-size: 1em">
<%= tag %>
</span>
<% end %>
</div>
<div class="grey-text" style="padding-top: 1em">
Used by <%= pluralize page_list.length, 'page' %>
</div>
<div>
<%=
link_to 'Delete this tag', tag_remove_path(
page_type: content_type.name,
slug: PageTagService.slug_for(tag)
), data: {
confirm: "Are you sure? This will delete this tag and remove it from all pages."
}, class: 'red-text'
%>
</div>
</div>
<div class="col s12 m6 l8">
<% page_list.each do |page_tag| %>
<div class="chip js-load-page-name" data-klass="<%= page_tag.page_type %>" data-id="<%= page_tag.page_id %>">
<%= link_to send("#{page_tag.page_type.downcase}_path", page_tag.page_id) do %>
<span class="<%= content_type.text_color %>">
<i class="material-icons left">
<%= content_type.icon %>
</i>
</span>
<span class="name-container">
<em>Loading <%= content_type.name %> name...</em>
</span>
<% end %>
<%= link_to destroy_specific_tag_path(page_tag), method: :delete, class: 'tooltipped', data: { tooltip: 'Remove this tag from this page' }, remote: true do %>
<i class="close material-icons">close</i>
<% end %>
</div>
<% end %>
</div>
</div>
<% end %>
</div>
</li>
<% end %>
</ul>
<% if !showed_any_tags %>
<div class="card-panel">
When you create tags for your pages, they'll appear here. Come back later when you've added some!
</div>
<% end %>

View File

@ -81,4 +81,4 @@
</div>
</div>
</div>
</div>
</div>

View File

@ -17,8 +17,7 @@
</a>
<div class="collapsible-body blue lighten-1">
<ul>
<%# TODO: we should use a cache here %>
<% (@current_user_content.fetch('Universe', []) + current_user.contributable_universes).sort_by(&:name).each do |universe| %>
<% @current_user_content.fetch('Universe', []).sort_by(&:name).each do |universe| %>
<li>
<%= link_to "?universe=#{universe.id}", class: 'waves-effect' do %>
<i class="material-icons <%= Universe.text_color %>">

View File

@ -98,6 +98,9 @@ Rails.application.routes.draw do
get '/scratchpad', to: 'main#notes', as: :notes
get 'tag/remove', to: 'page_tags#remove'
delete 'tag/:id/destroy', to: 'page_tags#destroy', as: :destroy_specific_tag
# Legacy route: left intact so /my/documents/X URLs continue to work for everyone's bookmarks
resources :documents
@ -133,6 +136,7 @@ Rails.application.routes.draw do
scope '/data' do
get '/', to: 'data#index', as: :data_vault
get '/usage', to: 'data#usage'
get '/tags', to: 'data#tags'
get '/recyclebin', to: 'data#recyclebin'
get '/archive', to: 'data#archive'
get '/documents', to: 'data#documents', as: :data_documents

View File

@ -0,0 +1,9 @@
require 'test_helper'
class PageTagsControllerTest < ActionDispatch::IntegrationTest
test "should get remove" do
get page_tags_remove_url
assert_response :success
end
end