Revert "Add a description field for cards"

This commit is contained in:
Jorge Manrubia
2025-04-21 16:41:33 +02:00
committed by GitHub
parent 4d1a1382e1
commit a4cc143b09
24 changed files with 190 additions and 131 deletions
-1
View File
@@ -96,7 +96,6 @@
border-color: var(--card-color) !important;
border-style: dashed !important;
box-shadow: none !important;
}
.card__background {
+26 -6
View File
@@ -100,7 +100,7 @@
z-index: 1;
}
.btn:not(.popup__item, .btn--plain, .btn--reversed) {
.btn:not(.popup__item, .btn--plain) {
--btn-background: var(--card-color);
--btn-color: var(--color-ink-reversed);
}
@@ -110,11 +110,6 @@
text-decoration: underline;
}
.btn--reversed {
--btn-background: var(--color-bg);
--btn-color: var(--card-color);
}
}
.card-perma__closure-message {
@@ -124,4 +119,29 @@
padding-left: 1ch;
}
}
/* Variants
/* ------------------------------------------------------------------------ */
.card-perma--pointing {
--arrow-size: 20em;
--aspect-ratio: 7;
position: relative;
margin-block-end: calc(var(--arrow-size) / var(--aspect-ratio));
&::after {
aspect-ratio: var(--aspect-ratio);
background-color: var(--color-container);
clip-path: polygon(50% 100%, 100% 0, 0 0);
inline-size: var(--arrow-size);
content: "";
display: block;
inset-block-start: 99%;
inset-inline-start: 50%;
position: absolute;
transform: translateX(-50%);
z-index: -1;
}
}
}
+6 -28
View File
@@ -99,42 +99,18 @@
padding-block: var(--card-padding-block);
}
.card__description {
house-md-toolbar,
.house-md-content {
color: color-mix(in srgb, var(--card-color) 40%, var(--color-ink));
}
.house-md-content {
min-block-size: 3lh;
padding: var(--block-space-half) var(--inline-space) 0 0;
}
& ~ .btn {
--btn-background: var(--card-color);
--btn-color: var(--color-ink-reversed);
}
}
.card__title {
--hover-size: 0;
--input-border-radius: 0;
--input-color: color-mix(in srgb, var(--card-color) 40%, var(--color-ink));
--lines: 3;
color: inherit;
flex: 2 1 75%;
font-size: var(--text-xx-large);
font-weight: 900;
line-height: 1.2;
line-height: 1.1;
min-block-size: 3lh;
text-wrap: balance;
.card-perma__bg & {
min-block-size: unset;
}
.card-field__title {
.card__title-field {
&:is(textarea)::placeholder {
color: inherit;
opacity: 0.5;
@@ -142,6 +118,8 @@
}
.card__title-link {
--lines: 3;
color: inherit;
}
}
@@ -152,11 +130,11 @@
flex-direction: column;
max-width: 100%;
min-width: 0;
padding-block: var(--block-space-half);
padding-block: var(--block-space);
}
.card__move-button {
--btn-background: color-mix(in srgb, inherit 40%, var(--color-ink));
--btn-background: color-mix(in srgb, var(--card-color) 40%, var(--color-ink));
margin-block-start: calc(var(--block-space) * 1.2);
margin-inline-end: calc(var(--inline-space) * -4);
-1
View File
@@ -68,7 +68,6 @@
padding:
var(--comment-padding-block)
var(--comment-padding-inline);
word-wrap: break-word;
}
.comment__edit {
+2 -1
View File
@@ -58,6 +58,7 @@
/* Markdown Content */
.house-md-content {
caret-color: var(--color-link);
flex-grow: 1;
font-family: var(--font-sans);
text-align: left;
@@ -66,7 +67,7 @@
&.house-md-content-empty::before {
content: attr(placeholder);
color: currentColor;
color: var(--color-ink);
opacity: 0.5;
pointer-events: none;
display: block;
+1 -1
View File
@@ -54,7 +54,7 @@ class CardsController < ApplicationController
end
def card_params
params.expect(card: [ :status, :title, :description, :image, tag_ids: [] ])
params.expect(card: [ :status, :title, :color, :due_on, :image, :draft_comment, tag_ids: [] ])
end
def render_card_replacement
+1 -2
View File
@@ -19,8 +19,7 @@ module CardsHelper
classes = [
options.delete(:class),
("card--golden" if card.golden?),
("card--doing" if card.doing?),
("card--drafted" if card.drafted?)
("card--doing" if card.doing?)
].compact.join(" ")
tag.article \
+1 -3
View File
@@ -1,5 +1,5 @@
class Card < ApplicationRecord
include Assignable, Colored, Engageable, Eventable, Golden,
include Assignable, Colored, DraftCommenting, Engageable, Eventable, Golden,
Messages, Notifiable, Pinnable, Closeable, Searchable, Staged,
Statuses, Taggable, Watchable
@@ -10,8 +10,6 @@ class Card < ApplicationRecord
has_one_attached :image, dependent: :purge_later
has_markdown :description
scope :reverse_chronologically, -> { order created_at: :desc, id: :desc }
scope :chronologically, -> { order created_at: :asc, id: :asc }
scope :latest, -> { order updated_at: :desc, id: :desc }
+33
View File
@@ -0,0 +1,33 @@
module Card::DraftCommenting
extend ActiveSupport::Concern
included do
after_save :capture_draft_comment
end
def draft_comment
find_or_build_initial_comment.body.content
end
def draft_comment=(body)
if body.present?
@draft_comment = body
else
messages.comments.destroy_all
end
end
private
def find_or_build_initial_comment
message = messages.comments.first || messages.new(messageable: Comment.new)
message.comment
end
def capture_draft_comment
if @draft_comment.present?
find_or_build_initial_comment.update! body: @draft_comment, creator: creator
end
@draft_comment = nil
end
end
+17 -23
View File
@@ -4,7 +4,7 @@ module Card::Searchable
included do
include ::Searchable
searchable_by :title_and_description, using: :cards_search_index, as: :title
searchable_by :title, using: :cards_search_index
scope :mentioning, ->(query) do
if query = sanitize_query_syntax(query)
@@ -18,31 +18,25 @@ module Card::Searchable
end
end
class_methods do
def sanitize_query_syntax(terms)
terms = terms.to_s
terms = remove_invalid_search_characters(terms)
terms = remove_unbalanced_quotes(terms)
terms.presence
end
private
def remove_invalid_search_characters(terms)
terms.gsub(/[^\w"]/, " ")
class_methods do
def sanitize_query_syntax(terms)
terms = terms.to_s
terms = remove_invalid_search_characters(terms)
terms = remove_unbalanced_quotes(terms)
terms.presence
end
def remove_unbalanced_quotes(terms)
if terms.count("\"").even?
terms
else
terms.gsub("\"", " ")
private
def remove_invalid_search_characters(terms)
terms.gsub(/[^\w"]/, " ")
end
end
end
private
# TODO: Temporary until we stabilize the search API
def title_and_description
[ title, description.to_plain_text ].join(" ")
def remove_unbalanced_quotes(terms)
if terms.count("\"").even?
terms
else
terms.gsub("\"", " ")
end
end
end
end
+7 -5
View File
@@ -1,9 +1,8 @@
<section id="<%= dom_id(card, :card_container) %>"
class="card-perma" style="--card-color: <%= card.color %>;">
class="card-perma <%= "card-perma--pointing" unless card.published? %>" style="--card-color: <%= card.color %>;">
<%= render "cards/container/engagement", card: card %>
<aside class="card-perma__actions card-perma__actions--left" role="toolbar">
<%= render "cards/container/edit", card: card if card.published? %>
<%= render "cards/container/gild", card: card if card.doing? %>
<%= render "cards/container/image", card: card %>
@@ -33,8 +32,11 @@
</div>
<% if card.published? %>
<%= render "cards/container/footer/published", card: card %>
<% elsif card.creating? %>
<%= render "cards/container/footer/draft", card: card %>
<aside class="card-perma__actions card-perma__actions--right" role="toolbar">
<%= turbo_frame_tag card, :watch, src: card_watch_path(card), data: { turbo_permanent: true } %>
<%= turbo_frame_tag card, :pin, src: card_pin_path(card), data: { turbo_permanent: true } %>
</aside>
<%= render "cards/container/closure", card: card %>
<% end %>
</section>
@@ -0,0 +1,29 @@
<div class="comments pad-block">
<div class="comment comment--new flex-inline align-start full-width">
<figure class="comment__avatar flex-item-no-shrink" aria-hidden="true">
<%= avatar_tag Current.user, hidden_for_screen_reader: true %>
</figure>
<div class="comment__content flex-inline flex-column full-width">
<div class="comment__body txt-align-start">
<form data-controller="outlet-auto-save paste"
class="flex flex-column gap full-width"
data-outlet-auto-save-auto-save-outlet="#card_form"
data-action="paste->paste#pasteFiles">
<%= tag.house_md card.draft_comment, name: "card[draft_comment]", class: "input comment__input",
form: "card_form",
placeholder: new_comment_placeholder(card),
data: { action: "house-md:change->outlet-auto-save#change focusout->outlet-auto-save#submit", uploads_url: uploads_url(format: "json") } %>
</form>
<% if card.creating? %>
<div class="margin-block-start flex align-center gap">
<%= button_to "Create card", card_publish_path(card), class: "btn btn--reversed" %>
<%= button_to "Save as draft", collection_card_path(card.collection, card), name: "card[status]", value: "drafted", method: :put, class: "btn" %>
</div>
<% end %>
</div>
</div>
</div>
</div>
+1 -1
View File
@@ -1,4 +1,4 @@
<div class="card-perma__notch card-perma__notch--bottom flex-column" id="<%= dom_id(card, :card_closure_toggle) %>" style="--card-color: <%= card.color %>">
<div class="card-perma__notch card-perma__notch--bottom flex-column" id="<%= dom_id(@card, :card_closure_toggle) %>" style="--card-color: <%= @card.color %>">
<% if card.closed? %>
<div class="flex gap-half margin-block-start-double margin-block-end">
<span class="card-perma__closure-message">Completed by <%= card.closed_by.name %> on <%= local_datetime_tag(card.closed_at, style: :shortdate) %>.</span>
-4
View File
@@ -1,4 +0,0 @@
<%= link_to edit_collection_card_path(card.collection, card), class: "btn", data: { turbo_frame: dom_id(card, :edit) } do %>
<%= icon_tag "pencil" %>
<span class="for-screen-reader">Edit</span>
<% end %>
+10 -23
View File
@@ -1,27 +1,14 @@
<% if card.published? %>
<%= turbo_frame_tag card, :edit do %>
<div class="full-width">
<h1 class="card__title flex align-start gap-half">
<%= link_to card.title, edit_collection_card_path(card.collection, card), class: "card__title-link" %>
</h1>
<p class="card__description margin-block-half">
<%= sanitize card.description_html %>
</p>
</div>
<% end %>
<% else %>
<%= form_with model: card, url: collection_card_path(card.collection, card), id: "card_form", class: "full-width", data: { controller: "auto-save" } do |form| %>
<h1 class="card__title">
<h1 class="card__title">
<% if card.published? %>
<%= turbo_frame_tag card, :edit do %>
<%= link_to card.title, edit_collection_card_path(card.collection, card), class: "card__title-link overflow-line-clamp" %>
<% end %>
<% else %>
<%= form_with model: card, url: collection_card_path(card.collection, card), id: "card_form", data: { controller: "auto-save" } do |form| %>
<%= form.text_area :title, placeholder: "Name it…",
class: "input input--textarea full-width borderless txt-align-start",
class: "input input--textarea full-width borderless txt-align-start #{ "fill-highlight" if card.creating? }",
autofocus: card.title.blank?,
data: { action: "auto-save#change blur->auto-save#submit keydown.enter->auto-save#submit:prevent keydown.ctrl+enter->auto-save#submit:prevent" } %>
</h1>
<div class="card__description margin-block-half">
<%= form.markdown_area :description, class: "input input--textarea full-width borderless txt-align-start card-field__description",
placeholder: "Add some notes, context, pictures, or video about this…",
data: { action: "keydown.ctrl+enter->form#submit:prevent keydown.meta+enter->form#submit:prevent keydown.esc->form#cancel:stop paste->paste#pasteFiles" } %>
</div>
<%= form.button "Save changes", type: :submit, class: "btn"%>
<% end %>
<% end %>
<% end %>
</h1>
@@ -1,4 +0,0 @@
<div class="card-perma__notch card-perma__notch--bottom">
<%= button_to "Create card", card_publish_path(card), class: "btn" %>
<%= button_to "Save as draft", collection_card_path(card.collection, card), name: "card[status]", value: "drafted", method: :put, class: "btn btn--reversed" %>
</div>
@@ -1,7 +0,0 @@
<%# FIXME: Let's move this aside outside of the card container section so these frames don't reload/flicker when card is replaced %>
<aside class="card-perma__actions card-perma__actions--right" role="toolbar">
<%= turbo_frame_tag card, :watch, src: card_watch_path(card) %>
<%= turbo_frame_tag card, :pin, src: card_pin_path(card) %>
</aside>
<%= render "cards/container/closure", card: card %>
+2 -2
View File
@@ -6,8 +6,8 @@
</header>
<div class="card__body flex gap full-width flex-item-grow">
<h1 class="card__title overflow-line-clamp">
<%= card.title %>
<h1 class="card__title">
<span class="card__title-link overflow-line-clamp"><%= card.title %></span>
</h1>
<%= link_to collection_card_path(card.collection, card), class: "card__link" do %>
@@ -4,7 +4,7 @@
<% end %>
<div class="position-relative" data-controller="dialog" data-action="keydown.esc->dialog#close click@document->dialog#closeOnClickOutside" <%= "hidden" if card.closed? %>>
<button class="btn card__hide-on-index fill-transparent" data-action="click->dialog#open:stop">
<button class="btn card__hide-on-index <%= card.creating? || card.drafted? ? "fill-highlight" : "fill-transparent" %>" data-action="click->dialog#open:stop">
<%= icon_tag "person-add" %>
<span class="for-screen-reader">Assign</span>
</button>
+1 -1
View File
@@ -12,7 +12,7 @@
</div>
<div class="position-relative" data-controller="dialog" data-action="keydown.esc->dialog#close click@document->dialog#closeOnClickOutside" <%= "hidden" if card.closed? %>>
<button class="tag-picker__button btn card__hide-on-index fill-transparent" data-action="click->dialog#open:stop">
<button class="tag-picker__button btn card__hide-on-index <%= card.creating? || card.drafted? ? "fill-highlight" : "fill-transparent" %>" data-action="click->dialog#open:stop">
<%= icon_tag "tag" %>
<span class="for-screen-reader">Add a tag</span>
</button>
+9 -15
View File
@@ -1,19 +1,13 @@
<%= turbo_frame_tag @card, :edit do %>
<%= form_with model: @card, url: collection_card_path(@card.collection, @card), class: "full-width", data: { controller: "form paste" } do |form| %>
<h1 class="card__title">
<%= form.label :title, class: "flex flex-column align-center" do %>
<%= form.text_area :title, class: "input input--textarea full-width borderless txt-align-start card-field__title",
required: true, autofocus: true, placeholder: "Name it…",
rows: 1,
data: { action: "keydown.enter->form#submit:prevent keydown.ctrl+enter->form#submit:prevent keydown.meta+enter->form#submit:prevent keydown.esc->form#cancel focus->form#select" } %>
<% end %>
</h1>
<div class="card__description margin-block-half">
<%= form.markdown_area :description, class: "input input--textarea full-width borderless txt-align-start card-field__description",
placeholder: "Add some notes, context, pictures, or video about this…",
data: { action: "keydown.ctrl+enter->form#submit:prevent keydown.meta+enter->form#submit:prevent keydown.esc->form#cancel:stop paste->paste#pasteFiles" } %>
</div>
<%= form.button "Save changes", type: :submit, class: "btn"%>
<%= form_with model: @card, url: collection_card_path(@card.collection, @card), class: "flex flex-column gap full-width", data: { controller: "form" } do |form| %>
<%= form.label :title, class: "flex flex-column align-center" do %>
<%= form.text_area :title, class: "input input--textarea full-width borderless txt-align-start card__title-field",
required: true, autofocus: true, placeholder: "Name it…",
rows: 3,
data: { action: "keydown.enter->form#submit:prevent keydown.ctrl+enter->form#submit:prevent keydown.meta+enter->form#submit:prevent keydown.esc->form#cancel focus->form#select" },
style: "color: var(--spat-color); --input-border-radius: 0" %>
<% end %>
<%= form.button "Save", type: :submit, hidden: true %>
<%= link_to "Close editor and discard changes", collection_card_path(@card.collection, @card), data: { form_target: "cancel" }, hidden: true %>
<% end %>
<% end %>
+2
View File
@@ -34,5 +34,7 @@
<% if @card.published? %>
<%= render "cards/messages", card: @card %>
<% else %>
<%= render "cards/description_as_draft_comment", card: @card %>
<% end %>
</div>
+4 -2
View File
@@ -36,17 +36,19 @@ class CardsControllerTest < ActionDispatch::IntegrationTest
patch collection_card_path(collections(:writebook), cards(:logo)), params: {
card: {
title: "Logo needs to change",
due_on: 1.week.from_now,
image: fixture_file_upload("moon.jpg", "image/jpeg"),
description: "Something more in-depth",
draft_comment: "Something more in-depth",
tag_ids: [ tags(:mobile).id ] } }
assert_response :success
card = cards(:logo).reload
assert_equal "Logo needs to change", card.title
assert_equal 1.week.from_now.to_date, card.due_on
assert_equal "moon.jpg", card.image.filename.to_s
assert_equal [ tags(:mobile) ], card.tags
assert_equal "Something more in-depth", card.description_plain_text.strip
assert_equal "Something more in-depth", card.messages.comments.first.comment.body_plain_text.strip
end
test "users can only see cards in collections they have access to" do
+37
View File
@@ -6,4 +6,41 @@ class Card::MessagesTest < ActiveSupport::TestCase
assert_empty card.messages
end
test "creating a card with an initial draft comment" do
card = collections(:writebook).cards.create! creator: users(:kevin), title: "New",
draft_comment: "This is a comment"
assert_equal 1, card.messages.count
assert_equal "This is a comment", card.draft_comment.strip
end
test "updating the draft comment" do
card = collections(:writebook).cards.create! creator: users(:kevin), title: "New",
draft_comment: "This is a comment"
card.update! draft_comment: "This is an updated comment"
assert_equal 1, card.messages.count
assert_equal "This is an updated comment", card.draft_comment.strip
end
test "setting the draft comment to be blank removes it" do
card = collections(:writebook).cards.create! creator: users(:kevin), title: "New",
draft_comment: "This is a comment"
card.update! draft_comment: " "
assert card.messages.first.nil?
end
test "omitting the draft comment does not remove it" do
card = collections(:writebook).cards.create! creator: users(:kevin), title: "New",
draft_comment: "This is a comment"
card.update! title: "Newer"
assert_equal 1, card.messages.count
assert_equal "This is a comment", card.draft_comment.strip
end
end