From 929c828b2160235aa55bed853b72efc2127e9112 Mon Sep 17 00:00:00 2001 From: Won Rhim Date: Wed, 24 Jan 2024 13:54:10 -0500 Subject: [PATCH 01/16] feat: add partial that renders emoji selector --- app/assets/images/smiley_face.svg | 13 +++++++++++ .../_emoji_selector.html.erb | 21 +++++++++++++++++ .../_emoji_selector.html.erb_spec.rb | 23 +++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 app/assets/images/smiley_face.svg create mode 100644 app/views/rich_text_reactions/_emoji_selector.html.erb create mode 100644 spec/views/rich_text_reactions/_emoji_selector.html.erb_spec.rb diff --git a/app/assets/images/smiley_face.svg b/app/assets/images/smiley_face.svg new file mode 100644 index 00000000..13a639dc --- /dev/null +++ b/app/assets/images/smiley_face.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/app/views/rich_text_reactions/_emoji_selector.html.erb b/app/views/rich_text_reactions/_emoji_selector.html.erb new file mode 100644 index 00000000..9d051b5e --- /dev/null +++ b/app/views/rich_text_reactions/_emoji_selector.html.erb @@ -0,0 +1,21 @@ +<%# +Locals required for this partial: +- rich_text_id: Id of the ActionText::RichText that the new RichTextReaction + belongs to +%> + +
+ <%# is used as the button for the selector %> + + <%= render inline: Rails.root.join('app/assets/images/smiley_face.svg').read %> + + + <%= form_with url: rich_text_reactions_path do |form| %> + <%= form.hidden_field :rich_text_id, value: rich_text_id %> + + <%# `Emoji` is at lib/emoji.rb %> + <% emojis.each do |emoji| %> + <%= form.button emoji.emoji, value: emoji.caption %> + <% end %> + <% end %> +
diff --git a/spec/views/rich_text_reactions/_emoji_selector.html.erb_spec.rb b/spec/views/rich_text_reactions/_emoji_selector.html.erb_spec.rb new file mode 100644 index 00000000..d6866d12 --- /dev/null +++ b/spec/views/rich_text_reactions/_emoji_selector.html.erb_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'rich_text_reactions/_emoji_selector.html.erb', type: :view do + it 'renders a form to create a new rich text reaction' do + rich_text_id = create(:rich_text_reaction).rich_text_id + emojis = Emoji.captions.map { |caption| Emoji.new(caption) } + + render( + partial: 'rich_text_reactions/emoji_selector', + locals: { rich_text_id:, emojis: } + ) + + expect(rendered).to have_selector( + "form[action='#{rich_text_reactions_path}']", + visible: :hidden + ).and have_selector( + "input[value='#{rich_text_id}']", + visible: :hidden + ) + end +end From 44c2190f15123ca67ec047856ef5bf1bb033b203 Mon Sep 17 00:00:00 2001 From: Won Rhim Date: Wed, 24 Jan 2024 14:27:42 -0500 Subject: [PATCH 02/16] refactor: improve reusability and flexibility of view component --- .../update_component.html.erb | 12 ++++------ app/views/standup_meetings/_update.html.erb | 8 +++++++ app/views/standup_meetings/index.html.erb | 24 +++++++++---------- 3 files changed, 25 insertions(+), 19 deletions(-) create mode 100644 app/views/standup_meetings/_update.html.erb diff --git a/app/components/standup_meetings/update_component.html.erb b/app/components/standup_meetings/update_component.html.erb index 25c2cceb..5c92cd2e 100644 --- a/app/components/standup_meetings/update_component.html.erb +++ b/app/components/standup_meetings/update_component.html.erb @@ -1,9 +1,7 @@ -
- - <%= user_full_name %> - + + <%= user_full_name %> + -
+
- <%= tag.span(standup_content, class: "grow whitespace-pre-line") %> -
+<%= tag.span(standup_content, class: "grow whitespace-pre-line") %> diff --git a/app/views/standup_meetings/_update.html.erb b/app/views/standup_meetings/_update.html.erb new file mode 100644 index 00000000..c8d6538e --- /dev/null +++ b/app/views/standup_meetings/_update.html.erb @@ -0,0 +1,8 @@ +<%# locals required: standup_meeting, content_type %> + +
+ <%= render StandupMeetings::UpdateComponent.new( + standup_meeting:, + content_type: + ) %> +
diff --git a/app/views/standup_meetings/index.html.erb b/app/views/standup_meetings/index.html.erb index 2eeb3400..82db1513 100644 --- a/app/views/standup_meetings/index.html.erb +++ b/app/views/standup_meetings/index.html.erb @@ -48,24 +48,24 @@
<%= render StandupMeetings::ColumnComponent.new(title: "Previous Work Day") do%> - <%= render StandupMeetings::UpdateComponent.with_collection( - @completed_meetings, - content_type: :yesterday_work_description - ) %> + <% @completed_meetings.each do |standup_meeting| %> + <%= render partial: "update", + locals: { standup_meeting:, content_type: :yesterday_work_description } %> + <% end %> <% end %> <%= render StandupMeetings::ColumnComponent.new(title: "Today's Work Day") do %> - <%= render StandupMeetings::UpdateComponent.with_collection( - @completed_meetings, - content_type: :today_work_description - ) %> + <% @completed_meetings.each do |standup_meeting| %> + <%= render partial: "update", + locals: { standup_meeting:, content_type: :today_work_description } %> + <% end %> <% end %> <%= render StandupMeetings::ColumnComponent.new(title: "Blockers") do %> - <%= render StandupMeetings::UpdateComponent.with_collection( - @completed_meetings, - content_type: :blockers_description - ) %> + <% @completed_meetings.each do |standup_meeting| %> + <%= render partial: "update", + locals: { standup_meeting:, content_type: :blockers_description } %> + <% end %> <% end %>
From 6693ec522abba317d9559e8e72311ffae6fbd2dd Mon Sep 17 00:00:00 2001 From: Won Rhim Date: Wed, 24 Jan 2024 15:56:16 -0500 Subject: [PATCH 03/16] refactor: improve reusability and flexibility of view component --- ....html.erb => rich_text_component.html.erb} | 2 +- app/components/rich_text_component.rb | 19 ++++++++ .../standup_meetings/update_component.rb | 25 ----------- spec/components/rich_text_component_spec.rb | 23 ++++++++++ .../standup_meetings/update_component_spec.rb | 43 ------------------- 5 files changed, 43 insertions(+), 69 deletions(-) rename app/components/{standup_meetings/update_component.html.erb => rich_text_component.html.erb} (64%) create mode 100644 app/components/rich_text_component.rb delete mode 100644 app/components/standup_meetings/update_component.rb create mode 100644 spec/components/rich_text_component_spec.rb delete mode 100644 spec/components/standup_meetings/update_component_spec.rb diff --git a/app/components/standup_meetings/update_component.html.erb b/app/components/rich_text_component.html.erb similarity index 64% rename from app/components/standup_meetings/update_component.html.erb rename to app/components/rich_text_component.html.erb index 5c92cd2e..442d174d 100644 --- a/app/components/standup_meetings/update_component.html.erb +++ b/app/components/rich_text_component.html.erb @@ -4,4 +4,4 @@
-<%= tag.span(standup_content, class: "grow whitespace-pre-line") %> +<%= tag.span(@rich_text, class: "grow whitespace-pre-line") %> diff --git a/app/components/rich_text_component.rb b/app/components/rich_text_component.rb new file mode 100644 index 00000000..2ac14e9b --- /dev/null +++ b/app/components/rich_text_component.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class RichTextComponent < ViewComponent::Base + def initialize(rich_text:, user:) + @rich_text = rich_text + @user = user + end + + private + + def user_full_name + @user.full_name + end + + # Check to see if the body does not have blank text. + def render? + @rich_text.present? + end +end diff --git a/app/components/standup_meetings/update_component.rb b/app/components/standup_meetings/update_component.rb deleted file mode 100644 index 312fc4a1..00000000 --- a/app/components/standup_meetings/update_component.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -class StandupMeetings::UpdateComponent < ViewComponent::Base - with_collection_parameter :standup_meeting - - def initialize(standup_meeting:, content_type:) - @standup_meeting = standup_meeting - @content_type = content_type - @user = standup_meeting.user - end - - private - - def standup_content - @standup_content ||= @standup_meeting.public_send(@content_type) - end - - def user_full_name - @user.full_name - end - - def render? - standup_content.present? - end -end diff --git a/spec/components/rich_text_component_spec.rb b/spec/components/rich_text_component_spec.rb new file mode 100644 index 00000000..d18e3c68 --- /dev/null +++ b/spec/components/rich_text_component_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe RichTextComponent, type: :component do + let!(:rich_text) { build(:action_text_rich_text) } + let!(:user) { rich_text.record } + + it "renders the rich text content along with the user's full name" do + render_inline described_class.new(rich_text:, user:) + + expect(page).to have_content(rich_text.to_plain_text) + .and have_content(user.full_name) + end + + it "renders nothing with no rich text content" do + rich_text.body = ActionText::Content.new('') + + render_inline described_class.new(rich_text:, user:) + + expect(page).not_to have_content('body') + end +end diff --git a/spec/components/standup_meetings/update_component_spec.rb b/spec/components/standup_meetings/update_component_spec.rb deleted file mode 100644 index 77b6af10..00000000 --- a/spec/components/standup_meetings/update_component_spec.rb +++ /dev/null @@ -1,43 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe StandupMeetings::UpdateComponent, type: :component do - let(:empty_yesterday_meeting) { build(:standup_meeting, yesterday_work_description: '') } - - context 'with content to display' do - let(:yesterday_work_description) { 'Lorem ipsum' } - let(:today_work_description) { 'Sit amet' } - let(:standup_meeting) do - build(:standup_meeting, yesterday_work_description:, today_work_description:) - end - - it "renders yesterday's content when passed the yesterday content type" do - render_inline( - described_class.new(standup_meeting:, content_type: :yesterday_work_description) - ) - - expect(page).to have_content(yesterday_work_description) - end - - it "renders today's content when passed the today content type" do - render_inline( - described_class.new(standup_meeting:, content_type: :today_work_description) - ) - - expect(page).to have_content(today_work_description) - end - end - - context 'with no content to display' do - let(:meeting_with_empty_yesterday) { build(:standup_meeting, yesterday_work_description: '') } - - it 'renders nothing' do - render_inline( - described_class.new(standup_meeting: meeting_with_empty_yesterday, content_type: :yesterday_work_description) - ) - - expect(page).not_to have_selector('body') - end - end -end From c41b19648d073079e966953517c3d0a4e947fc3d Mon Sep 17 00:00:00 2001 From: Won Rhim Date: Wed, 24 Jan 2024 16:34:29 -0500 Subject: [PATCH 04/16] feat: add unstyled emoji selector for standup meetings --- .../stylesheets/application.tailwind.css | 1 + app/assets/stylesheets/reaction_selector.css | 7 ++++++ .../standup_meetings_controller.rb | 2 ++ app/helpers/emojis_helper.rb | 5 ++++ .../_emoji_selector.html.erb | 19 ++++++++------- app/views/standup_meetings/_update.html.erb | 12 ++++++---- app/views/standup_meetings/index.html.erb | 21 ++++++++++++----- spec/factories/action_text_rich_texts.rb | 15 ++---------- spec/factories/rich_text_reactions.rb | 9 +------- .../_emoji_selector.html.erb_spec.rb | 23 +++++++++++-------- 10 files changed, 64 insertions(+), 50 deletions(-) create mode 100644 app/assets/stylesheets/reaction_selector.css create mode 100644 app/helpers/emojis_helper.rb diff --git a/app/assets/stylesheets/application.tailwind.css b/app/assets/stylesheets/application.tailwind.css index 8093482f..f1cae06a 100644 --- a/app/assets/stylesheets/application.tailwind.css +++ b/app/assets/stylesheets/application.tailwind.css @@ -5,6 +5,7 @@ @import "tailwindcss/components"; @import "tailwindcss/utilities"; @import 'direct_uploads'; +@import 'reaction_selector'; .field_with_errors { @apply flex [&>input]:input-error [&>input]:w-full; diff --git a/app/assets/stylesheets/reaction_selector.css b/app/assets/stylesheets/reaction_selector.css new file mode 100644 index 00000000..2db5efe0 --- /dev/null +++ b/app/assets/stylesheets/reaction_selector.css @@ -0,0 +1,7 @@ +details > summary { + list-style: none; +} + +details > summary::-webkit-details-marker { + display: none; +} diff --git a/app/controllers/standup_meetings_controller.rb b/app/controllers/standup_meetings_controller.rb index 812c4228..9a74fe41 100644 --- a/app/controllers/standup_meetings_controller.rb +++ b/app/controllers/standup_meetings_controller.rb @@ -1,3 +1,5 @@ +require 'emoji' + class StandupMeetingsController < ApplicationController # rubocop:disable Metrics/AbcSize def index diff --git a/app/helpers/emojis_helper.rb b/app/helpers/emojis_helper.rb new file mode 100644 index 00000000..4c6ed8a6 --- /dev/null +++ b/app/helpers/emojis_helper.rb @@ -0,0 +1,5 @@ +module EmojisHelper + def all_emojis + Emoji.captions.map { |caption| Emoji.new(caption) } + end +end diff --git a/app/views/rich_text_reactions/_emoji_selector.html.erb b/app/views/rich_text_reactions/_emoji_selector.html.erb index 9d051b5e..97e3c9f6 100644 --- a/app/views/rich_text_reactions/_emoji_selector.html.erb +++ b/app/views/rich_text_reactions/_emoji_selector.html.erb @@ -1,7 +1,9 @@ <%# -Locals required for this partial: -- rich_text_id: Id of the ActionText::RichText that the new RichTextReaction - belongs to +Locals required: +- rich_text_id: Id of the ActionText::RichText that the new RichTextReaction belongs to + +Helpers used: +- app/helpers/emojis_helper %>
@@ -10,12 +12,13 @@ Locals required for this partial: <%= render inline: Rails.root.join('app/assets/images/smiley_face.svg').read %> - <%= form_with url: rich_text_reactions_path do |form| %> + <%= form_with model: RichTextReaction.new do |form| %> <%= form.hidden_field :rich_text_id, value: rich_text_id %> - - <%# `Emoji` is at lib/emoji.rb %> - <% emojis.each do |emoji| %> - <%= form.button emoji.emoji, value: emoji.caption %> + + <% all_emojis.each do |emoji| %> + <%= form.button :emoji_caption, value: emoji.caption do %> + <%= emoji.emoji %> + <% end %> <% end %> <% end %>
diff --git a/app/views/standup_meetings/_update.html.erb b/app/views/standup_meetings/_update.html.erb index c8d6538e..bd01ea39 100644 --- a/app/views/standup_meetings/_update.html.erb +++ b/app/views/standup_meetings/_update.html.erb @@ -1,8 +1,10 @@ -<%# locals required: standup_meeting, content_type %> +<%# +Locals required: +- rich_text: an ActionText::RichText object, +- user: the owner User of rich_text +%>
- <%= render StandupMeetings::UpdateComponent.new( - standup_meeting:, - content_type: - ) %> + <%= render RichTextComponent.new(rich_text:, user:) %> + <%= render partial: "rich_text_reactions/emoji_selector", locals: { rich_text_id: rich_text.id } %>
diff --git a/app/views/standup_meetings/index.html.erb b/app/views/standup_meetings/index.html.erb index 82db1513..bd554ff9 100644 --- a/app/views/standup_meetings/index.html.erb +++ b/app/views/standup_meetings/index.html.erb @@ -48,23 +48,32 @@
<%= render StandupMeetings::ColumnComponent.new(title: "Previous Work Day") do%> - <% @completed_meetings.each do |standup_meeting| %> + <% @completed_meetings.each do |completed_meeting| %> <%= render partial: "update", - locals: { standup_meeting:, content_type: :yesterday_work_description } %> + locals: { + rich_text: completed_meeting.yesterday_work_description, + user: completed_meeting.user + } %> <% end %> <% end %> <%= render StandupMeetings::ColumnComponent.new(title: "Today's Work Day") do %> - <% @completed_meetings.each do |standup_meeting| %> + <% @completed_meetings.each do |completed_meeting| %> <%= render partial: "update", - locals: { standup_meeting:, content_type: :today_work_description } %> + locals: { + rich_text: completed_meeting.today_work_description, + user: completed_meeting.user + } %> <% end %> <% end %> <%= render StandupMeetings::ColumnComponent.new(title: "Blockers") do %> - <% @completed_meetings.each do |standup_meeting| %> + <% @completed_meetings.each do |completed_meeting| %> <%= render partial: "update", - locals: { standup_meeting:, content_type: :blockers_description } %> + locals: { + rich_text: completed_meeting.blockers_description, + user: completed_meeting.user + } %> <% end %> <% end %>
diff --git a/spec/factories/action_text_rich_texts.rb b/spec/factories/action_text_rich_texts.rb index b331b93b..490602cb 100644 --- a/spec/factories/action_text_rich_texts.rb +++ b/spec/factories/action_text_rich_texts.rb @@ -1,19 +1,8 @@ FactoryBot.define do factory :action_text_rich_text, class: 'ActionText::RichText' do - # +rich_text_owner+ must be given by the user of this factory, and it may - # be any persisted ActiveRecord model record. - transient do - rich_text_owner { nil } - end - name { Faker::Lorem.word } body { ActionText::Content.new "
#{Faker::Lorem.sentence}
" } - - after(:build) do |action_text_rich_text, evaluator| - if evaluator.rich_text_owner - action_text_rich_text.record_type = evaluator.rich_text_owner.class.name - action_text_rich_text.record_id = evaluator.rich_text_owner.id - end - end + record_type { User.name } + record_id { create(:user).id } end end diff --git a/spec/factories/rich_text_reactions.rb b/spec/factories/rich_text_reactions.rb index 4960b5e0..eb02b16a 100644 --- a/spec/factories/rich_text_reactions.rb +++ b/spec/factories/rich_text_reactions.rb @@ -21,15 +21,8 @@ # FactoryBot.define do factory :rich_text_reaction do - # +rich_text_owner+ can be given by the user of this factory, and it may - # be any persisted ActiveRecord model record. By default, a User record is - # used. - transient do - rich_text_owner { user } - end - user emoji_caption { Emoji.captions.sample } - rich_text { association(:action_text_rich_text, rich_text_owner:) } + rich_text { association(:action_text_rich_text, record: user) } end end diff --git a/spec/views/rich_text_reactions/_emoji_selector.html.erb_spec.rb b/spec/views/rich_text_reactions/_emoji_selector.html.erb_spec.rb index d6866d12..a11af296 100644 --- a/spec/views/rich_text_reactions/_emoji_selector.html.erb_spec.rb +++ b/spec/views/rich_text_reactions/_emoji_selector.html.erb_spec.rb @@ -5,19 +5,22 @@ RSpec.describe 'rich_text_reactions/_emoji_selector.html.erb', type: :view do it 'renders a form to create a new rich text reaction' do rich_text_id = create(:rich_text_reaction).rich_text_id + emojis = Emoji.captions.map { |caption| Emoji.new(caption) } - render( - partial: 'rich_text_reactions/emoji_selector', + render partial: 'rich_text_reactions/emoji_selector', locals: { rich_text_id:, emojis: } - ) - expect(rendered).to have_selector( - "form[action='#{rich_text_reactions_path}']", - visible: :hidden - ).and have_selector( - "input[value='#{rich_text_id}']", - visible: :hidden - ) + expect(rendered) + .to have_selector("form[action='#{rich_text_reactions_path}']", + visible: :hidden) + .and have_selector("input[value='#{rich_text_id}']", + visible: :hidden) + + emojis.each do |emoji| + expect(rendered).to have_button("rich_text_reaction[emoji_caption]", + text: emoji.emoji, + visible: :hidden) + end end end From b88d243f87bf9f4e80158d5efa9f3200fb6f42b4 Mon Sep 17 00:00:00 2001 From: Won Rhim Date: Thu, 25 Jan 2024 13:14:31 -0500 Subject: [PATCH 05/16] feat: correctly position emoji selector modal --- app/components/rich_text_component.html.erb | 2 +- .../_emoji_selector.html.erb | 32 +++++++++++-------- app/views/standup_meetings/_update.html.erb | 2 +- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/app/components/rich_text_component.html.erb b/app/components/rich_text_component.html.erb index 442d174d..3597945d 100644 --- a/app/components/rich_text_component.html.erb +++ b/app/components/rich_text_component.html.erb @@ -1,4 +1,4 @@ - + <%= user_full_name %> diff --git a/app/views/rich_text_reactions/_emoji_selector.html.erb b/app/views/rich_text_reactions/_emoji_selector.html.erb index 97e3c9f6..7a1545a3 100644 --- a/app/views/rich_text_reactions/_emoji_selector.html.erb +++ b/app/views/rich_text_reactions/_emoji_selector.html.erb @@ -6,19 +6,23 @@ Helpers used: - app/helpers/emojis_helper %> -
- <%# is used as the button for the selector %> - - <%= render inline: Rails.root.join('app/assets/images/smiley_face.svg').read %> - +
+
+ + <%= render inline: Rails.root.join('app/assets/images/smiley_face.svg').read %> + - <%= form_with model: RichTextReaction.new do |form| %> - <%= form.hidden_field :rich_text_id, value: rich_text_id %> - - <% all_emojis.each do |emoji| %> - <%= form.button :emoji_caption, value: emoji.caption do %> - <%= emoji.emoji %> +
+ <%= form_with model: RichTextReaction.new do |form| %> + <%= form.hidden_field :rich_text_id, value: rich_text_id %> + + <% all_emojis.each do |emoji| %> + <%= form.button :emoji_caption, value: emoji.caption, class: "mx-1" do %> + <%= emoji.emoji %> + <% end %> + <% end %> <% end %> - <% end %> - <% end %> -
+
+
+ diff --git a/app/views/standup_meetings/_update.html.erb b/app/views/standup_meetings/_update.html.erb index bd01ea39..a0c0376d 100644 --- a/app/views/standup_meetings/_update.html.erb +++ b/app/views/standup_meetings/_update.html.erb @@ -4,7 +4,7 @@ Locals required: - user: the owner User of rich_text %> -
+
<%= render RichTextComponent.new(rich_text:, user:) %> <%= render partial: "rich_text_reactions/emoji_selector", locals: { rich_text_id: rich_text.id } %>
From 0b357da1201471c523135e10c47a0944e86c67dd Mon Sep 17 00:00:00 2001 From: Won Rhim Date: Thu, 25 Jan 2024 13:41:05 -0500 Subject: [PATCH 06/16] feat: style button animation --- app/views/rich_text_reactions/_emoji_selector.html.erb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/views/rich_text_reactions/_emoji_selector.html.erb b/app/views/rich_text_reactions/_emoji_selector.html.erb index 7a1545a3..bf0a1bad 100644 --- a/app/views/rich_text_reactions/_emoji_selector.html.erb +++ b/app/views/rich_text_reactions/_emoji_selector.html.erb @@ -18,7 +18,11 @@ Helpers used: <%= form.hidden_field :rich_text_id, value: rich_text_id %> <% all_emojis.each do |emoji| %> - <%= form.button :emoji_caption, value: emoji.caption, class: "mx-1" do %> + <%= form.button :emoji_caption, + value: emoji.caption, + class: "p-1 border-transparent border-2 + hover:bg-gray-300 hover:rounded-lg + active:border active:border-2 active:border-green-400" do %> <%= emoji.emoji %> <% end %> <% end %> From 021be18f73360a760305ae513a4a7bc02cf465d9 Mon Sep 17 00:00:00 2001 From: Won Rhim Date: Thu, 25 Jan 2024 16:13:26 -0500 Subject: [PATCH 07/16] feat: hide emoji selector when clicking away --- app/javascript/application.js | 1 + app/javascript/src/emoji_selector.js | 13 +++++++++++++ .../rich_text_reactions/_emoji_selector.html.erb | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 app/javascript/src/emoji_selector.js diff --git a/app/javascript/application.js b/app/javascript/application.js index c538c561..4a8f9974 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -5,6 +5,7 @@ import 'trix'; import '@rails/actiontext'; import './src/direct_uploads'; import './src/inline_code'; +import './src/emoji_selector'; import * as ActiveStorage from '@rails/activestorage'; diff --git a/app/javascript/src/emoji_selector.js b/app/javascript/src/emoji_selector.js new file mode 100644 index 00000000..a6e08bd1 --- /dev/null +++ b/app/javascript/src/emoji_selector.js @@ -0,0 +1,13 @@ +document.addEventListener('click', function(event) { + const emojiSelections = document.querySelectorAll('details[open].emoji-selection'); + + if (emojiSelections.length > 0) { + const selectionClicked = [...emojiSelections].some( + selection => selection.contains(event.target) + ); + + if (selectionClicked === false) { + emojiSelections.forEach(selection => selection.removeAttribute('open')); + } + } +}); diff --git a/app/views/rich_text_reactions/_emoji_selector.html.erb b/app/views/rich_text_reactions/_emoji_selector.html.erb index bf0a1bad..8c859f74 100644 --- a/app/views/rich_text_reactions/_emoji_selector.html.erb +++ b/app/views/rich_text_reactions/_emoji_selector.html.erb @@ -7,7 +7,7 @@ Helpers used: %>
-
+
<%= render inline: Rails.root.join('app/assets/images/smiley_face.svg').read %> From 7373b07c78a0e35692d8cfde59b7cd6554fb31fe Mon Sep 17 00:00:00 2001 From: Won Rhim Date: Thu, 25 Jan 2024 16:14:53 -0500 Subject: [PATCH 08/16] fix: prevent "PLACEHOLDER" from flooding page for now --- app/views/rich_text_reactions/create.turbo_stream.erb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/rich_text_reactions/create.turbo_stream.erb b/app/views/rich_text_reactions/create.turbo_stream.erb index d9b6d00b..36b864b4 100644 --- a/app/views/rich_text_reactions/create.turbo_stream.erb +++ b/app/views/rich_text_reactions/create.turbo_stream.erb @@ -1 +1,2 @@ -<%= "PLACEHOLDER" %> +<%# placeholder %> +<%= "" %> From 9287575bfda7658312fc4297abff5777d387f5ea Mon Sep 17 00:00:00 2001 From: Won Rhim Date: Thu, 25 Jan 2024 16:16:23 -0500 Subject: [PATCH 09/16] rubocop --- spec/components/rich_text_component_spec.rb | 2 +- .../rich_text_reactions/_emoji_selector.html.erb_spec.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/components/rich_text_component_spec.rb b/spec/components/rich_text_component_spec.rb index d18e3c68..15995eb3 100644 --- a/spec/components/rich_text_component_spec.rb +++ b/spec/components/rich_text_component_spec.rb @@ -13,7 +13,7 @@ .and have_content(user.full_name) end - it "renders nothing with no rich text content" do + it 'renders nothing with no rich text content' do rich_text.body = ActionText::Content.new('') render_inline described_class.new(rich_text:, user:) diff --git a/spec/views/rich_text_reactions/_emoji_selector.html.erb_spec.rb b/spec/views/rich_text_reactions/_emoji_selector.html.erb_spec.rb index a11af296..dae81481 100644 --- a/spec/views/rich_text_reactions/_emoji_selector.html.erb_spec.rb +++ b/spec/views/rich_text_reactions/_emoji_selector.html.erb_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe 'rich_text_reactions/_emoji_selector.html.erb', type: :view do +RSpec.describe 'rich_text_reactions/_emoji_selector.html.erb' do it 'renders a form to create a new rich text reaction' do rich_text_id = create(:rich_text_reaction).rich_text_id @@ -18,7 +18,7 @@ visible: :hidden) emojis.each do |emoji| - expect(rendered).to have_button("rich_text_reaction[emoji_caption]", + expect(rendered).to have_button('rich_text_reaction[emoji_caption]', text: emoji.emoji, visible: :hidden) end From fb678a61b6a66168c80990ee2f60a69feab60aa3 Mon Sep 17 00:00:00 2001 From: Won Rhim Date: Thu, 25 Jan 2024 16:37:36 -0500 Subject: [PATCH 10/16] chore: rename for consistency --- app/assets/stylesheets/application.tailwind.css | 2 +- .../stylesheets/{reaction_selector.css => emoji_selector.css} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename app/assets/stylesheets/{reaction_selector.css => emoji_selector.css} (100%) diff --git a/app/assets/stylesheets/application.tailwind.css b/app/assets/stylesheets/application.tailwind.css index f1cae06a..703ef5b0 100644 --- a/app/assets/stylesheets/application.tailwind.css +++ b/app/assets/stylesheets/application.tailwind.css @@ -5,7 +5,7 @@ @import "tailwindcss/components"; @import "tailwindcss/utilities"; @import 'direct_uploads'; -@import 'reaction_selector'; +@import 'emoji_selector'; .field_with_errors { @apply flex [&>input]:input-error [&>input]:w-full; diff --git a/app/assets/stylesheets/reaction_selector.css b/app/assets/stylesheets/emoji_selector.css similarity index 100% rename from app/assets/stylesheets/reaction_selector.css rename to app/assets/stylesheets/emoji_selector.css From 44ba9ece1aa32cfccaf6924ef3ef9b56063c7e81 Mon Sep 17 00:00:00 2001 From: Won Rhim Date: Thu, 25 Jan 2024 17:08:10 -0500 Subject: [PATCH 11/16] fix: correct the clickable emoji selector button space --- app/assets/images/smiley_face.svg | 2 +- app/views/rich_text_reactions/_emoji_selector.html.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/images/smiley_face.svg b/app/assets/images/smiley_face.svg index 13a639dc..9037fe25 100644 --- a/app/assets/images/smiley_face.svg +++ b/app/assets/images/smiley_face.svg @@ -1,4 +1,4 @@ - + diff --git a/app/views/rich_text_reactions/_emoji_selector.html.erb b/app/views/rich_text_reactions/_emoji_selector.html.erb index 8c859f74..8564b331 100644 --- a/app/views/rich_text_reactions/_emoji_selector.html.erb +++ b/app/views/rich_text_reactions/_emoji_selector.html.erb @@ -7,7 +7,7 @@ Helpers used: %>
-
+
<%= render inline: Rails.root.join('app/assets/images/smiley_face.svg').read %> From 832fff665dd16e7715dbef6c8030c31b8f0c00a1 Mon Sep 17 00:00:00 2001 From: Won Rhim Date: Thu, 25 Jan 2024 17:23:01 -0500 Subject: [PATCH 12/16] ESLint --- app/javascript/src/emoji_selector.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/javascript/src/emoji_selector.js b/app/javascript/src/emoji_selector.js index a6e08bd1..b8f15cc8 100644 --- a/app/javascript/src/emoji_selector.js +++ b/app/javascript/src/emoji_selector.js @@ -1,13 +1,13 @@ -document.addEventListener('click', function(event) { - const emojiSelections = document.querySelectorAll('details[open].emoji-selection'); +document.addEventListener('click', (event) => { + const emojiSelections = document.querySelectorAll('details[open].emoji-selection'); - if (emojiSelections.length > 0) { - const selectionClicked = [...emojiSelections].some( - selection => selection.contains(event.target) - ); + if (emojiSelections.length > 0) { + const selectionClicked = [...emojiSelections].some( + (selection) => selection.contains(event.target), + ); - if (selectionClicked === false) { - emojiSelections.forEach(selection => selection.removeAttribute('open')); - } - } + if (selectionClicked === false) { + emojiSelections.forEach((selection) => selection.removeAttribute('open')); + } + } }); From f62d88900f33ca3acdc73647e124314927c9df9b Mon Sep 17 00:00:00 2001 From: Won Rhim Date: Fri, 26 Jan 2024 13:36:13 -0500 Subject: [PATCH 13/16] chore: remove unused require --- app/controllers/standup_meetings_controller.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/controllers/standup_meetings_controller.rb b/app/controllers/standup_meetings_controller.rb index 9a74fe41..812c4228 100644 --- a/app/controllers/standup_meetings_controller.rb +++ b/app/controllers/standup_meetings_controller.rb @@ -1,5 +1,3 @@ -require 'emoji' - class StandupMeetingsController < ApplicationController # rubocop:disable Metrics/AbcSize def index From 346f4aab1a30539601d6e38e278c55d25a2229ed Mon Sep 17 00:00:00 2001 From: Won Rhim Date: Sun, 28 Jan 2024 17:52:17 -0500 Subject: [PATCH 14/16] refactor: use stimulus over vanilla JS for toggling
--- app/javascript/application.js | 1 - .../controllers/details_toggle_controller.js | 13 ++++++++++++ app/javascript/controllers/index.js | 20 ++++++++++--------- app/javascript/src/emoji_selector.js | 13 ------------ .../_emoji_selector.html.erb | 6 ++++-- 5 files changed, 28 insertions(+), 25 deletions(-) create mode 100644 app/javascript/controllers/details_toggle_controller.js delete mode 100644 app/javascript/src/emoji_selector.js diff --git a/app/javascript/application.js b/app/javascript/application.js index 4a8f9974..c538c561 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -5,7 +5,6 @@ import 'trix'; import '@rails/actiontext'; import './src/direct_uploads'; import './src/inline_code'; -import './src/emoji_selector'; import * as ActiveStorage from '@rails/activestorage'; diff --git a/app/javascript/controllers/details_toggle_controller.js b/app/javascript/controllers/details_toggle_controller.js new file mode 100644 index 00000000..753a8643 --- /dev/null +++ b/app/javascript/controllers/details_toggle_controller.js @@ -0,0 +1,13 @@ +import { Controller } from "@hotwired/stimulus" + +// Connects to data-controller="details-toggle" +export default class extends Controller { + static targets = ["details"]; + + clickOut(event) { + const detailsIsOpen = this.detailsTarget.hasAttribute('open'); + const clickedOutOfDetails = this.detailsTarget.contains(event.target) === false; + + if (detailsIsOpen && clickedOutOfDetails) this.detailsTarget.removeAttribute('open'); + } +} diff --git a/app/javascript/controllers/index.js b/app/javascript/controllers/index.js index 4d0f8af7..5846bb25 100644 --- a/app/javascript/controllers/index.js +++ b/app/javascript/controllers/index.js @@ -2,17 +2,19 @@ // Run that command whenever you add a new controller or create them with // ./bin/rails generate stimulus controllerName -import { application } from './application'; +import { application } from "./application" -import LinkBuilderController from './link_builder_controller'; +import DetailsToggleController from "./details_toggle_controller" +application.register("details-toggle", DetailsToggleController) -import ModalController from './modal_controller'; +import LinkBuilderController from "./link_builder_controller" +application.register("link-builder", LinkBuilderController) -import PairRequestsFormController from './pair_requests_form_controller'; +import ModalController from "./modal_controller" +application.register("modal", ModalController) -import SelectController from './select_controller'; +import PairRequestsFormController from "./pair_requests_form_controller" +application.register("pair-requests-form", PairRequestsFormController) -application.register('link-builder', LinkBuilderController); -application.register('modal', ModalController); -application.register('pair-requests-form', PairRequestsFormController); -application.register('select', SelectController); +import SelectController from "./select_controller" +application.register("select", SelectController) diff --git a/app/javascript/src/emoji_selector.js b/app/javascript/src/emoji_selector.js deleted file mode 100644 index b8f15cc8..00000000 --- a/app/javascript/src/emoji_selector.js +++ /dev/null @@ -1,13 +0,0 @@ -document.addEventListener('click', (event) => { - const emojiSelections = document.querySelectorAll('details[open].emoji-selection'); - - if (emojiSelections.length > 0) { - const selectionClicked = [...emojiSelections].some( - (selection) => selection.contains(event.target), - ); - - if (selectionClicked === false) { - emojiSelections.forEach((selection) => selection.removeAttribute('open')); - } - } -}); diff --git a/app/views/rich_text_reactions/_emoji_selector.html.erb b/app/views/rich_text_reactions/_emoji_selector.html.erb index 8564b331..ef0899a5 100644 --- a/app/views/rich_text_reactions/_emoji_selector.html.erb +++ b/app/views/rich_text_reactions/_emoji_selector.html.erb @@ -6,8 +6,10 @@ Helpers used: - app/helpers/emojis_helper %> -
-
+
+
<%= render inline: Rails.root.join('app/assets/images/smiley_face.svg').read %> From 89015f69c4b563935c9eb2b99423ded9a781fa90 Mon Sep 17 00:00:00 2001 From: Won Rhim Date: Sun, 28 Jan 2024 18:13:54 -0500 Subject: [PATCH 15/16] chore: rename partial using convention --- ...ate.html.erb => _standup_meeting.html.erb} | 0 app/views/standup_meetings/index.html.erb | 22 ++++++------------- 2 files changed, 7 insertions(+), 15 deletions(-) rename app/views/standup_meetings/{_update.html.erb => _standup_meeting.html.erb} (100%) diff --git a/app/views/standup_meetings/_update.html.erb b/app/views/standup_meetings/_standup_meeting.html.erb similarity index 100% rename from app/views/standup_meetings/_update.html.erb rename to app/views/standup_meetings/_standup_meeting.html.erb diff --git a/app/views/standup_meetings/index.html.erb b/app/views/standup_meetings/index.html.erb index bd554ff9..0042690f 100644 --- a/app/views/standup_meetings/index.html.erb +++ b/app/views/standup_meetings/index.html.erb @@ -49,31 +49,23 @@
<%= render StandupMeetings::ColumnComponent.new(title: "Previous Work Day") do%> <% @completed_meetings.each do |completed_meeting| %> - <%= render partial: "update", - locals: { - rich_text: completed_meeting.yesterday_work_description, - user: completed_meeting.user - } %> + <%# The keyword `partial` must be used in order to pass `locals`. %> + <%= render partial: completed_meeting, + locals: { rich_text: completed_meeting.yesterday_work_description, user: completed_meeting.user } %> <% end %> <% end %> <%= render StandupMeetings::ColumnComponent.new(title: "Today's Work Day") do %> <% @completed_meetings.each do |completed_meeting| %> - <%= render partial: "update", - locals: { - rich_text: completed_meeting.today_work_description, - user: completed_meeting.user - } %> + <%= render partial: completed_meeting, + locals: { rich_text: completed_meeting.today_work_description, user: completed_meeting.user } %> <% end %> <% end %> <%= render StandupMeetings::ColumnComponent.new(title: "Blockers") do %> <% @completed_meetings.each do |completed_meeting| %> - <%= render partial: "update", - locals: { - rich_text: completed_meeting.blockers_description, - user: completed_meeting.user - } %> + <%= render partial: completed_meeting, + locals: { rich_text: completed_meeting.blockers_description, user: completed_meeting.user } %> <% end %> <% end %>
From 88a21c19daf8c275ebbb34e3b0938af087811c09 Mon Sep 17 00:00:00 2001 From: Won Rhim Date: Mon, 29 Jan 2024 11:26:36 -0500 Subject: [PATCH 16/16] chore: eslint --- .../controllers/details_toggle_controller.js | 14 +++++------ app/javascript/controllers/index.js | 25 ++++++++----------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/app/javascript/controllers/details_toggle_controller.js b/app/javascript/controllers/details_toggle_controller.js index 753a8643..c6488db9 100644 --- a/app/javascript/controllers/details_toggle_controller.js +++ b/app/javascript/controllers/details_toggle_controller.js @@ -1,13 +1,13 @@ -import { Controller } from "@hotwired/stimulus" +import { Controller } from '@hotwired/stimulus'; // Connects to data-controller="details-toggle" export default class extends Controller { - static targets = ["details"]; + static targets = ['details']; - clickOut(event) { - const detailsIsOpen = this.detailsTarget.hasAttribute('open'); - const clickedOutOfDetails = this.detailsTarget.contains(event.target) === false; + clickOut(event) { + const detailsIsOpen = this.detailsTarget.hasAttribute('open'); + const clickedOutOfDetails = this.detailsTarget.contains(event.target) === false; - if (detailsIsOpen && clickedOutOfDetails) this.detailsTarget.removeAttribute('open'); - } + if (detailsIsOpen && clickedOutOfDetails) this.detailsTarget.removeAttribute('open'); + } } diff --git a/app/javascript/controllers/index.js b/app/javascript/controllers/index.js index 5846bb25..0a273caa 100644 --- a/app/javascript/controllers/index.js +++ b/app/javascript/controllers/index.js @@ -2,19 +2,16 @@ // Run that command whenever you add a new controller or create them with // ./bin/rails generate stimulus controllerName -import { application } from "./application" +import { application } from './application'; -import DetailsToggleController from "./details_toggle_controller" -application.register("details-toggle", DetailsToggleController) +import DetailsToggleController from './details_toggle_controller'; +import LinkBuilderController from './link_builder_controller'; +import ModalController from './modal_controller'; +import PairRequestsFormController from './pair_requests_form_controller'; +import SelectController from './select_controller'; -import LinkBuilderController from "./link_builder_controller" -application.register("link-builder", LinkBuilderController) - -import ModalController from "./modal_controller" -application.register("modal", ModalController) - -import PairRequestsFormController from "./pair_requests_form_controller" -application.register("pair-requests-form", PairRequestsFormController) - -import SelectController from "./select_controller" -application.register("select", SelectController) +application.register('details-toggle', DetailsToggleController); +application.register('link-builder', LinkBuilderController); +application.register('modal', ModalController); +application.register('pair-requests-form', PairRequestsFormController); +application.register('select', SelectController);