Merge branch 'main' into consolidate-cards
* main: (31 commits) Style drafted cards Considering needs to include drafted cards or you'll never be able to see them This item makes no sense until it's saved Tighten engagement switch design, only display it for published cards Needed to come first In order of appearance Schema movement -- is this because the dumper doesnt sort deterministically? cc @flavorjones Move comments under cards Fix indention Refresh timers when morphing happens Extract helper for card articles, use classes to determine when to show golden status Only consider golden those cards in "doing" Fix recently completed order for good! Place recently closed cards first Monkey patch a prepend_order method Rename inconsistency: go with goldness Touch Use gild/ungild Format Fix test ...
This commit is contained in:
@@ -0,0 +1 @@
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m15.58 16.8-3.58-2.3-3.58 2.3 1.08-4.12-3.29-2.68 4.25-.26 1.54-3.94 1.54 3.94 4.25.26-3.29 2.68m5.5-.68c0-1.11.9-2 2-2v-4c0-1.11-.9-2-2-2h-16a2 2 0 0 0 -2 2v4c1.11 0 2 .9 2 2a2 2 0 0 1 -2 2v4a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-4a2 2 0 0 1 -2-2z"/></svg>
|
||||
|
After Width: | Height: | Size: 320 B |
@@ -1 +0,0 @@
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m12 18.5 7.5 4.5-2-8.5 6.6-5.7-8.7-.8-3.4-8-3.4 8-8.7.8 6.6 5.7-2 8.5z"/></svg>
|
||||
|
Before Width: | Height: | Size: 148 B |
@@ -42,6 +42,7 @@
|
||||
--lch-blue: 54% 0.15 255;
|
||||
--lch-blue-light: 95% 0.03 255;
|
||||
--lch-blue-dark: 80% 0.08 255;
|
||||
--lch-golden: 83% 0.1128 72.43;
|
||||
--lch-orange: 70% 0.2 44;
|
||||
--lch-red: 51% 0.2 31;
|
||||
--lch-green: 65.59% 0.234 142.49;
|
||||
@@ -69,6 +70,7 @@
|
||||
--color-always-black: oklch(var(--lch-always-black));
|
||||
--color-always-white: oklch(var(--lch-always-white));
|
||||
--color-container: oklch(var(--lch-light-blue));
|
||||
--color-golden: oklch(var(--lch-golden));
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
--lch-black: 100% 0 0;
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
&:has(input:checked) {
|
||||
--btn-background: var(--color-ink);
|
||||
--btn-color: var(--color-ink-reversed);
|
||||
@@ -188,5 +188,37 @@
|
||||
animation: zoom-fade 300ms ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
.btn__group {
|
||||
.btn {
|
||||
--btn-border-radius: 0;
|
||||
inline-size: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
form {
|
||||
flex: 1 1 0%;
|
||||
}
|
||||
|
||||
:first-of-type .btn {
|
||||
border-bottom-left-radius: 2em;
|
||||
border-inline-end: 0;
|
||||
border-top-left-radius: 2em;
|
||||
flex: 1 0 50%;
|
||||
padding-inline-end: 0.8em;
|
||||
}
|
||||
|
||||
:last-of-type .btn {
|
||||
border-bottom-right-radius: 2em;
|
||||
border-inline-start: 0;
|
||||
border-top-right-radius: 2em;
|
||||
flex: 1 0 50%;
|
||||
padding-inline-start: 0.8em;
|
||||
}
|
||||
|
||||
span {
|
||||
inline-size: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
.card--golden.card--doing {
|
||||
--border-color: var(--color-bg) !important;
|
||||
|
||||
background-color: var(--color-bg);
|
||||
background-image: linear-gradient(90deg, oklch(var(--lch-golden) / 0.5) 0%, oklch(var(--lch-golden) / 0.1) 50%, oklch(var(--lch-golden) / 0.75) 100%);
|
||||
box-shadow:
|
||||
0 0 0.5em 0.2em var(--color-golden),
|
||||
0 0 1em 0.4em var(--color-golden) !important;
|
||||
outline: 1px solid var(--color-golden);
|
||||
}
|
||||
|
||||
.card__background {
|
||||
inset: 0;
|
||||
position: absolute;
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
.icon--everyone { --svg: url("everyone.svg "); }
|
||||
.icon--filter { --svg: url("filter.svg "); }
|
||||
.icon--globe { --svg: url("globe.svg "); }
|
||||
.icon--golden-ticket { --svg: url("golden-ticket.svg "); }
|
||||
.icon--home { --svg: url("home.svg "); }
|
||||
.icon--logout { --svg: url("logout.svg "); }
|
||||
.icon--menu { --svg: url("menu.svg "); }
|
||||
@@ -61,7 +62,6 @@
|
||||
.icon--rename { --svg: url("rename.svg "); }
|
||||
.icon--settings { --svg: url("settings.svg "); }
|
||||
.icon--share { --svg: url("share.svg "); }
|
||||
.icon--star { --svg: url("star.svg "); }
|
||||
.icon--tag { --svg: url("tag.svg "); }
|
||||
.icon--thumb-up { --svg: url("thumb-up.svg "); }
|
||||
.icon--trash { --svg: url("trash.svg "); }
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
class Comments::ReactionsController < ApplicationController
|
||||
class Cards::Comments::ReactionsController < ApplicationController
|
||||
before_action :set_comment
|
||||
|
||||
def index
|
||||
@@ -12,7 +12,7 @@ class Comments::ReactionsController < ApplicationController
|
||||
@reaction = @comment.reactions.create!(reaction_params)
|
||||
|
||||
broadcast_create
|
||||
redirect_to collection_card_comment_reactions_url(@comment.card.collection, @comment.card, @comment)
|
||||
redirect_to card_comment_reactions_url(@comment.card, @comment)
|
||||
end
|
||||
|
||||
def destroy
|
||||
@@ -33,7 +33,7 @@ class Comments::ReactionsController < ApplicationController
|
||||
|
||||
def broadcast_create
|
||||
@reaction.broadcast_append_to @reaction.comment, :comments,
|
||||
target: "reactions_comment_#{@comment.id}", partial: "comments/reactions/reaction", locals: { comment: @comment }
|
||||
target: "reactions_comment_#{@comment.id}", partial: "cards/comments/reactions/reaction", locals: { comment: @comment }
|
||||
end
|
||||
|
||||
def broadcast_remove
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
class CommentsController < ApplicationController
|
||||
class Cards::CommentsController < ApplicationController
|
||||
include CardScoped
|
||||
before_action :set_comment, only: [ :show, :edit, :update, :destroy ]
|
||||
before_action :require_own_comment, only: [ :edit, :update, :destroy ]
|
||||
@@ -0,0 +1,13 @@
|
||||
class Cards::GoldnessesController < ApplicationController
|
||||
include CardScoped
|
||||
|
||||
def create
|
||||
@card.gild
|
||||
redirect_to @card
|
||||
end
|
||||
|
||||
def destroy
|
||||
@card.ungild
|
||||
redirect_to @card
|
||||
end
|
||||
end
|
||||
@@ -11,7 +11,7 @@ class CardsController < ApplicationController
|
||||
def index
|
||||
@considering = page_and_filter_for @filter.with(engagement_status: "considering", indexed_by: "latest"), per_page: PAGE_SIZE
|
||||
@doing = page_and_filter_for @filter.with(engagement_status: "doing", indexed_by: "latest"), per_page: PAGE_SIZE
|
||||
@closed = page_and_filter_for @filter.with(indexed_by: "closed"), per_page: PAGE_SIZE
|
||||
@closed = page_and_filter_for(@filter.with(indexed_by: "closed"), per_page: PAGE_SIZE) { |cards| cards.recently_closed_first }
|
||||
end
|
||||
|
||||
def create
|
||||
@@ -40,8 +40,10 @@ class CardsController < ApplicationController
|
||||
end
|
||||
|
||||
def page_and_filter_for(filter, per_page: nil)
|
||||
cards = block_given? ? yield(filter.cards) : filter.cards
|
||||
|
||||
OpenStruct.new \
|
||||
page: GearedPagination::Recordset.new(filter.cards, per_page:).page(1),
|
||||
page: GearedPagination::Recordset.new(cards, per_page:).page(1),
|
||||
filter: filter
|
||||
end
|
||||
|
||||
|
||||
@@ -26,4 +26,19 @@ module CardsHelper
|
||||
class: "btn txt-small",
|
||||
**options
|
||||
end
|
||||
|
||||
def card_article_tag(card, id: dom_id(card, :ticket), **options, &block)
|
||||
classes = [
|
||||
options.delete(:class),
|
||||
("card--golden" if card.golden?),
|
||||
("card--doing" if card.doing?)
|
||||
].compact.join(" ")
|
||||
|
||||
tag.article \
|
||||
id: id,
|
||||
style: "--card-color: #{card.color}; view-transition-name: #{id}",
|
||||
class: classes,
|
||||
**options,
|
||||
&block
|
||||
end
|
||||
end
|
||||
|
||||
@@ -24,6 +24,14 @@ export default class extends Controller {
|
||||
clearInterval(this.#timer)
|
||||
}
|
||||
|
||||
refreshAll() {
|
||||
this.constructor.targets.forEach(targetName => {
|
||||
this.targets.findAll(targetName).forEach(target => {
|
||||
this.#formatTime(this[`${targetName}Formatter`], target)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
timeTargetConnected(target) {
|
||||
this.#formatTime(this.timeFormatter, target)
|
||||
}
|
||||
|
||||
+4
-3
@@ -1,6 +1,7 @@
|
||||
class Card < ApplicationRecord
|
||||
include Assignable, Boostable, Colored, Commentable, Engageable, Eventable,
|
||||
Messages, Notifiable, Pinnable, Closeable, Scorable, Searchable, Staged, Statuses, Taggable, Watchable
|
||||
include Assignable, Boostable, Colored, Commentable, Engageable, Eventable, Golden,
|
||||
Messages, Notifiable, Pinnable, Closeable, Scorable, Searchable, Staged,
|
||||
Statuses, Taggable, Watchable
|
||||
|
||||
belongs_to :collection, touch: true
|
||||
belongs_to :creator, class_name: "User", default: -> { Current.user }
|
||||
@@ -34,7 +35,7 @@ class Card < ApplicationRecord
|
||||
scope :by_engagement_status, ->(status) do
|
||||
case status.to_s
|
||||
when "considering" then considering
|
||||
when "doing" then doing
|
||||
when "doing" then doing.with_golden_first
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ module Card::Engageable
|
||||
has_one :engagement, dependent: :destroy, class_name: "Card::Engagement"
|
||||
|
||||
scope :doing, -> { published.active.joins(:engagement) }
|
||||
scope :considering, -> { published.active.where.missing(:engagement) }
|
||||
scope :considering, -> { published_or_drafted_by(Current.user).active.where.missing(:engagement) }
|
||||
|
||||
scope :stagnated, -> { doing.where(last_active_at: ..STAGNATED_AFTER.ago) }
|
||||
end
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
module Card::Golden
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
scope :golden, -> { joins(:goldness) }
|
||||
|
||||
has_one :goldness, dependent: :destroy, class_name: "Card::Goldness"
|
||||
|
||||
scope :with_golden_first, -> { left_outer_joins(:goldness).prepend_order("card_goldnesses.id IS NULL") }
|
||||
end
|
||||
|
||||
def golden?
|
||||
goldness.present?
|
||||
end
|
||||
|
||||
def gild
|
||||
create_goldness! unless golden?
|
||||
end
|
||||
|
||||
def ungild
|
||||
goldness&.destroy
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
class Card::Goldness < ApplicationRecord
|
||||
belongs_to :card, touch: true
|
||||
end
|
||||
+18
-15
@@ -18,23 +18,26 @@ class Comment < ApplicationRecord
|
||||
card_comments.many? && card_comments_prior.last&.creator != creator
|
||||
end
|
||||
|
||||
private
|
||||
def to_partial_path
|
||||
"cards/#{super}"
|
||||
end
|
||||
|
||||
def cleanup_events
|
||||
# Delete events that reference through event_summary
|
||||
if message&.event_summary.present?
|
||||
Event.where(summary: message.event_summary).destroy_all
|
||||
private
|
||||
def cleanup_events
|
||||
# Delete events that reference through event_summary
|
||||
if message&.event_summary.present?
|
||||
Event.where(summary: message.event_summary).destroy_all
|
||||
end
|
||||
|
||||
# Delete events that reference directly in particulars
|
||||
Event.where(particulars: { comment_id: id }).destroy_all
|
||||
end
|
||||
|
||||
# Delete events that reference directly in particulars
|
||||
Event.where(particulars: { comment_id: id }).destroy_all
|
||||
end
|
||||
def card_comments_prior
|
||||
card_comments.where(created_at: ...created_at)
|
||||
end
|
||||
|
||||
def card_comments_prior
|
||||
card_comments.where(created_at: ...created_at)
|
||||
end
|
||||
|
||||
def card_comments
|
||||
Comment.joins(:message).where(messages: { card: card })
|
||||
end
|
||||
def card_comments
|
||||
Comment.joins(:message).where(messages: { card: card })
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<% if card.golden? %>
|
||||
<%= button_to card_goldness_path(card), method: :delete, class: "btn btn--reversed" do %>
|
||||
<%= icon_tag "golden-ticket" %>
|
||||
<span class="for-screen-reader">Demote to normal</span>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= button_to card_goldness_path(card), class: "btn" do %>
|
||||
<%= icon_tag "golden-ticket" %>
|
||||
<span class="for-screen-reader">Promote to golden</span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
@@ -1,6 +1,6 @@
|
||||
<%= messages_tag(card) do %>
|
||||
<%= render partial: "messages/message", collection: card.messages, cached: true %>
|
||||
<%= render "comments/new", card: card, cached: true %>
|
||||
<%= render "cards/comments/new", card: card, cached: true %>
|
||||
|
||||
<div class="comments__subscribers flex flex-column margin-block txt-align-start full-width">
|
||||
<strong class="txt-uppercase">Subscribers</strong>
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
<%= link_to comment.creator.name, user_path(comment.creator), class: "txt-ink btn btn--plain fill-transparent", data: { turbo_frame: "_top" } %>
|
||||
</strong>
|
||||
|
||||
<%= link_to collection_card_path(comment.card.collection, comment.card, anchor: "comment_#{comment.id}"), class: "txt-undecorated txt-uppercase" do %>
|
||||
<%= link_to card_path(comment.card, anchor: "comment_#{comment.id}"), class: "txt-undecorated txt-uppercase" do %>
|
||||
<%= local_datetime_tag comment.created_at, style: :shortdate, class: "txt-ink translucent" %>
|
||||
<% end %>
|
||||
|
||||
<%= link_to edit_collection_card_comment_path(comment.card.collection, comment.card, comment),
|
||||
<%= link_to edit_card_comment_path(comment.card, comment),
|
||||
class: "comment__edit btn btn--plain txt-xx-small fill-transparent translucent flex-item-justify-end" do %>
|
||||
<%= icon_tag "menu-dots-horizontal" %>
|
||||
<span class="for-screen-reader">Edit this comment</span>
|
||||
@@ -20,7 +20,7 @@
|
||||
<%= sanitize comment.body_html %>
|
||||
</div>
|
||||
|
||||
<%= render "comments/reactions/reactions", comment: comment %>
|
||||
<%= render "cards/comments/reactions/reactions", comment: comment %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
@@ -3,5 +3,5 @@
|
||||
<%= avatar_tag comment.creator, hidden_for_screen_reader: true %>
|
||||
</figure>
|
||||
|
||||
<%= render "comments/body", comment: comment %>
|
||||
<%= render "cards/comments/body", comment: comment %>
|
||||
<% end %>
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
<div class="comment__content flex-inline flex-column full-width">
|
||||
<div class="comment__body txt-align-start">
|
||||
<%= form_with model: Comment.new, url: collection_card_comments_path(card.collection, card), class: "flex flex-column gap full-width",
|
||||
<%= form_with model: Comment.new, url: card_comments_path(card), class: "flex flex-column gap full-width",
|
||||
data: { controller: "form paste local-save",
|
||||
local_save_key_value: "comment-#{card.id}",
|
||||
action: "turbo:submit-end->local-save#submit keydown.ctrl+enter->form#submit:prevent keydown.meta+enter->form#submit:prevent keydown.esc->form#cancel:stop paste->paste#pasteFiles" } do |form| %>
|
||||
@@ -1,14 +1,14 @@
|
||||
<%= turbo_frame_tag dom_id(@comment) do %>
|
||||
<div class="comment__content comment--edit flex-inline flex-column full-width">
|
||||
<div class="comment__body txt-align-start">
|
||||
<%= form_with model: [@card.collection, @card, @comment], class: "flex flex-column gap full-width",
|
||||
<%= form_with model: [ @card, @comment ], class: "flex flex-column gap full-width",
|
||||
data: { controller: "form paste", action: "keydown.ctrl+enter->form#submit:prevent keydown.meta+enter->form#submit:prevent keydown.esc->form#cancel:stop paste->paste#pasteFiles" } do |form| %>
|
||||
<%= form.markdown_area :body, class: "input comment__input", required: true, autofocus: true, placeholder: new_comment_placeholder(@card) %>
|
||||
<div class="flex gap-half justify-start">
|
||||
<%= form.button class: "btn btn--reversed", type: :submit do %>
|
||||
<span>Save changes</span>
|
||||
<% end %>
|
||||
<%= link_to collection_card_comment_path(@card.collection, @card, @comment), class: "btn", data: { form_target: "cancel" } do %>
|
||||
<%= link_to card_comment_path(@card, @comment), class: "btn", data: { form_target: "cancel" } do %>
|
||||
<span">Cancel</span>
|
||||
<% end %>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= form_with url: collection_card_comment_path(@card.collection, @card, @comment), method: :delete, id: dom_id(@comment, :delete_form), data: { turbo_frame: "_top" } %>
|
||||
<%= form_with url: card_comment_path(@card, @comment), method: :delete, id: dom_id(@comment, :delete_form), data: { turbo_frame: "_top" } %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
class: [ "txt-small", { "txt-medium": reaction.all_emoji? } ],
|
||||
data: { action: "click->reaction-delete#reveal keydown.enter->reaction-delete#reveal:prevent", reaction_delete_target: "content" } %>
|
||||
|
||||
<%= button_to collection_card_comment_reaction_path(comment.card.collection, comment.card, comment, reaction),
|
||||
<%= button_to card_comment_reaction_path(comment.card, comment, reaction),
|
||||
method: :delete,
|
||||
class: "btn btn--negative flex-item-justify-end reaction__delete",
|
||||
data: { action: "reaction-delete#perform", reaction_delete_target: "button" } do %>
|
||||
+2
-2
@@ -2,12 +2,12 @@
|
||||
<%= turbo_stream_from comment, :comments %>
|
||||
<div class="reactions flex flex-wrap align-center gap full-width">
|
||||
<div class="flex-inline flex-wrap gap" id="<%= dom_id(comment, :reactions) %>" data-turbo-streaming-target="container">
|
||||
<%= render partial: "comments/reactions/reaction", collection: comment.reactions.ordered, locals: { comment: comment }, cached: true %>
|
||||
<%= render partial: "cards/comments/reactions/reaction", collection: comment.reactions.ordered, locals: { comment: comment }, cached: true %>
|
||||
</div>
|
||||
|
||||
<%= turbo_frame_tag comment, :new_reaction do %>
|
||||
<div class="flex-inline" data-controller="soft-keyboard">
|
||||
<%= link_to new_collection_card_comment_reaction_path(comment.card.collection, comment.card, comment), role: "button",
|
||||
<%= link_to new_card_comment_reaction_path(comment.card, comment), role: "button",
|
||||
class: "btn reaction__action", action: "soft-keyboard#open" do %>
|
||||
<%= icon_tag "reaction" %>
|
||||
<span class="for-screen-reader">Add a reaction</span>
|
||||
@@ -0,0 +1 @@
|
||||
<%= render "cards/comments/reactions/reactions", comment: @comment %>
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
<%= turbo_frame_tag dom_id(@comment, :new_reaction) do %>
|
||||
<%= form_with url: collection_card_comment_reactions_path(@comment.card.collection, @comment.card, @comment),
|
||||
<%= form_with url: card_comment_reactions_path(@comment.card, @comment),
|
||||
class: "reaction reaction__form flex-inline postion--relative max-width align-center fill-white gap expanded",
|
||||
html: { aria: { label: "New reaction" } },
|
||||
data: { controller: "form", turbo_frame: dom_id(@comment, :reacting), action: "keydown.esc->form#cancel" } do |form| %>
|
||||
@@ -17,7 +17,7 @@
|
||||
<span class="for-screen-reader">Submit</span>
|
||||
<% end %>
|
||||
|
||||
<%= link_to collection_card_comment_reactions_path(@comment.card.collection, @comment.card, @comment), role: "button",
|
||||
<%= link_to card_comment_reactions_path(@comment.card, @comment), role: "button",
|
||||
data: { turbo_frame: dom_id(@comment, :reactions), form_target: "cancel" }, class: "btn btn--negative" do %>
|
||||
<%= icon_tag "minus" %>
|
||||
<span class="for-screen-reader">Cancel</span>
|
||||
@@ -0,0 +1 @@
|
||||
<%= render "cards/comments/body", comment: @comment %>
|
||||
@@ -0,0 +1 @@
|
||||
<%= render "cards/comments/body", comment: @comment %>
|
||||
@@ -1,5 +1,5 @@
|
||||
<% cache card do %>
|
||||
<article class="card" style="--card-color: <%= card.color %>; view-transition-name: <%= dom_id(card, :ticket) %>;" id="<%= dom_id(card, :ticket) %>">
|
||||
<%= card_article_tag card, class: "card" do %>
|
||||
<header class="card__header flex align-center gap min-width">
|
||||
<%= link_to card.collection.name, cards_path(collection_ids: [card.collection]),
|
||||
class: "card__collection txt-uppercase overflow-ellipsis txt-reversed" %>
|
||||
@@ -35,5 +35,5 @@
|
||||
</footer>
|
||||
|
||||
<%= render "cards/display/common/background", card: card %>
|
||||
</article>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<% cache [ card ] do %>
|
||||
<article class="card"
|
||||
style="--card-color: <%= card.color %>; view-transition-name: <%= dom_id(card, :ticket) %>;"
|
||||
id="<%= dom_id(card, :ticket) %>">
|
||||
<%= card_article_tag card, class: "card" do %>
|
||||
<header class="card__header flex align-center gap min-width">
|
||||
<span class="card__collection txt-uppercase overflow-ellipsis txt-reversed"><%= card.collection.name %></span>
|
||||
<%= render "cards/display/preview/tags", card: card %>
|
||||
@@ -24,5 +22,5 @@
|
||||
</footer>
|
||||
|
||||
<%= render "cards/display/common/background", card: card %>
|
||||
</article>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -4,10 +4,17 @@
|
||||
<div class="card__meta-grid">
|
||||
<span class="card__meta-item card__meta-item--added overflow-ellipsis">
|
||||
Added <%= local_datetime_tag(card.created_at, style: :daysago) %>
|
||||
<% if card.drafted? %>
|
||||
<strong>(Draft)</strong>
|
||||
<% end %>
|
||||
</span>
|
||||
<span class="card__meta-item card__meta-item--updated overflow-ellipsis">
|
||||
<%= card.creating? ? "Created" : "Updated" %>
|
||||
<%= local_datetime_tag(card.updated_at, style: :daysago) %>
|
||||
<% if card.creating? %>
|
||||
|
||||
<% else %>
|
||||
Updated
|
||||
<%= local_datetime_tag(card.updated_at, style: :daysago) %>
|
||||
<% end %>
|
||||
</span>
|
||||
<span class="card__meta-item card__meta-item--reported overflow-ellipsis">
|
||||
Reported by <strong><%= familiar_name_for(card.creator) %></strong>
|
||||
|
||||
@@ -31,11 +31,7 @@
|
||||
<%= render "cards/doing_toggle", card: @card %>
|
||||
|
||||
<aside class="card-perma__actions card-perma__actions--left" role="toolbar">
|
||||
<button class="btn">
|
||||
<%= icon_tag "star" %>
|
||||
<span class="for-screen-reader">Star this card</span>
|
||||
<input type="checkbox" class="card-perma__star-input">
|
||||
</button>
|
||||
<%= render "cards/golden_toggle", card: @card if @card.doing? %>
|
||||
<%= render "cards/image", card: @card %>
|
||||
<%= button_to collection_card_path(@card.collection, @card),
|
||||
method: :delete,
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<%= render "comments/reactions/reactions", comment: @comment %>
|
||||
@@ -1 +0,0 @@
|
||||
<%= render "comments/body", comment: @comment %>
|
||||
@@ -1 +0,0 @@
|
||||
<%= render "comments/body", comment: @comment %>
|
||||
@@ -25,7 +25,7 @@
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
|
||||
</head>
|
||||
|
||||
<body data-controller="lightbox local-time timezone-cookie">
|
||||
<body data-controller="lightbox local-time timezone-cookie" data-action="turbo:morph@window->local-time#refreshAll">
|
||||
<header id="header">
|
||||
<a href="#main-content" class="skip-navigation btn">Skip to main content</a>
|
||||
<%= yield :header %>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<% cache message do %>
|
||||
<%# Template Dependency: comments/comment %>
|
||||
<%# Template Dependency: cards/comments/comment %>
|
||||
<%# Template Dependency: event_summaries/event_summary %>
|
||||
<%= render partial: message.messageable.to_partial_path, object: message.messageable %>
|
||||
<% end %>
|
||||
|
||||
+30
-24
@@ -8,6 +8,16 @@ Rails.application.routes.draw do
|
||||
end
|
||||
end
|
||||
|
||||
resources :collections do
|
||||
scope module: :collections do
|
||||
resource :subscriptions
|
||||
resource :workflow, only: :update
|
||||
resource :involvement
|
||||
end
|
||||
|
||||
resources :cards
|
||||
end
|
||||
|
||||
namespace :cards do
|
||||
resources :previews
|
||||
end
|
||||
@@ -22,14 +32,20 @@ Rails.application.routes.draw do
|
||||
resource :reading
|
||||
resource :recover
|
||||
resource :watch
|
||||
resource :goldness
|
||||
|
||||
resources :assignments
|
||||
resources :boosts
|
||||
resources :stagings
|
||||
resources :taggings
|
||||
|
||||
resources :comments do
|
||||
resources :reactions, module: :comments
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
resources :notifications, only: :index
|
||||
namespace :notifications do
|
||||
resource :tray, only: :show
|
||||
@@ -44,19 +60,7 @@ Rails.application.routes.draw do
|
||||
end
|
||||
end
|
||||
|
||||
resources :collections do
|
||||
scope module: :collections do
|
||||
resource :subscriptions
|
||||
resource :workflow, only: :update
|
||||
resource :involvement
|
||||
end
|
||||
|
||||
resources :cards do
|
||||
resources :comments do
|
||||
resources :reactions, module: :comments
|
||||
end
|
||||
end
|
||||
end
|
||||
resources :filters
|
||||
|
||||
resources :events, only: :index
|
||||
namespace :events do
|
||||
@@ -67,12 +71,15 @@ Rails.application.routes.draw do
|
||||
resources :stages, module: :workflows
|
||||
end
|
||||
|
||||
resources :filters
|
||||
resources :qr_codes
|
||||
resources :uploads, only: :create
|
||||
get "/u/*slug" => "uploads#show", as: :upload
|
||||
|
||||
namespace :my do
|
||||
resources :pins
|
||||
end
|
||||
resource :terminal, only: [ :show, :edit ]
|
||||
|
||||
|
||||
resources :qr_codes
|
||||
get "join/:join_code", to: "users#new", as: :join
|
||||
post "join/:join_code", to: "users#create"
|
||||
|
||||
resource :session do
|
||||
scope module: "sessions" do
|
||||
@@ -86,8 +93,10 @@ Rails.application.routes.draw do
|
||||
end
|
||||
end
|
||||
|
||||
get "join/:join_code", to: "users#new", as: :join
|
||||
post "join/:join_code", to: "users#create"
|
||||
namespace :my do
|
||||
resources :pins
|
||||
end
|
||||
|
||||
|
||||
resolve "Card" do |card, options|
|
||||
route_for :collection_card, card.collection, card, options
|
||||
@@ -98,13 +107,10 @@ Rails.application.routes.draw do
|
||||
route_for :collection_card, comment.card.collection, comment.card, options
|
||||
end
|
||||
|
||||
|
||||
get "up", to: "rails/health#show", as: :rails_health_check
|
||||
get "manifest" => "rails/pwa#manifest", as: :pwa_manifest
|
||||
|
||||
resources :uploads, only: :create
|
||||
get "/u/*slug" => "uploads#show", as: :upload
|
||||
|
||||
resource :terminal, only: [ :show, :edit ]
|
||||
|
||||
root "events#index"
|
||||
end
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
class CreateCardGoldnesses < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
create_table :card_goldnesses do |t|
|
||||
t.references :card, null: false, foreign_key: true, index: { unique: true }
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
Generated
+9
-1
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.1].define(version: 2025_04_09_201424) do
|
||||
ActiveRecord::Schema[8.1].define(version: 2025_04_10_141409) do
|
||||
create_table "accesses", force: :cascade do |t|
|
||||
t.integer "collection_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
@@ -102,6 +102,13 @@ ActiveRecord::Schema[8.1].define(version: 2025_04_09_201424) do
|
||||
t.index ["card_id"], name: "index_card_engagements_on_card_id"
|
||||
end
|
||||
|
||||
create_table "card_goldnesses", force: :cascade do |t|
|
||||
t.integer "card_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["card_id"], name: "index_card_goldnesses_on_card_id", unique: true
|
||||
end
|
||||
|
||||
create_table "cards", force: :cascade do |t|
|
||||
t.float "activity_score", default: 0.0, null: false
|
||||
t.datetime "activity_score_at"
|
||||
@@ -333,6 +340,7 @@ ActiveRecord::Schema[8.1].define(version: 2025_04_09_201424) do
|
||||
|
||||
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
|
||||
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
|
||||
add_foreign_key "card_goldnesses", "cards"
|
||||
add_foreign_key "cards", "workflow_stages", column: "stage_id"
|
||||
add_foreign_key "closures", "cards"
|
||||
add_foreign_key "closures", "users"
|
||||
|
||||
+96
-72
@@ -21,7 +21,7 @@ columns:
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
- &23 !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
- &24 !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: collection_id
|
||||
cast_type: *1
|
||||
@@ -50,26 +50,6 @@ columns:
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: involvement
|
||||
cast_type: &7 !ruby/object:ActiveModel::Type::String
|
||||
true: t
|
||||
false: f
|
||||
precision:
|
||||
scale:
|
||||
limit:
|
||||
sql_type_metadata: &8 !ruby/object:ActiveRecord::ConnectionAdapters::SqlTypeMetadata
|
||||
sql_type: varchar
|
||||
type: :string
|
||||
limit:
|
||||
precision:
|
||||
scale:
|
||||
'null': false
|
||||
default: watching
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
- &9 !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: updated_at
|
||||
@@ -90,6 +70,26 @@ columns:
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: involvement
|
||||
cast_type: &7 !ruby/object:ActiveModel::Type::String
|
||||
true: t
|
||||
false: f
|
||||
precision:
|
||||
scale:
|
||||
limit:
|
||||
sql_type_metadata: &8 !ruby/object:ActiveRecord::ConnectionAdapters::SqlTypeMetadata
|
||||
sql_type: varchar
|
||||
type: :string
|
||||
limit:
|
||||
precision:
|
||||
scale:
|
||||
'null': false
|
||||
default: watching
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
accounts:
|
||||
- *5
|
||||
- *6
|
||||
@@ -341,7 +341,7 @@ columns:
|
||||
- *5
|
||||
- *19
|
||||
- *20
|
||||
- &24 !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
- &21 !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: card_id
|
||||
cast_type: *1
|
||||
@@ -367,16 +367,21 @@ columns:
|
||||
comment:
|
||||
- *6
|
||||
- *9
|
||||
card_goldnesses:
|
||||
- *5
|
||||
- *21
|
||||
- *6
|
||||
- *9
|
||||
cards:
|
||||
- *5
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: activity_score
|
||||
cast_type: &21 !ruby/object:ActiveModel::Type::Float
|
||||
cast_type: &22 !ruby/object:ActiveModel::Type::Float
|
||||
precision:
|
||||
scale:
|
||||
limit:
|
||||
sql_type_metadata: &22 !ruby/object:ActiveRecord::ConnectionAdapters::SqlTypeMetadata
|
||||
sql_type_metadata: &23 !ruby/object:ActiveRecord::ConnectionAdapters::SqlTypeMetadata
|
||||
sql_type: float
|
||||
type: :float
|
||||
limit:
|
||||
@@ -400,8 +405,8 @@ columns:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: activity_score_order
|
||||
cast_type: *21
|
||||
sql_type_metadata: *22
|
||||
cast_type: *22
|
||||
sql_type_metadata: *23
|
||||
'null': false
|
||||
default: 0.0
|
||||
default_function:
|
||||
@@ -417,7 +422,7 @@ columns:
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
- *23
|
||||
- *24
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: comments_count
|
||||
@@ -458,16 +463,6 @@ columns:
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: last_active_at
|
||||
cast_type: *3
|
||||
sql_type_metadata: *4
|
||||
'null': false
|
||||
default:
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: stage_id
|
||||
@@ -499,6 +494,16 @@ columns:
|
||||
collation:
|
||||
comment:
|
||||
- *9
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: last_active_at
|
||||
cast_type: *3
|
||||
sql_type_metadata: *4
|
||||
'null': false
|
||||
default:
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
closure_reasons:
|
||||
- *5
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
@@ -511,7 +516,6 @@ columns:
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
- *6
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: label
|
||||
@@ -522,21 +526,12 @@ columns:
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
- *6
|
||||
- *9
|
||||
closures:
|
||||
- *5
|
||||
- *24
|
||||
- *21
|
||||
- *6
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: reason
|
||||
cast_type: *7
|
||||
sql_type_metadata: *8
|
||||
'null': false
|
||||
default:
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
- *9
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
@@ -548,6 +543,16 @@ columns:
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
name: reason
|
||||
cast_type: *7
|
||||
sql_type_metadata: *8
|
||||
'null': false
|
||||
default:
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
collections:
|
||||
- *5
|
||||
- &32 !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
@@ -593,7 +598,7 @@ columns:
|
||||
collation:
|
||||
comment:
|
||||
collections_filters:
|
||||
- *23
|
||||
- *24
|
||||
- *18
|
||||
comments:
|
||||
- *5
|
||||
@@ -619,7 +624,7 @@ columns:
|
||||
default_function:
|
||||
collation:
|
||||
comment:
|
||||
- *24
|
||||
- *21
|
||||
- *6
|
||||
- *25
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
@@ -712,7 +717,7 @@ columns:
|
||||
comment:
|
||||
messages:
|
||||
- *5
|
||||
- *24
|
||||
- *21
|
||||
- *6
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
@@ -737,7 +742,7 @@ columns:
|
||||
- *9
|
||||
notifications:
|
||||
- *5
|
||||
- *24
|
||||
- *21
|
||||
- *6
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||
auto_increment:
|
||||
@@ -783,7 +788,7 @@ columns:
|
||||
- *30
|
||||
pins:
|
||||
- *5
|
||||
- *24
|
||||
- *21
|
||||
- *6
|
||||
- *9
|
||||
- *30
|
||||
@@ -869,7 +874,7 @@ columns:
|
||||
- *30
|
||||
taggings:
|
||||
- *5
|
||||
- *24
|
||||
- *21
|
||||
- *6
|
||||
- *31
|
||||
- *9
|
||||
@@ -927,7 +932,7 @@ columns:
|
||||
- *9
|
||||
watches:
|
||||
- *5
|
||||
- *24
|
||||
- *21
|
||||
- *6
|
||||
- *9
|
||||
- *30
|
||||
@@ -984,6 +989,7 @@ primary_keys:
|
||||
assigners_filters:
|
||||
assignments: id
|
||||
card_engagements: id
|
||||
card_goldnesses: id
|
||||
cards: id
|
||||
closure_reasons: id
|
||||
closures: id
|
||||
@@ -1020,6 +1026,7 @@ data_sources:
|
||||
assigners_filters: true
|
||||
assignments: true
|
||||
card_engagements: true
|
||||
card_goldnesses: true
|
||||
cards: true
|
||||
closure_reasons: true
|
||||
closures: true
|
||||
@@ -1351,6 +1358,23 @@ indexes:
|
||||
nulls_not_distinct:
|
||||
comment:
|
||||
valid: true
|
||||
card_goldnesses:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: card_goldnesses
|
||||
name: index_card_goldnesses_on_card_id
|
||||
unique: true
|
||||
columns:
|
||||
- card_id
|
||||
lengths: {}
|
||||
orders: {}
|
||||
opclasses: {}
|
||||
where:
|
||||
type:
|
||||
using:
|
||||
include:
|
||||
nulls_not_distinct:
|
||||
comment:
|
||||
valid: true
|
||||
cards:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: cards
|
||||
@@ -1386,11 +1410,10 @@ indexes:
|
||||
valid: true
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: cards
|
||||
name: index_cards_on_last_active_at_and_status
|
||||
name: index_cards_on_stage_id
|
||||
unique: false
|
||||
columns:
|
||||
- last_active_at
|
||||
- status
|
||||
- stage_id
|
||||
lengths: {}
|
||||
orders: {}
|
||||
opclasses: {}
|
||||
@@ -1403,10 +1426,11 @@ indexes:
|
||||
valid: true
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: cards
|
||||
name: index_cards_on_stage_id
|
||||
name: index_cards_on_last_active_at_and_status
|
||||
unique: false
|
||||
columns:
|
||||
- stage_id
|
||||
- last_active_at
|
||||
- status
|
||||
lengths: {}
|
||||
orders: {}
|
||||
opclasses: {}
|
||||
@@ -1437,10 +1461,11 @@ indexes:
|
||||
closures:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: closures
|
||||
name: index_closures_on_card_id
|
||||
unique: true
|
||||
name: index_closures_on_card_id_and_created_at
|
||||
unique: false
|
||||
columns:
|
||||
- card_id
|
||||
- created_at
|
||||
lengths: {}
|
||||
orders: {}
|
||||
opclasses: {}
|
||||
@@ -1453,11 +1478,10 @@ indexes:
|
||||
valid: true
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: closures
|
||||
name: index_closures_on_card_id_and_created_at
|
||||
unique: false
|
||||
name: index_closures_on_card_id
|
||||
unique: true
|
||||
columns:
|
||||
- card_id
|
||||
- created_at
|
||||
lengths: {}
|
||||
orders: {}
|
||||
opclasses: {}
|
||||
@@ -1993,10 +2017,11 @@ indexes:
|
||||
tags:
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: tags
|
||||
name: index_tags_on_account_id
|
||||
unique: false
|
||||
name: index_tags_on_account_id_and_title
|
||||
unique: true
|
||||
columns:
|
||||
- account_id
|
||||
- title
|
||||
lengths: {}
|
||||
orders: {}
|
||||
opclasses: {}
|
||||
@@ -2009,11 +2034,10 @@ indexes:
|
||||
valid: true
|
||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||
table: tags
|
||||
name: index_tags_on_account_id_and_title
|
||||
unique: true
|
||||
name: index_tags_on_account_id
|
||||
unique: false
|
||||
columns:
|
||||
- account_id
|
||||
- title
|
||||
lengths: {}
|
||||
orders: {}
|
||||
opclasses: {}
|
||||
@@ -2140,4 +2164,4 @@ indexes:
|
||||
nulls_not_distinct:
|
||||
comment:
|
||||
valid: true
|
||||
version: 20250409201424
|
||||
version: 20250410141409
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
module ActiveRecordRelationPrependOrder
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
def prepend_order(*args)
|
||||
new_orders = args.flatten.map { |arg| arg.is_a?(String) ? arg : arg.to_sql }
|
||||
|
||||
spawn.tap do |relation|
|
||||
relation.order_values = new_orders + order_values
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ActiveRecord::Relation.include(ActiveRecordRelationPrependOrder)
|
||||
ActiveRecord::AssociationRelation.include(ActiveRecordRelationPrependOrder)
|
||||
@@ -0,0 +1,26 @@
|
||||
require "test_helper"
|
||||
|
||||
class Cards::Comments::ReactionsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in_as :jz
|
||||
@comment = comments(:logo_agreement_jz)
|
||||
end
|
||||
|
||||
test "create" do
|
||||
assert_turbo_stream_broadcasts [ @comment, :comments ], count: 1 do
|
||||
assert_difference -> { @comment.reactions.count }, 1 do
|
||||
post card_comment_reactions_url(@comment.card, @comment, format: :turbo_stream), params: { reaction: { content: "Great work!" } }
|
||||
assert_redirected_to card_comment_reactions_url(@comment.card, @comment)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "destroy" do
|
||||
assert_turbo_stream_broadcasts [ @comment, :comments ], count: 1 do
|
||||
assert_difference -> { @comment.reactions.count }, -1 do
|
||||
delete card_comment_reaction_url(@comment.card, @comment, reactions(:kevin), format: :turbo_stream)
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
require "test_helper"
|
||||
|
||||
class Cards::CommentsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in_as :kevin
|
||||
end
|
||||
|
||||
test "create" do
|
||||
assert_difference "cards(:logo).messages.comments.count", +1 do
|
||||
post card_comments_url(cards(:logo), params: { comment: { body: "Agreed." } })
|
||||
end
|
||||
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "update" do
|
||||
put card_comment_url(cards(:logo), comments(:logo_agreement_kevin)), params: { comment: { body: "I've changed my mind" } }
|
||||
|
||||
assert_response :success
|
||||
assert_equal "I've changed my mind", comments(:logo_agreement_kevin).reload.body.content
|
||||
end
|
||||
|
||||
test "update another user's comment" do
|
||||
assert_no_changes "comments(:logo_agreement_jz).body.content" do
|
||||
put card_comment_url(cards(:logo), comments(:logo_agreement_jz)), params: { comment: { body: "I've changed my mind" } }
|
||||
end
|
||||
|
||||
assert_response :forbidden
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,27 @@
|
||||
require "test_helper"
|
||||
|
||||
class Cards::GoldnessesControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in_as :kevin
|
||||
end
|
||||
|
||||
test "create" do
|
||||
card = cards(:text)
|
||||
|
||||
assert_changes -> { card.reload.golden? }, from: false, to: true do
|
||||
post card_goldness_url(card)
|
||||
end
|
||||
|
||||
assert_redirected_to collection_card_url(card.collection, card)
|
||||
end
|
||||
|
||||
test "destroy" do
|
||||
card = cards(:logo)
|
||||
|
||||
assert_changes -> { card.reload.golden? }, from: true, to: false do
|
||||
delete card_goldness_url(card)
|
||||
end
|
||||
|
||||
assert_redirected_to collection_card_url(card.collection, card)
|
||||
end
|
||||
end
|
||||
@@ -1,30 +0,0 @@
|
||||
require "test_helper"
|
||||
|
||||
class CommentsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in_as :kevin
|
||||
end
|
||||
|
||||
test "create" do
|
||||
assert_difference "cards(:logo).messages.comments.count", +1 do
|
||||
post collection_card_comments_url(collections(:writebook), cards(:logo), params: { comment: { body: "Agreed." } })
|
||||
end
|
||||
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "update" do
|
||||
put collection_card_comment_url(collections(:writebook), cards(:logo), comments(:logo_agreement_kevin)), params: { comment: { body: "I've changed my mind" } }
|
||||
|
||||
assert_response :success
|
||||
assert_equal "I've changed my mind", comments(:logo_agreement_kevin).reload.body.content
|
||||
end
|
||||
|
||||
test "update another user's comment" do
|
||||
assert_no_changes "comments(:logo_agreement_jz).body.content" do
|
||||
put collection_card_comment_url(collections(:writebook), cards(:logo), comments(:logo_agreement_jz)), params: { comment: { body: "I've changed my mind" } }
|
||||
end
|
||||
|
||||
assert_response :forbidden
|
||||
end
|
||||
end
|
||||
@@ -1,26 +0,0 @@
|
||||
require "test_helper"
|
||||
|
||||
class Comments::ReactionsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in_as :jz
|
||||
@comment = comments(:logo_agreement_jz)
|
||||
end
|
||||
|
||||
test "create" do
|
||||
assert_turbo_stream_broadcasts [ @comment, :comments ], count: 1 do
|
||||
assert_difference -> { @comment.reactions.count }, 1 do
|
||||
post collection_card_comment_reactions_url(@comment.card.collection, @comment.card, @comment, format: :turbo_stream), params: { reaction: { content: "Great work!" } }
|
||||
assert_redirected_to collection_card_comment_reactions_url(@comment.card.collection, @comment.card, @comment)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "destroy" do
|
||||
assert_turbo_stream_broadcasts [ @comment, :comments ], count: 1 do
|
||||
assert_difference -> { @comment.reactions.count }, -1 do
|
||||
delete collection_card_comment_reaction_url(@comment.card.collection, @comment.card, @comment, reactions(:kevin), format: :turbo_stream)
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Vendored
+1
-1
@@ -1,2 +1,2 @@
|
||||
logo_engagement:
|
||||
logo:
|
||||
card: logo
|
||||
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
logo:
|
||||
card: logo
|
||||
@@ -0,0 +1,27 @@
|
||||
require "test_helper"
|
||||
|
||||
class Card::GoldenTest < ActiveSupport::TestCase
|
||||
setup do
|
||||
Current.session = sessions(:david)
|
||||
end
|
||||
|
||||
test "check whether a card is golden" do
|
||||
assert cards(:logo).golden?
|
||||
assert_not cards(:text).golden?
|
||||
end
|
||||
|
||||
test "promote and demote from golden" do
|
||||
assert_changes -> { cards(:text).reload.golden? }, to: true do
|
||||
cards(:text).gild
|
||||
end
|
||||
|
||||
assert_changes -> { cards(:logo).reload.golden? }, to: false do
|
||||
cards(:logo).ungild
|
||||
end
|
||||
end
|
||||
|
||||
test "scopes" do
|
||||
assert_includes Card.golden, cards(:logo)
|
||||
assert_not_includes Card.golden, cards(:text)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user