Skip to content

Commit 123cf2c

Browse files
Merge pull request #4842 from OneCommunityGlobal/Swathi_PR_Review_Team_Usability
Swathi- PR Review Team Analytics Dashboard Usability
2 parents 9672f78 + 541810a commit 123cf2c

8 files changed

Lines changed: 123 additions & 88 deletions

File tree

src/components/PRGradingDashboard/GradingTable.jsx

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,40 +11,40 @@ function GradingTable({
1111
onAddGradedPR,
1212
}) {
1313
return (
14-
<div className={styles.tableWrapper}>
15-
<table className={styles.table}>
16-
<thead className={styles.tableHead}>
17-
<tr>
18-
<th className={styles.tableHeader}>Reviewer Name</th>
19-
<th className={styles.tableHeader}>PRs Reviewed</th>
20-
<th className={styles.tableHeader}>PRs Needed</th>
21-
<th className={styles.tableHeader}>PR Actions</th>
22-
</tr>
23-
</thead>
24-
<tbody className={styles.tableBody}>
25-
{gradings.map((grading, index) => (
26-
<React.Fragment key={grading.reviewer}>
27-
<ReviewerRow
28-
grading={grading}
29-
onUpdatePRsReviewed={onUpdatePRsReviewed}
30-
onAddPRClick={onAddPRClick}
31-
/>
32-
{openAddModal === grading.reviewer && (
33-
<tr className={styles.modalRow}>
34-
<td colSpan="4" className={styles.modalCell}>
35-
<AddPRModal
36-
reviewer={grading.reviewer}
37-
onAdd={onAddGradedPR}
38-
onCancel={() => onAddPRClick(null)}
39-
/>
40-
</td>
41-
</tr>
42-
)}
43-
</React.Fragment>
44-
))}
45-
</tbody>
46-
</table>
47-
</div>
14+
// <div className={styles.tableWrapper}>
15+
<table className={styles.table}>
16+
<thead className={styles.tableHead}>
17+
<tr>
18+
<th className={styles.tableHeader}>Reviewer Name</th>
19+
<th className={styles.tableHeader}>PRs Reviewed</th>
20+
<th className={styles.tableHeader}>PRs Needed</th>
21+
<th className={styles.tableHeader}>PR Actions</th>
22+
</tr>
23+
</thead>
24+
<tbody className={styles.tableBody}>
25+
{gradings.map((grading, index) => (
26+
<React.Fragment key={grading.reviewer}>
27+
<ReviewerRow
28+
grading={grading}
29+
onUpdatePRsReviewed={onUpdatePRsReviewed}
30+
onAddPRClick={onAddPRClick}
31+
/>
32+
{openAddModal === grading.reviewer && (
33+
<tr className={styles.modalRow}>
34+
<td colSpan="4" className={styles.modalCell}>
35+
<AddPRModal
36+
reviewer={grading.reviewer}
37+
onAdd={onAddGradedPR}
38+
onCancel={() => onAddPRClick(null)}
39+
/>
40+
</td>
41+
</tr>
42+
)}
43+
</React.Fragment>
44+
))}
45+
</tbody>
46+
</table>
47+
// </div>
4848
);
4949
}
5050

src/components/PRGradingDashboard/GradingTable.module.css

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
1-
.tableWrapper {
2-
overflow-x: auto;
3-
overflow-y: visible;
4-
}
5-
61
.table {
72
width: 100%;
8-
min-width: 100%;
93
border-collapse: collapse;
104
}
115

src/components/PRGradingDashboard/PRGradingDashboard.jsx

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import SummaryList from './SummaryList';
66
import ConfirmationModal from './ConfirmationModal';
77
import AddReviewerModal from './AddReviewerModal';
88
import styles from './PRGradingDashboard.module.css';
9+
import { SelectionProvider } from './SelectionContext';
910

