Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FBC内の分報の削除・編集機能の追加 #8362

Draft
wants to merge 27 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
bf367e0
分報のコントローラーへのdestroyアクションの追加
SuzukiShuntarou Feb 21, 2025
6fa4fb2
destroyアクションのルーティングを追加
SuzukiShuntarou Feb 21, 2025
8afcb26
分報に削除リンクと内容修正ボタンの追加
SuzukiShuntarou Feb 21, 2025
cf620a7
分報の表示画面と編集画面を切り替えできるようにした
SuzukiShuntarou Feb 21, 2025
59eae00
分報の編集画面でコメント画面とプレビュー画面を切り替えできるようにした
SuzukiShuntarou Feb 21, 2025
7822c34
分報の編集画面内のプレビュー画面に切り替えると保存済の分報の内容が表示されるようにした
SuzukiShuntarou Feb 21, 2025
7a88f6f
分報の編集画面のコメントのテキストエリアに入力した内容がプレビュー画面に反映されるようにした
SuzukiShuntarou Feb 21, 2025
b485bda
rubocopで指摘されたメソッド定義について修正
SuzukiShuntarou Feb 21, 2025
bf4305a
編集画面内のコメントを全て消した後にキャンセルして編集画面を閉じた場合に、編集画面を再度開いて元のコメントの内容が表示されるようにした
SuzukiShuntarou Feb 21, 2025
a480039
editButtonのクリックイベントについてeditButtonが存在するかどうかの条件分岐を追加
SuzukiShuntarou Feb 21, 2025
d1ec589
apiでの分報の更新機能の追加
SuzukiShuntarou Feb 21, 2025
a75b872
本番環境のタブ覧に分報が表示されるように条件分岐を削除した
SuzukiShuntarou Feb 21, 2025
1e3f04c
変数名のタイプミスを修正した
SuzukiShuntarou Feb 21, 2025
53fd86d
分報の編集、削除は作成者とadmin権限を持つユーザだけができるようにした
SuzukiShuntarou Feb 22, 2025
70b8b42
分報の編集画面を開くとコメントとプレビュータブが存在することを確認するテストの追加
SuzukiShuntarou Feb 22, 2025
345cd97
分報の作成者とアドミン権限を持つユーザだけが編集・削除出来ることを確認するテストを追加
SuzukiShuntarou Feb 22, 2025
3eb3f6f
分報の更新・削除が正しく出来ることを確認するテストを追加
SuzukiShuntarou Feb 22, 2025
844fd60
キャンセルボタンから分報の更新を取り消し出来ることを確認するテストを追加
SuzukiShuntarou Feb 22, 2025
bd90af5
コメントタブの入力欄に記載した内容がプレビュータブに表示されることを確認するテストを追加
SuzukiShuntarou Feb 22, 2025
d8bc76e
分報のページが2ページ以上の時、分報を削除すると元の分報のページにリダイレクトすることを確認するテストを追加
SuzukiShuntarou Feb 22, 2025
f5bf21e
確認用の分報の初期データを追加
SuzukiShuntarou Feb 22, 2025
af5808c
分報を削除した時のリダイレクト先を削除した分報のページに戻るようにした
SuzukiShuntarou Feb 22, 2025
18b2a9e
初期データの分報の数を変更
SuzukiShuntarou Feb 22, 2025
3a879d3
分報の削除時に元のページに戻るテストの修正
SuzukiShuntarou Feb 22, 2025
ae51552
分報のデザイン変更
machida Feb 27, 2025
b73c18e
デザインに合わせて変更と発火用のjs-クラスを追加した
SuzukiShuntarou Feb 27, 2025
59783d8
編集・削除機能に関する追加したシステムテストについてデザインに合わせて変更した
SuzukiShuntarou Feb 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 53 additions & 14 deletions app/components/users/micro_reports/micro_report_component.html.slim
Original file line number Diff line number Diff line change
@@ -1,17 +1,56 @@
.thread-comment
.thread-comment__start
= render 'users/icon', user: @user, link_class: 'page-content-header__user-link', image_class: 'page-content-header__user-icon'
.thread-comment__end
article.a-card
header.card-header
h2.thread-comment__title
= link_to user_path(@user), class: 'thread-comment__title-link a-text-link' do
.micro-report(id="micro_report_#{@micro_report.id}" data-micro_report_id="#{@micro_report.id}" data-micro_report_content="#{@micro_report.content}")
.micro-report__start
= render 'users/icon', user: @user, link_class: 'micro-report__user-link', image_class: 'micro-report_user-icon'
.micro-report__end
.is-micro-report.micro-report-display
header.micro-report__header
h2.micro-report__title
= link_to user_path(@user), class: 'micro-report__title-link a-text-link' do
= @user.login_name
time.thread-comment__created-at
time.micro-report__created-at
= posted_datetime
hr.a-border-tint
.thread-comment__description
.a-long-text.is-md.js-markdown-view
.micro-report__body
.a-short-text.is-sm.js-markdown-view
= @micro_report.content
hr.a-border-tint
= render(Reactions::ReactionsComponent.new(reactionable: @micro_report, current_user: @current_user))
.micro-report__footer
- if @micro_report.user == @current_user || admin_login?
.micro-report-actions
ul.micro-report-actions__items
li.micro-report-actions__item
button.micro-report-actions__action.a-text-link.js-editor-button
| 内容修正
li.micro-report-actions__item
= link_to user_micro_report_path(@user, @micro_report), data: { confirm: '本当によろしいですか?' }, method: :delete, class: 'micro-report-actions__action a-muted-text-link' do
span#delete
| 削除する
= render(Reactions::ReactionsComponent.new(reactionable: @micro_report, current_user: @current_user))

