From c96b7818d6d9b254321e473e2609bb606816041d Mon Sep 17 00:00:00 2001
From: Macaulay Precious <87583799+Precious-Macaulay@users.noreply.github.com>
Date: Thu, 22 Feb 2024 02:29:15 +0000
Subject: [PATCH 1/3] Allow user to sort issue #1013 Fix
---
frontend/src/components/task/task-table.js | 164 +++++++++++++++++----
1 file changed, 135 insertions(+), 29 deletions(-)
diff --git a/frontend/src/components/task/task-table.js b/frontend/src/components/task/task-table.js
index 299f4162..633604f7 100644
--- a/frontend/src/components/task/task-table.js
+++ b/frontend/src/components/task/task-table.js
@@ -157,6 +157,70 @@ const styles = theme => ({
},
})
+const tableHeaderMetadata = {
+ "task.table.head.task": { sortable: true, numeric: false, dataBaseKey: "title" },
+ "task.table.head.status": { sortable: true, numeric: false, dataBaseKey: "status" },
+ "task.table.head.project": { sortable: true, numeric: false, dataBaseKey: "Project.name" },
+ "task.table.head.value": { sortable: true, numeric: true, dataBaseKey: "value" },
+ "task.table.head.labels": { sortable: true, numeric: false, dataBaseKey: "Labels" },
+ "task.table.head.createdAt": { sortable: true, numeric: false, dataBaseKey: "createdAt" }
+}
+
+const getSortingValue = (item, fieldId) => {
+ const getValue = (item, dataBaseKey) => {
+ const keys = dataBaseKey.split(".");
+ return keys.reduce((obj, key) => (obj && obj[key] !== 'undefined') ? obj[key] : undefined, item);
+ };
+
+ const metadata = tableHeaderMetadata[fieldId];
+ if (!metadata) {
+ console.error(`No metadata found for fieldId: ${fieldId}`);
+ return null;
+ }
+
+ const { numeric, dataBaseKey } = metadata;
+
+ const value = getValue(item, dataBaseKey);
+
+ if (value === undefined) {
+ console.error(`Failed to get value for fieldId: ${fieldId}`);
+ return null;
+ }
+
+ if (Date.parse(value)) {
+ return new Date(value).getTime();
+ }
+
+ if (numeric) {
+ const parsedValue = parseFloat(value);
+ if (isNaN(parsedValue)) {
+ console.error(`Failed to parse numeric value for fieldId: ${fieldId}`);
+ return null;
+ }
+ return parsedValue;
+ }
+ return value;
+};
+
+const sortData = (data, sortedBy, sortDirection) => {
+ if (sortDirection === 'none') {
+ return data; // Return the original data if no sorting is required
+ }
+
+ return [...data].sort((a, b) => {
+ let aValue = getSortingValue(a, sortedBy);
+ let bValue = getSortingValue(b, sortedBy);
+
+ if (aValue === null || bValue === null) {
+ return 0;
+ }
+
+ const comparator = String(aValue).localeCompare(String(bValue), 'en', { numeric: true, sensitivity: 'base', ignorePunctuation: true });
+
+ return sortDirection === 'asc' ? comparator : -comparator
+ });
+};
+
class CustomPaginationActionsTable extends React.Component {
constructor(props) {
super(props)
@@ -164,9 +228,41 @@ class CustomPaginationActionsTable extends React.Component {
this.state = {
page: 0,
rowsPerPage: 10,
+ sortedBy: null,
+ sortDirection: 'asc',
+ sortedData: this.props.tasks.data
}
}
+ componentDidUpdate(prevProps) {
+ if (prevProps.tasks !== this.props.tasks) {
+ const { sortedBy, sortDirection } = this.state;
+ const newSortedData = sortData(this.props.tasks.data, sortedBy, sortDirection);
+ this.setState({
+ sortedData: newSortedData
+ });
+ }
+ }
+
+ handleSort = (fieldId, sortDirection) => {
+ const newSortedData = sortData(this.props.tasks.data, fieldId, sortDirection);
+
+ return {
+ sortedBy: fieldId,
+ sortDirection,
+ sortedData: newSortedData,
+ };
+ }
+
+ sortHandler = (fieldId) => {
+ this.setState((prevState) => {
+ const { sortedBy, sortDirection } = prevState;
+ const newSortDirection = sortedBy === fieldId ? (sortDirection === 'asc' ? 'desc' : (sortDirection === 'desc' ? 'none' : 'asc')) : 'asc';
+ return this.handleSort(fieldId, newSortDirection);
+ });
+ };
+
+
handleChangePage = (event, page) => {
this.setState({ page })
};
@@ -189,8 +285,39 @@ class CustomPaginationActionsTable extends React.Component {
render() {
const { classes, tasks } = this.props
- const { rowsPerPage, page } = this.state
- const emptyRows = tasks.data.length ? rowsPerPage - Math.min(rowsPerPage, tasks.data.length - page * rowsPerPage) : 0
+ const { rowsPerPage, page, sortedBy, sortDirection, sortedData } = this.state;
+
+ const emptyRows = sortedData.length ? rowsPerPage - Math.min(rowsPerPage, sortedData.length - page * rowsPerPage) : 0
+ const TableCellWithSortLogic = ({ fieldId, defineMessage, sortHandler }) => {
+ return (
+ {
+ return sortHandler(fieldId)
+ }
+ }
+ >
+
+
+ )
+ }
+
+ const TableHeadCustom = () => {
+ console.log()
+ return (
+
+
+ {Object.entries(tableHeaderMetadata).map(([fieldId, metadata]) => (
+
+
+
+ ))}
+
+
+ );
+ };
if (tasks.completed && tasks.data.length === 0) {
@@ -208,30 +335,9 @@ class CustomPaginationActionsTable extends React.Component {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
- {tasks.data.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map(n => {
+ {sortedData.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map(n => {
const assigned = n.Assigns.find(a => a.id === n.assigned)
const assignedUser = assigned && assigned.User
return (
@@ -299,11 +405,11 @@ class CustomPaginationActionsTable extends React.Component {
this.handleChangePage(e, page)}
- onChangeRowsPerPage={(e, page) => this.handleChangeRowsPerPage(e, page)}
+ onPageChange={(e, page) => this.handleChangePage(e, page)}
+ onRowsPerPageChange={(e, page) => this.handleChangeRowsPerPage(e, page)}
Actions={TablePaginationActionsWrapped}
/>
@@ -323,4 +429,4 @@ CustomPaginationActionsTable.propTypes = {
user: PropTypes.object,
}
-export default injectIntl(withRouter(withStyles(styles)(CustomPaginationActionsTable)))
+export default injectIntl(withRouter(withStyles(styles)(CustomPaginationActionsTable)))
\ No newline at end of file
From f98bd0b53bf1d562b1889e3adb27d2f48f6ffafb Mon Sep 17 00:00:00 2001
From: Macaulay Precious <87583799+Precious-Macaulay@users.noreply.github.com>
Date: Thu, 22 Feb 2024 02:43:18 +0000
Subject: [PATCH 2/3] added pmd file to root
---
pmd.xml | 12 ++++++++++++
1 file changed, 12 insertions(+)
create mode 100644 pmd.xml
diff --git a/pmd.xml b/pmd.xml
new file mode 100644
index 00000000..f39b32c2
--- /dev/null
+++ b/pmd.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
From eb5ae7f15cef0552f23c3c88997c7315d34c1dea Mon Sep 17 00:00:00 2001
From: Macaulay Precious <87583799+Precious-Macaulay@users.noreply.github.com>
Date: Sat, 24 Feb 2024 00:39:16 +0000
Subject: [PATCH 3/3] fix sorting issue in task table
---
frontend/src/components/task/task-table.js | 33 ++++++++++++++--------
1 file changed, 21 insertions(+), 12 deletions(-)
diff --git a/frontend/src/components/task/task-table.js b/frontend/src/components/task/task-table.js
index bbea91cb..89218fe5 100644
--- a/frontend/src/components/task/task-table.js
+++ b/frontend/src/components/task/task-table.js
@@ -167,6 +167,7 @@ const tableHeaderMetadata = {
}
const getSortingValue = (item, fieldId) => {
+
const getValue = (item, dataBaseKey) => {
const keys = dataBaseKey.split(".");
return keys.reduce((obj, key) => (obj && obj[key] !== 'undefined') ? obj[key] : undefined, item);
@@ -187,10 +188,6 @@ const getSortingValue = (item, fieldId) => {
return null;
}
- if (Date.parse(value)) {
- return new Date(value).getTime();
- }
-
if (numeric) {
const parsedValue = parseFloat(value);
if (isNaN(parsedValue)) {
@@ -203,21 +200,33 @@ const getSortingValue = (item, fieldId) => {
};
const sortData = (data, sortedBy, sortDirection) => {
- if (sortDirection === 'none') {
- return data; // Return the original data if no sorting is required
- }
+ if (sortDirection === 'none') return data;
return [...data].sort((a, b) => {
let aValue = getSortingValue(a, sortedBy);
let bValue = getSortingValue(b, sortedBy);
+ // Handle null values
if (aValue === null || bValue === null) {
- return 0;
+ return (aValue === null ? (sortDirection === 'asc' ? -1 : 1) : (sortDirection === 'asc' ? 1 : -1));
}
- const comparator = String(aValue).localeCompare(String(bValue), 'en', { numeric: true, sensitivity: 'base', ignorePunctuation: true });
+ // Handle date sorting
+ if (sortedBy === 'task.table.head.createdAt') {
+ let aDate = new Date(aValue).getTime();
+ let bDate = new Date(bValue).getTime();
+ return (sortDirection === 'asc' ? aDate - bDate : bDate - aDate);
+ }
- return sortDirection === 'asc' ? comparator : -comparator
+ // Handle labels array sorting
+ if (sortedBy === 'task.table.head.labels') {
+ aValue = aValue.map(label => label.name).join('');
+ bValue = bValue.map(label => label.name).join('');
+ }
+
+ // Handle string sorting
+ let comparator = String(aValue).localeCompare(String(bValue), 'en', { numeric: true, sensitivity: 'base', ignorePunctuation: true });
+ return (sortDirection === 'asc' ? comparator : -comparator);
});
};
@@ -320,13 +329,13 @@ class CustomPaginationActionsTable extends React.Component {
if (tasks.completed && tasks.data.length === 0) {
-
+ return (
-
+ );
}
return (