Skip to content

Products.jsx を非React化する #9136

@machida

Description

@machida

概要

脱React化の一環として、提出物一覧機能をReactから普通のrails viewに移行します。

#9134#9135#9137 が終わってからの着手になります。

対象ファイル

Reactコンポーネント

  • app/javascript/components/Products.jsx (削除)
  • app/javascript/components/Product.jsx (前提として既に素のJSに移行済み)

ViewテンプレートとAPI

  • app/views/products/index.html.slim (全ての提出物一覧)
  • app/views/products/unchecked/index.html.slim (未チェック提出物一覧)
  • app/views/products/unassigned/index.html.slim (未アサイン提出物一覧)
  • app/views/products/self_assigned/index.html.slim (自分の担当提出物一覧)
  • app/controllers/api/products_controller.rb (API)

関連コントローラー

  • app/controllers/products_controller.rb
  • app/controllers/products/unchecked_controller.rb
  • app/controllers/products/unassigned_controller.rb
  • app/controllers/products/self_assigned_controller.rb

実装内容

現在の実装:

  • React + SWRで提出物データを取得(/api/products.json 等)
  • 複数の条件による提出物一覧表示(全て、未チェック、未アサイン、自分の担当)
  • ページネーション機能(50件/ページ)
  • 経過日数別グループ表示(未アサインページ)
  • フィルターボタン(全て/未返信)
  • 空状態表示

移行後の実装:

  • 各コントローラーで提出物データを取得
  • Rails viewで提出物一覧をレンダリング
  • kaminariでページネーション
  • パーシャルで個別提出物表示(Product.jsx → product-card.js を活用)

注意点

  • 複数のページで使用されている(4箇所の異なるview)
  • 多様なパラメータ対応(selectedTab、checker_id、target等)
  • 経過日数別グループ表示:未アサインページでの特殊なレイアウト
  • フィルター機能:未返信/全て の切り替え
  • ページネーション:React版50件/ページと同じ設定
  • 空状態表示:複数パターンの空状態メッセージ
  • UnconfirmedLink機能:一括で開くリンク
  • elapsedDays.js統合:経過日数表示のサイドナビゲーション
  • APIの後方互換性:/api/products.json 等の使用状況

React版の複雑な機能

  1. selectedTabによる分岐処理(all/unchecked/unassigned/self_assigned)
  2. 経過日数別グループ化(unassignedタブのみ)
  3. 動的フィルターURL生成
  4. productDeadlineDay基準の経過日数計算
  5. 経過日数サイドナビゲーション(elapsedDays.js使用)

参考資料

チェックリスト

事前調査・準備

  • Product.jsx の素のJS移行(product-card.js)完了確認
  • 依存コンポーネント(Pagination、UnconfirmedLink、LoadingListPlaceholder)の非React化状況確認
  • elapsedDays.js の実装確認
  • 各APIエンドポイント(/api/products、/api/products/unchecked等)の使用状況確認

API・コントローラー

  • products_controller#index でデータ取得の実装
  • products/unchecked_controller#index でデータ取得の実装
  • products/unassigned_controller#index でデータ取得の実装(経過日数別グループ化含む)
  • products/self_assigned_controller#index でデータ取得の実装
  • kaminariによる50件/ページのページネーション実装
  • フィルター機能(checker_id、target等)の実装

View実装

  • products/index.html.slim からReact部分を削除、Rails標準レンダリングに変更
  • products/unchecked/index.html.slim の修正
  • products/unassigned/index.html.slim の修正(経過日数別グループ表示含む)
  • products/self_assigned/index.html.slim の修正
  • 提出物一覧レンダリング(product-card.js使用)の実装
  • フィルターボタン(全て/未返信)の実装
  • 経過日数ヘッダー表示の実装
  • ページネーション表示の実装
  • 空状態表示の実装(複数パターン)

JavaScript統合

  • elapsedDays.js の統合(サイドナビゲーション)
  • product-card.js の初期化
  • UnconfirmedLink機能の実装

テスト・確認

  • 全ての提出物一覧での表示確認
  • 未チェック提出物一覧での表示・フィルタリング確認
  • 未アサイン提出物一覧での経過日数別グループ表示確認
  • 自分の担当提出物一覧での表示・フィルタリング確認
  • ページネーションの動作確認(全ページ)
  • 空状態表示の確認(全パターン)
  • 経過日数サイドナビゲーションの確認
  • 一括で開くリンクの動作確認

段階的クリーンアップ

  • 不要なReactコンポーネントファイルを削除(Products.jsx)
  • APIエンドポイント(/api/products 等)の削除(移行完了後、別PRでも可)
  • 不要なJSライブラリ依存関係の削除(SWR、usePage等)

パフォーマンス・考慮事項

  • 経過日数別グループ化でのN+1問題防止
  • 50件/ページでのパフォーマンス確認
  • フィルター条件でのクエリ最適化
  • elapsedDays.js との統合によるJS初期化タイミング

実装の複雑度について

Products.jsx は非常に複雑なコンポーネントです:

  • 4つの異なるタブモードの条件分岐
  • 経過日数別グループ表示の特殊レイアウト
  • 動的なAPIエンドポイント生成
  • フィルター機能とURL管理

分割戦略

Phase 1: シンプルなページから開始

Issue 1: Products/index.html.slim(全ての提出物)を非React化

  • 対象: app/views/products/index.html.slim のみ
  • 特徴: 最もシンプル(経過日数グループなし、基本的なページネーションのみ)
  • 依存関係: Product.jsx → product-card.js の前提

Issue 2: Products/unchecked/index.html.slim(未チェック提出物)を非React化

  • 対象: app/views/products/unchecked/index.html.slim のみ
  • 特徴: フィルターボタン(全て/未返信)追加
  • 前提: Issue 1完了

Issue 3: Products/self_assigned/index.html.slim(自分の担当提出物)を非React化

  • 対象: app/views/products/self_assigned/index.html.slim のみ
  • 特徴: Issue 2と同様のフィルター機能
  • 前提: Issue 2完了

Phase 2: 最も複雑なページ

Issue 4: Products/unassigned/index.html.slim(未アサイン提出物)を非React化

  • 対象: app/views/products/unassigned/index.html.slim のみ
  • 特徴: 経過日数別グループ表示、サイドナビゲーション
  • 前提: Issue 1-3完了、elapsedDays.js の理解

Phase 3: クリーンアップ

Issue 5: Products.jsx関連のクリーンアップ

  • 対象: APIエンドポイント削除、JSライブラリ依存関係削除
  • 前提: Issue 1-4完了

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    完成

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions