-
Notifications
You must be signed in to change notification settings - Fork 2
Feat/walt/purchase report sort frontend #1044
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
base: develop
Are you sure you want to change the base?
Conversation
…it into the purchase reports page
… the purchase reports page
…it into the purchase reports page
… the purchase reports page
Summary of ChangesHello @nakatashingo, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! このプルリクエストは、購入報告一覧ページのユーザビリティを大幅に向上させるための機能追加です。具体的には、立替者(局名および氏名)による絞り込み機能と、未清算金額および未封詰め金額の合計表示機能が導入されました。これにより、ユーザーはより効率的に必要な情報を探し、全体の財務状況を把握できるようになります。 Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
Deploying finansu with
|
| Latest commit: |
29d8823
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://a09fe70f.finansu.pages.dev |
| Branch Preview URL: | https://feat-walt-purchase-report-so.finansu.pages.dev |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
このプルリクエストでは、購入報告一覧ページに立替者による絞り込み機能と、未清算・未封詰め金額の合計表示機能が追加されました。新機能の実装は概ね良好ですが、状態管理のロジックにいくつか改善の余地があります。特に、絞り込みモーダル内の状態管理が冗長であり、簡潔にすることができます。また、APIからのデータ取得部分で、より堅牢な型チェックを行うことで、将来的なエラーを防ぐことができます。詳細は各コメントを参照してください。
|
|
||
| const { data: usersResponse } = useGetUsers(); | ||
| const users = useMemo(() => { | ||
| const responseData = usersResponse?.data as User[] | { data?: User[] } | undefined; | ||
| if (Array.isArray(responseData)) return responseData; | ||
| return responseData?.data ?? []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
useGetUsersフックからのデータ抽出ロジックが、型アサーションに依存しており、堅牢性に欠ける可能性があります。orvalで生成されたuseGetUsersの戻り値の型がvoidになっているようですが、実際には{ data: User[] }またはUser[]のようなデータが返却されていると推測されます。この不一致は、APIスキーマ定義の誤りやorvalの設定に起因する可能性があります。
現状のコードは型アサーション as User[] | { data?: User[] } | undefined を使ってこの問題を回避していますが、APIのレスポンス形式が想定外のものに変わった場合にランタイムエラーを引き起こす可能性があります。
根本的な解決としてはAPIスキーマやorvalの設定を見直すべきですが、コンポーネントレベルでの改善として、より安全な型ガードを使用するか、この実装のリスクについてコメントを残しておくことを推奨します。
|
|
||
| const [selectedYear, setSelectedYear] = useState<number>( | ||
| yearPeriods && yearPeriods.length > 0 ? yearPeriods[yearPeriods.length - 1].year : 0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| const [draftPaidByUserId, setDraftPaidByUserId] = useState<number | null | undefined>( | ||
| selectedPaidByUserId, | ||
| ); | ||
|
|
||
| useEffect(() => { | ||
| if (!isOpen) return; | ||
| setDraftBureauId(selectedBureauId); | ||
| setDraftPaidByUserId(selectedPaidByUserId); | ||
| }, [isOpen, selectedBureauId, selectedPaidByUserId]); | ||
|
|
||
| const bureauNameMap = useMemo( | ||
| () => | ||
| new Map( | ||
| bureaus.map((bureau) => [bureau.id ?? 0, bureau.name] as const).filter(([id]) => id > 0), | ||
| ), | ||
| [bureaus], | ||
| ); | ||
|
|
||
| const filteredUsers = useMemo(() => { | ||
| if (!draftBureauId) return users; | ||
| return users.filter((user) => user.bureauID === draftBureauId); | ||
| }, [draftBureauId, users]); | ||
|
|
||
| const paidBySelectValue = draftPaidByUserId === null ? 'none' : draftPaidByUserId ?? ''; | ||
|
|
||
| const handleBureauChange = (event: React.ChangeEvent<HTMLSelectElement>) => { | ||
| const value = event.target.value; | ||
| const nextBureauId = value === '' ? null : Number(value); | ||
| setDraftBureauId(nextBureauId); | ||
| setDraftPaidByUserId(undefined); | ||
| }; | ||
|
|
||
| const handlePaidByChange = (event: React.ChangeEvent<HTMLSelectElement>) => { | ||
| const value = event.target.value; | ||
| if (value === '') { | ||
| setDraftPaidByUserId(undefined); | ||
| return; | ||
| } | ||
| if (value === 'none') { | ||
| setDraftPaidByUserId(null); | ||
| return; | ||
| } | ||
| setDraftPaidByUserId(Number(value)); | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
draftPaidByUserId の状態管理に number | null | undefined の3つの型が使われており、コードが少し複雑になっています。現状では null と undefined が両方とも「絞り込みなし」を意味するように見え、冗長です。
draftBureauId が number | null で管理されているように、draftPaidByUserId も number | null に統一し、null を「絞り込みなし」として扱うことで、コードをシンプルにし、一貫性を高めることができます。
以下の提案では、関連する状態とハンドラを null を使うように修正しています。
これに合わせて、96行目の option の value も 'none' から '' に変更してください: <option value=''>絞り込みなし</option>
const [draftPaidByUserId, setDraftPaidByUserId] = useState<number | null>(
selectedPaidByUserId ?? null,
);
useEffect(() => {
if (!isOpen) return;
setDraftBureauId(selectedBureauId);
setDraftPaidByUserId(selectedPaidByUserId ?? null);
}, [isOpen, selectedBureauId, selectedPaidByUserId]);
const bureauNameMap = useMemo(
() =>
new Map(
bureaus.map((bureau) => [bureau.id ?? 0, bureau.name] as const).filter(([id]) => id > 0),
),
[bureaus],
);
const filteredUsers = useMemo(() => {
if (!draftBureauId) return users;
return users.filter((user) => user.bureauID === draftBureauId);
}, [draftBureauId, users]);
const paidBySelectValue = draftPaidByUserId ?? '';
const handleBureauChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
const value = event.target.value;
const nextBureauId = value === '' ? null : Number(value);
setDraftBureauId(nextBureauId);
setDraftPaidByUserId(null);
};
const handlePaidByChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
const value = event.target.value;
setDraftPaidByUserId(value === '' ? null : Number(value));
};
対応Issue
https://www.notion.so/nutfes-nutmeg/FinanSu-2b941f19206380518f1af6de573da465
https://nut-m-e-g.slack.com/archives/C020WQ3GY07/p1765010563203229
概要
画面スクリーンショット等
URLスクリーンショット
テスト項目
備考