.a-card.is-micro-report.micro-report-editor.is-hidden
.thread-comment-form__form
.a-form-tabs
.a-form-tabs__tab.js-edit-tab.is-active
| コメント
.a-form-tabs__tab.js-preview-tab
| プレビュー
.a-markdown-input
.a-markdown-input__inner.is-editor.is-active
.form-textarea
.form-textarea__body
textarea.a-text-input.a-markdown-input__textarea id="js-comment-#{@micro_report.id}" data-preview="#js-comment-preview-#{@micro_report.id}" data-input=".js-comment-file-input-#{@micro_report.id}" name='micro_report[content]'
= @micro_report.content
.form-textarea__footer
.form-textarea__insert
label.a-file-insert.a-button.is-xs.is-text-reversal.is-block
| ファイルを挿入
input(class="js-comment-file-input-#{@micro_report.id}" type='file' multiple)
.a-markdown-input__inner.is-preview
.a-long-text.is-md.a-markdown-input__preview id="js-comment-preview-#{@micro_report.id}"
.card-footer
.card-main-actions
.card-main-actions__items
.card-main-actions__item
button.a-button.is-sm.is-primary.is-block.js-save-button
| 保存する
.card-main-actions__item
button.a-button.is-sm.is-secondary.is-block.js-cancel-button
| キャンセル
2 changes: 2 additions & 0 deletions app/components/users/micro_reports/micro_report_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ def posted_datetime
l(time, format: :date_and_time)
end
end

delegate :admin_login?, to: :helpers
end
23 changes: 23 additions & 0 deletions app/controllers/api/micro_reports_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

class API::MicroReportsController < API::BaseController
before_action :set_micro_report, only: %i[update]

def update
if @micro_report.update(micro_report_params)
head :ok
else
head :bad_request
end
end

private

def set_micro_report
@micro_report = current_user.admin? ? MicroReport.find(params[:id]) : current_user.micro_reports.find(params[:id])
end

def micro_report_params
params.require(:micro_report).permit(:content)
end
end
20 changes: 20 additions & 0 deletions app/controllers/users/micro_reports_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

class Users::MicroReportsController < ApplicationController
PAGER_NUMBER = 25
FIRST_PAGE = 1

before_action :set_user
before_action :set_micro_report, only: %i[destroy]

def index
@micro_reports = @user.micro_reports.order(created_at: :asc).page(params[:page]).per(PAGER_NUMBER)
Expand All @@ -21,12 +23,30 @@ def create
redirect_to user_micro_reports_path(@user, page: @user.latest_micro_report_page)
end

def destroy
@micro_report.destroy!

referer_path = request.referer
matched_page_number = referer_path.match(/page=(\d+)/)
page_number = matched_page_number ? matched_page_number[1].to_i : FIRST_PAGE
if MicroReport.page(page_number).out_of_range?
redirect_to user_micro_reports_path(@user, page: @user.latest_micro_report_page)
else
redirect_to referer_path
end
flash[:notice] = '分報を削除しました。'
end

private

def set_user
@user = User.find(params[:user_id])
end

def set_micro_report
@micro_report = current_user.admin? ? MicroReport.find(params[:id]) : current_user.micro_reports.find(params[:id])
end

def micro_report_params
params.require(:micro_report).permit(:content)
end
Expand Down
8 changes: 3 additions & 5 deletions app/helpers/page_tabs/users_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@ def user_page_tabs(user, active_tab:)
tabs << { name: '提出物', link: user_products_path(user), count: user.products.length }
tabs << { name: '質問', link: user_questions_path(user), count: user.questions.length }
tabs << { name: '回答', link: user_answers_path(user), count: user.answers.length }
if Rails.env.development? || Rails.env.test? # 分報の編集、削除を実装したらこの条件は削除する
tabs << { name: '分報',
link: "#{user_micro_reports_path(user, page: user.latest_micro_report_page)}#latest-micro-report",
count: user.micro_reports.length }
end
tabs << { name: '分報',
link: "#{user_micro_reports_path(user, page: user.latest_micro_report_page)}#latest-micro-report",
count: user.micro_reports.length }
tabs << { name: '相談部屋', link: talk_path(user.talk) } if current_user.admin? && !user.admin?
render PageTabsComponent.new(tabs:, active_tab:)
end
Expand Down
117 changes: 117 additions & 0 deletions app/javascript/micro-reports-edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import CSRF from 'csrf'
import MarkdownInitializer from 'markdown-initializer'
import TextareaInitializer from 'textarea-initializer'

