Skip to content

Commit 397908c

Browse files
committed
Make table sortable
1 parent e990b68 commit 397908c

File tree

2 files changed

+82
-50
lines changed

2 files changed

+82
-50
lines changed

Frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"@testing-library/jest-dom": "^5.17.0",
88
"@testing-library/react": "^13.4.0",
99
"@testing-library/user-event": "^13.5.0",
10+
"ag-grid-react": "^32.3.2",
1011
"axios": "^1.7.7",
1112
"bootstrap": "^5.3.3",
1213
"jwt-decode": "^4.0.0",

Frontend/src/components/question/Question.jsx

Lines changed: 81 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import ButtonGroup from "react-bootstrap/ButtonGroup";
55
import CreateQn from "./CreateQn";
66
import EditQn from "./EditQn";
77
import questionService from "../../services/questions"
8+
import { AgGridReact } from 'ag-grid-react'; // React Data Grid Component
9+
import "ag-grid-community/styles/ag-grid.css"; // Mandatory CSS required by the Data Grid
10+
import "ag-grid-community/styles/ag-theme-quartz.css"; // Optional Theme applied to the Data Grid
811

912
function Question() {
1013
const [questions, setQuestions] = useState([]);
@@ -24,10 +27,6 @@ function Question() {
2427
})
2528
.catch(err => console.log(err));
2629
}, []);
27-
28-
const easyQuestions = questions.filter(q => q.complexity === "Easy")
29-
const mediumQuestions = questions.filter(q => q.complexity === "Medium")
30-
const hardQuestions = questions.filter(q => q.complexity === "Hard")
3130

3231
const addQuestion = (newQuestion) => {
3332
setQuestions((prevQuestions) => [...prevQuestions, newQuestion]);
@@ -74,50 +73,88 @@ function Question() {
7473
}
7574
};
7675

77-
const renderQuestionsTable = (questions) => {
78-
const sortedQuestions = [...questions].sort((a, b) => a.id - b.id)
76+
const renderQuestionsTable = () => {
77+
const CustomButtonComponent = (props) => {
78+
const question = props.data
79+
return <ButtonGroup className="mb-2">
80+
<button
81+
className='btn btn-success'
82+
onClick={() => handleShowEditModal(question)}
83+
>
84+
Edit
85+
</button>
86+
<button className='btn btn-danger' size="sm"
87+
onClick={() => handleShowDelete(question._id)}>
88+
Delete
89+
</button>
90+
</ButtonGroup>
91+
};
92+
93+
const colDefs = [
94+
{ field: "id", flex: 1, wrapText: true, sort: "asc" },
95+
{ field: "title", flex: 2 },
96+
{ field: "description", flex: 5, wrapText: true, autoHeight: true},
97+
{ field: "complexity", flex: 1.5,
98+
comparator: (valueA, valueB, nodeA, nodeB, isDescending) => {
99+
if (valueA == valueB) return 0;
100+
if (valueA == "Easy" || valueB == "Hard") return -1;
101+
if (valueA == "Hard" || valueB == "Easy") return 1;
102+
}
103+
},
104+
{ field: "action", width: 200, resizable: false, sortable: false, cellRenderer: CustomButtonComponent }
105+
];
79106

80107
return (
81-
<Table>
82-
<thead>
83-
<tr>
84-
<th>ID</th>
85-
<th>Title</th>
86-
<th>Description</th>
87-
<th>Category</th>
88-
<th>Action</th>
89-
</tr>
90-
</thead>
91-
<tbody>
92-
{sortedQuestions.map((question) => (
93-
<tr key={question.id}>
94-
<td>{question.id}</td>
95-
<td>{question.title}</td>
96-
<td>{question.description}</td>
97-
<td>{question.category ? question.category.join(", ") : ''}</td>
98-
<td>
99-
<ButtonGroup className="mb-2">
100-
<button
101-
className='btn btn-success'
102-
onClick={() => handleShowEditModal(question)}
103-
>
104-
Edit
105-
</button>
106-
<button className='btn btn-danger' size="sm"
107-
onClick={() => handleShowDelete(question._id)}>
108-
Delete
109-
</button>
110-
</ButtonGroup>
111-
</td>
112-
</tr>
113-
))}
114-
</tbody>
115-
</Table>
108+
<div
109+
className="container-fluid ag-theme-quartz" // applying the Data Grid theme
110+
style={{ height: 500 }} // the Data Grid will fill the size of the parent container
111+
>
112+
<AgGridReact
113+
rowData={questions}
114+
columnDefs={colDefs}
115+
/>
116+
</div>
117+
118+
// <Table>
119+
// <thead>
120+
// <tr>
121+
// <th>ID</th>
122+
// <th>Title</th>
123+
// <th>Description</th>
124+
// <th>Category</th>
125+
// <th>Action</th>
126+
// </tr>
127+
// </thead>
128+
// <tbody>
129+
// {sortedQuestions.map((question) => (
130+
// <tr key={question.id}>
131+
// <td>{question.id}</td>
132+
// <td>{question.title}</td>
133+
// <td>{question.description}</td>
134+
// <td>{question.category ? question.category.join(", ") : ''}</td>
135+
// <td>
136+
// <ButtonGroup className="mb-2">
137+
// <button
138+
// className='btn btn-success'
139+
// onClick={() => handleShowEditModal(question)}
140+
// >
141+
// Edit
142+
// </button>
143+
// <button className='btn btn-danger' size="sm"
144+
// onClick={() => handleShowDelete(question._id)}>
145+
// Delete
146+
// </button>
147+
// </ButtonGroup>
148+
// </td>
149+
// </tr>
150+
// ))}
151+
// </tbody>
152+
// </Table>
116153
);
117154
};
118155

119156
return (
120-
<div className="d-flex">
157+
<div className="container-fluid">
121158
<div className='bg-white rounded p-3 m-3'>
122159
<div className="d-flex justify-content-between">
123160
<h1>Questions</h1>
@@ -137,14 +174,8 @@ function Question() {
137174
<hr/>
138175

139176
<div className="container">
140-
<h2 className="p-2">Easy Questions</h2>
141-
{renderQuestionsTable(easyQuestions)}
142-
143-
<h2 className="p-2">Medium Questions</h2>
144-
{renderQuestionsTable(mediumQuestions)}
145-
146-
<h2 className="p-2">Hard Questions</h2>
147-
{renderQuestionsTable(hardQuestions)}
177+
<h2 className="p-2">Questions</h2>
178+
{renderQuestionsTable()}
148179

149180
{/* Edit Modal */}
150181
<Modal show={showEditModal} onHide={handleCloseEditModal} backdrop="static">

0 commit comments

Comments
 (0)