1011
const TEAM_CODE = 'TeamA';
1112
const TEAM_NAME = 'Team Alpha';
@@ -249,47 +250,48 @@ function PRGradingDashboard() {
249250
</div>
250251

251252
{/* Main Table */}
252-
<div className={styles.section}>
253-
<div className={styles.tableHeaderActions}>
254-
<button
255-
type="button"
256-
onClick={() => setShowAddReviewerModal(true)}
257-
className={styles.addReviewerButton}
258-
>
259-
+ Add Reviewer
260-
</button>
253+
<SelectionProvider>
254+
<div className={styles.section}>
255+
<div className={styles.tableHeaderActions}>
256+
<button
257+
type="button"
258+
onClick={() => setShowAddReviewerModal(true)}
259+
className={styles.addReviewerButton}
260+
>
261+
+ Add Reviewer
262+
</button>
263+
</div>
264+
<GradingTable
265+
gradings={gradings}
266+
onUpdatePRsReviewed={updatePRsReviewed}
267+
onAddPRClick={setOpenAddModal}
268+
openAddModal={openAddModal}
269+
onAddGradedPR={requestAddGradedPR}
270+
/>
261271
</div>
262-
<GradingTable
263-
gradings={gradings}
264-
onUpdatePRsReviewed={updatePRsReviewed}
265-
onAddPRClick={setOpenAddModal}
266-
openAddModal={openAddModal}
267-
onAddGradedPR={requestAddGradedPR}
268-
/>
269-
</div>
270272

271-
{/* Summary Section */}
272-
<div className={styles.summarySection}>
273-
<h2 className={styles.summaryTitle}>Summary</h2>
274-
<SummaryList
275-
gradings={gradings}
276-
onUpdateGrade={updateGrade}
277-
onRemovePR={removeGradedPR}
278-
/>
279-
</div>
273+
{/* Summary Section */}
274+
<div className={styles.summarySection}>
275+
<h2 className={styles.summaryTitle}>Summary</h2>
276+
<SummaryList
277+
gradings={gradings}
278+
onUpdateGrade={updateGrade}
279+
onRemovePR={removeGradedPR}
280+
/>
281+
</div>
282+
</SelectionProvider>
280283

281284
{/* Footer */}
282-
<div className={styles.footer}>
283-
<div className={styles.footerContent}>
284-
<button
285-
onClick={handleSave}
286-
disabled={saving}
287-
type="button"
288-
className={styles.saveButton}
289-
>
290-
{saving ? 'Saving...' : 'Save'}
291-
</button>
292-
</div>
285+
286+
<div className={styles.footerContent}>
287+
<button
288+
onClick={handleSave}
289+
disabled={saving}
290+
type="button"
291+
className={styles.saveButton}
292+
>
293+
{saving ? 'Saving...' : 'Save'}
294+
</button>
293295
</div>
294296
</div>
295297

src/components/PRGradingDashboard/PRGradingDashboard.module.css

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
* {
2+
min-width: 0;
3+
}
14
.container {
25
min-height: 100vh;
36
background-color: #f9fafb;
@@ -40,7 +43,7 @@
4043
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
4144
padding: 1.5rem;
4245
margin-bottom: 1.5rem;
43-
overflow: visible;
46+
overflow-x: auto;
4447
}
4548

4649
.tableHeaderActions {
@@ -87,16 +90,14 @@
8790
margin-bottom: 1rem;
8891
}
8992

90-
.footer {
91-
background-color: white;
92-
border-radius: 0.5rem;
93-
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
94-
padding: 1.5rem;
95-
}
96-
9793
.footerContent {
9894
display: flex;
9995
justify-content: flex-end;
96+
position: fixed;
97+
bottom: 0;
98+
right: 2.5rem;
99+
padding: 2rem;
100+
padding-bottom: 0.5rem;
100101
}
101102

102103
.saveButton {

src/components/PRGradingDashboard/ReviewerRow.jsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import React from 'react';
22
import { Plus } from 'lucide-react';
33
import styles from './ReviewerRow.module.css';
4+
import { useRowSelection } from './SelectionContext';
45

56
function ReviewerRow({ grading, onUpdatePRsReviewed, onAddPRClick }) {
7+
const { activeId, selectRow } = useRowSelection();
8+
69
const handlePRsReviewedChange = e => {
710
const value = e.target.value;
811
// Allow empty string for better UX, but convert to 0 on blur if invalid
@@ -21,7 +24,9 @@ function ReviewerRow({ grading, onUpdatePRsReviewed, onAddPRClick }) {
2124
return (
2225
<tr className={styles.row}>
2326
<td className={styles.cell}>
24-
<div className={styles.reviewerName}>{grading.reviewer}</div>
27+
<button className={styles.reviewerName} onClick={() => selectRow(grading.reviewer)}>
28+
{grading.reviewer}
29+
</button>
2530
</td>
2631
<td className={styles.cell}>
2732
<input

src/components/PRGradingDashboard/ReviewerRow.module.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
font-size: 0.875rem;
1616
font-weight: 500;
1717
color: #111827;
18+
cursor: pointer;
1819
}
1920

2021
.prsReviewedInput {
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { createContext, useContext, useState } from 'react';
2+
3+
const SelectionContext = createContext();
4+
5+
export const SelectionProvider = ({ children }) => {
6+
const [activeId, setActiveId] = useState(null);
7+
8+
const selectRow = id => setActiveId(id);
9+
10+
return (
11+
<SelectionContext.Provider value={{ activeId, selectRow }}>
12+
{children}
13+
</SelectionContext.Provider>
14+
);
15+
};
16+
17+
export const useRowSelection = () => useContext(SelectionContext);

src/components/PRGradingDashboard/SummaryList.jsx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,29 @@
1-
import React from 'react';
1+
import React, { useRef, useEffect } from 'react';
22
import { Trash2 } from 'lucide-react';
33
import styles from './SummaryList.module.css';
4+
import { useRowSelection } from './SelectionContext';
45

56
const GRADE_OPTIONS = ['Unsatisfactory', 'Okay', 'Exceptional', 'No Correct Image'];
67

78
function SummaryList({ gradings, onUpdateGrade, onRemovePR }) {
9+
const { activeId } = useRowSelection();
10+
const rowRefs = useRef({});
11+
12+
useEffect(() => {
13+
if (activeId && rowRefs.current[activeId]) {
14+
rowRefs.current[activeId].scrollIntoView({ behavior: 'smooth' });
15+
}
16+
}, [activeId]);
17+
818
return (
919
<div className={styles.container}>
1020
{gradings.map(grading => (
11-
<div key={grading.reviewer} className={styles.reviewerSection}>
21+
<div
22+
key={grading.reviewer}
23+
id={grading.reviewer}
24+
className={styles.reviewerSection}
25+
ref={el => (rowRefs.current[grading.reviewer] = el)}
26+
>
1227
<h3 className={styles.reviewerName}>{grading.reviewer}</h3>
1328
{grading.gradedPrs.length === 0 ? (
1429
<p className={styles.emptyMessage}>No graded PRs yet</p>

0 commit comments

Comments
 (0)