document.addEventListener('DOMContentLoaded', () => {
const microReports = document.querySelectorAll('.micro-report')

microReports.forEach((microReport) => {
const microReportId = microReport.dataset.micro_report_id
const microReportContent = microReport.dataset.micro_report_content
TextareaInitializer.initialize(`#js-comment-${microReportId}`)
let savedMicroReport = ''

const microReportDisplay = microReport.querySelector(
'.micro-report-display'
)
const microReportEditor = microReport.querySelector('.micro-report-editor')

const microReporDisplayContent =
microReportDisplay.querySelector('.a-short-text')
const microReportEditorPreview = microReportEditor.querySelector(
'.a-markdown-input__preview'
)
const editorTextarea = microReportEditor.querySelector(
'.a-markdown-input__textarea'
)

const markdownInitializer = new MarkdownInitializer()
if (microReportContent) {
microReporDisplayContent.innerHTML =
markdownInitializer.render(microReportContent)
microReportEditorPreview.innerHTML =
markdownInitializer.render(microReportContent)
}

const modalElements = [microReportDisplay, microReportEditor]
const editButton = microReportDisplay.querySelector('.js-editor-button')
if (editButton) {
editButton.addEventListener('click', () => {
if (!savedMicroReport) {
savedMicroReport = editorTextarea.value
}
toggleVisibility(modalElements, 'is-hidden')
})
}
const saveButton = microReportEditor.querySelector('.js-save-button')
if (saveButton) {
saveButton.addEventListener('click', () => {
toggleVisibility(modalElements, 'is-hidden')
savedMicroReport = editorTextarea.value
updatemicroReport(microReportId, savedMicroReport)
microReporDisplayContent.innerHTML =
markdownInitializer.render(savedMicroReport)
})
}

const cancelButton = microReportEditor.querySelector('.js-cancel-button')
cancelButton.addEventListener('click', () => {
toggleVisibility(modalElements, 'is-hidden')
editorTextarea.value = savedMicroReport
microReportEditorPreview.innerHTML =
markdownInitializer.render(savedMicroReport)
})

editorTextarea.addEventListener('input', () => {
microReportEditorPreview.innerHTML = markdownInitializer.render(
editorTextarea.value
)
})

const editTab = microReportEditor.querySelector('.js-edit-tab')
const editorTabContent = microReportEditor.querySelector('.is-editor')
const previewTab = microReportEditor.querySelector('.js-preview-tab')
const previewTabContent = microReportEditor.querySelector('.is-preview')
const tabElements = [
editTab,
editorTabContent,
previewTab,
previewTabContent
]
editTab.addEventListener('click', () =>
toggleVisibility(tabElements, 'is-active')
)
previewTab.addEventListener('click', () =>
toggleVisibility(tabElements, 'is-active')
)
})

function toggleVisibility(elements, className) {
elements.forEach((element) => {
element.classList.toggle(className)
})
}

function updatemicroReport(microReportId, content) {
if (content.length < 1) {
return null
}
const params = {
id: microReportId,
micro_report: { content: content }
}
fetch(`/api/micro_reports/${microReportId}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json; charset=utf-8',
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-Token': CSRF.getToken()
},
credentials: 'same-origin',
redirect: 'manual',
body: JSON.stringify(params)
}).catch((error) => {
console.warn(error)
})
}
})
1 change: 1 addition & 0 deletions app/javascript/packs/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import '../sort-faq.js'
import '../sort-faq-category.js'
import '../micro-report-form-tabs.js'
import '../micro-reports.js'
import '../micro-reports-edit.js'
import '../answer.js'
import '../new-answer.js'
import '../coding-test.js'
Expand Down
2 changes: 2 additions & 0 deletions app/javascript/stylesheets/application.sass
Original file line number Diff line number Diff line change
Expand Up @@ -127,5 +127,7 @@
@import application/blocks/coding-test/coding-tests-item

@import application/blocks/micro-report/micro-reports
@import application/blocks/micro-report/micro-report
@import application/blocks/micro-report/micro-report-form
@import application/blocks/micro-report/micro-report-form-tabs
@import application/blocks/micro-report/micro-report-actions
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.micro-report-actions__items
display: flex
gap: 1rem
Loading