diff --git a/src/components/Reports/PeopleTableDetails.jsx b/src/components/Reports/PeopleTableDetails.jsx
index 17d29ea540..508513c8fe 100644
--- a/src/components/Reports/PeopleTableDetails.jsx
+++ b/src/components/Reports/PeopleTableDetails.jsx
@@ -4,6 +4,12 @@ import { useTable } from 'react-table';
import styles from './PeopleTableDetails.module.css';
import TableFilter from './TableFilter/TableFilter';
+/**
+ * TaskResourceCell Component
+ * Renders the primary profile pictures for assigned resources (up to 2),
+ * a collapse/expand toggle button for additional resources, and a hidden/visible
+ * container for extra resources when expanded.
+ */
export function TaskResourceCell({
row,
column,
@@ -57,6 +63,10 @@ export function TaskResourceCell({
);
}
+/**
+ * YesNoCell Component
+ * Renders a centered checkmark for 'Yes' values or a cross mark otherwise.
+ */
export function YesNoCell({ value }) {
return (
@@ -65,11 +75,21 @@ export function YesNoCell({ value }) {
);
}
+/**
+ * CenteredValueCell Component
+ * Renders any standard text value centered within its table cell.
+ */
export function CenteredValueCell({ value }) {
return
{value}
;
}
+/**
+ * PeopleTableDetails Main Component
+ * Manages filtering states, table data configuration using react-table,
+ * desktop table layout, and responsive mobile card view.
+ */
function PeopleTableDetails(props) {
+ // Filter search states
const [name, setName] = useState('');
const [priority, setPriority] = useState('');
const [status, setStatus] = useState('');
@@ -140,7 +160,6 @@ function PeopleTableDetails(props) {
return filteredList;
};
- // REFACTORED: Toggle using state instead of direct DOM manipulation
const toggleMoreResources = useCallback((id) => {
setExpandedTasks((prev) => ({
...prev,
@@ -244,6 +263,7 @@ function PeopleTableDetails(props) {
Clear Filters
+
@@ -283,8 +303,53 @@ function PeopleTableDetails(props) {
+
+
+ {filteredTasks.map((task) => (
+
+
+ {task.taskName}
+ {task.status || 'Started'}
+
+
+
+
Priority
+
{task.priority}
+
+
+
Resources
+
+ {(task.resources || []).flat().map((res, i) => (
+

+ ))}
+
+
+
+
Active
+
{task.active}
+
+
+
Assign
+
{task.assign}
+
+
+
Estimated Hours
+
{task.estimatedHours}
+
+
+
Start Date
+
{task.startDate}
+
+
+
End Date
+
{task.endDate}
+
+
+
+ ))}
+
>
);
}
-export default PeopleTableDetails;
+export default PeopleTableDetails;
\ No newline at end of file
diff --git a/src/components/Reports/PeopleTableDetails.module.css b/src/components/Reports/PeopleTableDetails.module.css
index 2a293a9ed9..db2024613b 100644
--- a/src/components/Reports/PeopleTableDetails.module.css
+++ b/src/components/Reports/PeopleTableDetails.module.css
@@ -1,4 +1,3 @@
-/* stylelint-disable declaration-property-value-no-unknown, no-descending-specificity */
.wrapper {
overflow-x: auto;
width: 100%;
@@ -55,7 +54,6 @@
overflow: hidden;
}
-/* Profile picture styling */
.img-circle {
border-radius: 50%;
height: 30px;
@@ -95,11 +93,16 @@
color: #f1f1f1;
}
+.people-table-row-dark {
+ background-color: transparent !important;
+ color: #fff !important;
+ border-bottom: 1px solid #444 !important;
+}
+
.people-table-row:hover {
background-color: #fafafa;
}
-/* ✅ merged hover style */
.people-table-row-dark:hover {
background-color: #232946 !important;
color: #fff !important;
@@ -153,7 +156,7 @@
.extra {
display: none;
- border: collapse;
+ border: none;
}
.extra1 {
@@ -173,32 +176,54 @@
}
.task-card-dark {
- color: black;
+ color: #fff;
+ background-color: #232946;
+ border: 1px solid #444;
}
.task-header {
background-color: #eee7f8;
display: flex;
justify-content: space-between;
+ align-items: flex-start;
+ gap: 10px;
padding: 15px;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
- align-items: flex-start;
+}
+
+.task-card-dark .task-header {
+ background-color: #1a1a2e;
+ color: #fff;
}
.task-status {
display: flex;
align-items: center;
- padding: 5px 10px;
+ justify-content: center;
+ padding: 4px 10px;
border-radius: 20px;
background-color: #ffc107;
color: #fff;
- width: fit-content;
- margin-left: 5px;
+ flex-shrink: 0;
+ white-space: nowrap;
+ margin-left: 0;
+}
+
+.task-card-dark .task-status {
+ background-color: #ca50db;
+ color: #fff;
}
.task-info {
display: flex;
+ padding: 6px 0;
+ border-bottom: 1px solid #f2f2f2;
+}
+
+.task-card-dark .task-info {
+ border-bottom: 1px solid #374151;
+ color: #fff;
}
.sub-head {
@@ -206,12 +231,22 @@
text-align: end;
width: 50%;
padding-right: 2%;
+ color: #4b5563;
+}
+
+.task-card-dark .sub-head {
+ color: #9ca3af;
}
.sub-details {
text-align: start;
width: 50%;
padding-left: 2%;
+ color: #1f2937;
+}
+
+.task-card-dark .sub-details {
+ color: #fff;
}
.table-filter-container {
@@ -249,74 +284,39 @@
color: #e7b1ef;
}
-/* Dark mode styling for Clear Filters button */
-.wrapperDark .tasks-table-clear-filter-button {
- background-color: #232946 !important;
- border: 2px solid #5A67D8 !important;
- color: #fff !important;
-}
-
-.wrapperDark .tasks-table-clear-filter-button:hover {
- background-color: #1C2541 !important;
- border-color: #ca50db !important;
-}
-
.people-report-task-name {
- overflow-wrap: break-word;
- min-width: 200px;
+ flex: 1;
+ font-weight: 600;
+ font-size: 16px;
text-align: left;
-}
-
-.task-name-word-break {
- word-break: break-all;
+ overflow-wrap: break-word;
}
.people-table-scrollable {
- max-height: 600px;
- overflow-y: auto;
width: 100%;
+ max-height: 600px;
+ overflow: auto;
+ -webkit-overflow-scrolling: touch;
+ box-sizing: border-box;
}
-.peopleTableReact {
- width: 100%;
- min-width: 720px;
- border-collapse: collapse;
-}
-
-.peopleTableReact th,
-.peopleTableReact td {
- padding: 8px;
- text-align: left;
- overflow-wrap: break-word;
- vertical-align: middle;
-}
-
-.peopleTableReact th {
- background-color: #eee7f8;
- font-size: 18px;
-}
-
-.peopleTableReact td {
- border-bottom: 1px solid #f8f7f8;
- font-size: 16px;
+.people-table-scrollable::-webkit-scrollbar {
+ height: 8px;
+ width: 8px;
}
-.peopleTableReact th:first-child,
-.peopleTableReact td:first-child {
- width: 28%;
-}
-
-.peopleTableReact th:nth-child(4),
-.peopleTableReact td:nth-child(4) {
- width: 14%;
+.people-table-scrollable::-webkit-scrollbar-track {
+ background: #162032;
+ border-radius: 4px;
}
-.peopleTableReact tbody tr:hover {
- background-color: #fafafa;
+.people-table-scrollable::-webkit-scrollbar-thumb {
+ background: #4b5563;
+ border-radius: 4px;
}
-.people-table-row-dark td {
- border-color: #374151;
+.people-table-scrollable::-webkit-scrollbar-thumb:hover {
+ background: #6b7280;
}
.reports-table-head-dark th {
@@ -324,81 +324,68 @@
color: #f9fafb;
}
-.wrapperDark .people-table-scrollable {
- background-color: #162032;
- border: 1px solid #3a4460;
- border-radius: 8px;
- padding: 4px 0;
-}
-
-/* Dark mode for mobile modal cards */
-.task-card.task-card-dark {
- background-color: #232946;
- color: #fff;
- border: 1px solid #444;
-}
-
-.task-card.task-card-dark .task-header {
- background-color: #1a1a2e;
- color: #fff;
+.reports-table-head-dark {
+ background-color: #1a1a2e !important;
+ color: #fff !important;
+ border-bottom: 1px solid #444 !important;
}
-.task-card.task-card-dark .task-status {
- background-color: #ca50db;
- color: #fff;
+.people-table-row-dark td {
+ border-color: #374151;
}
-.task-card.task-card-dark .task-info {
- color: #fff;
+.peopleTableReact {
+ width: 100%;
+ min-width: 850px;
+ border-collapse: collapse;
}
-.task-card.task-card-dark .sub-head,
-.task-card.task-card-dark .sub-details {
- color: #fff;
+.peopleTableReact th,
+.peopleTableReact td {
+ padding: 8px;
+ text-align: left;
+ overflow-wrap: break-word;
+ vertical-align: middle;
}
-/* Modal textarea dark mode */
-.task-card-dark .rectangle {
- background: #232946;
- color: #fff;
- border: 1.5px solid #444;
+.peopleTableReact th:first-child,
+.peopleTableReact td:first-child {
+ width: 28%;
+ min-width: 260px;
+ max-width: 350px;
+ overflow-wrap: break-word;
}
-/* Desktop table dark mode */
-.reports-table-head-dark {
- background-color: #1a1a2e !important;
+.people-table-row-dark > div,
+.reports-table-head-dark > div {
color: #fff !important;
}
-.people-table-row-dark {
- background-color: transparent !important;
- color: #fff !important;
+.centerColumn {
+ text-align: center !important;
}
-.people-table-row-dark > div,
-.reports-table-head-dark > div {
- color: #fff !important;
+:global(.dark-mode) .peopleTableReact {
+ background-color: #1b2a41;
+ color: #f9fafb;
}
-.people-table-row-dark .people-table-center-cell,
-.people-table-row-dark .people-table-end-cell {
- color: #fff !important;
+:global(.dark-mode) .people-table-row-dark {
+ background-color: #1b2a41 !important;
+ color: #f9fafb !important;
}
-/* Table cell border for dark mode */
-.people-table-row-dark,
-.reports-table-head-dark {
- border-bottom: 1px solid #444 !important;
+.mobileCardContainer {
+ display: none;
}
-/* Table textarea dark mode */
-.people-table-row-dark .rectangle,
-.reports-table-head-dark .rectangle {
- background: #232946;
- color: #fff;
- border: 1px solid #444;
-}
+@media (width <= 600px) {
+ .people-table-scrollable {
+ display: none !important;
+ }
-.centerColumn {
- text-align: center !important;
+ .mobileCardContainer {
+ display: block !important;
+ width: 100%;
+ }
}
\ No newline at end of file
diff --git a/src/components/Reports/__tests__/PeopleTableDetails.test.jsx b/src/components/Reports/__tests__/PeopleTableDetails.test.jsx
index b7bfd66c84..6589022558 100644
--- a/src/components/Reports/__tests__/PeopleTableDetails.test.jsx
+++ b/src/components/Reports/__tests__/PeopleTableDetails.test.jsx
@@ -64,9 +64,9 @@ describe('Unit Test case for PeopleTableDetails component', () => {
it('Test 3 : Verify row data renders', () => {
render();
- expect(screen.getByText('Task 1')).toBeInTheDocument();
- expect(screen.getByText('Task 2')).toBeInTheDocument();
- expect(screen.getByText('Task 3')).toBeInTheDocument();
+ expect(screen.getAllByText('Task 1')[0]).toBeInTheDocument();
+ expect(screen.getAllByText('Task 2')[0]).toBeInTheDocument();
+ expect(screen.getAllByText('Task 3')[0]).toBeInTheDocument();
});
it('displays a task with no resources and no start date', () => {
@@ -78,7 +78,7 @@ describe('Unit Test case for PeopleTableDetails component', () => {
render();
- expect(screen.getByText('Unassigned task')).toBeInTheDocument();
+ expect(screen.getAllByText('Unassigned task')[0]).toBeInTheDocument();
});
it('Test 5 : Verify no toggle button if resources < 2', () => {
@@ -88,14 +88,14 @@ describe('Unit Test case for PeopleTableDetails component', () => {
it('Test 6 : Verify button renders if resources > 2', () => {
render();
- expect(screen.getByRole('button', { name: /^\d+\+$/ })).toBeInTheDocument();
+ expect(screen.getAllByRole('button', { name: /^\d+\+$/ })[0]).toBeInTheDocument();
});
it('shows resource toggle button when there are more than 2 resources', () => {
render();
- expect(screen.getByText('Project 2')).toBeInTheDocument();
- const toggleButton = screen.getByText('1+');
+ expect(screen.getAllByText('Project 2')[0]).toBeInTheDocument();
+ const toggleButton = screen.getAllByText('1+')[0];
expect(toggleButton).toBeInTheDocument();
});
@@ -103,7 +103,7 @@ describe('Unit Test case for PeopleTableDetails component', () => {
const taskId = taskFixtureThreeNamedResources[0]._id;
render();
- const toggleButton = screen.getByRole('button', { name: /^\d+\+$/ });
+ const toggleButton = screen.getAllByRole('button', { name: /^\d+\+$/ })[0];
expect(toggleButton).toBeInTheDocument();
expect(screen.getByTestId(`extra-resources-${taskId}`)).toBeInTheDocument();
@@ -112,13 +112,13 @@ describe('Unit Test case for PeopleTableDetails component', () => {
display: 'table-cell',
});
- fireEvent.click(screen.getByRole('button', { name: /^\d+\+$/ }));
+ fireEvent.click(screen.getAllByRole('button', { name: /^\d+\+$/ })[0]);
expect(screen.getByTestId(`extra-resources-${taskId}`)).toHaveStyle({ display: 'none' });
});
it('Test 8 : Verify remaining resource count displayed', () => {
render();
- expect(screen.getByText('2+')).toBeInTheDocument();
+ expect(screen.getAllByText('2+')[0]).toBeInTheDocument();
});
});
@@ -137,7 +137,7 @@ describe('TaskResourceCell', () => {
{...baseProps}
/>,
);
- expect(screen.getByText('1+')).toBeInTheDocument();
+ expect(screen.getAllByText('1+')[0]).toBeInTheDocument();
});
it('shows the extra-resources block when the task is in expandedTasks', () => {
@@ -163,7 +163,7 @@ describe('TaskResourceCell', () => {
toggleMoreResources={toggleMoreResources}
/>,
);
- fireEvent.click(screen.getByText('1+'));
+ fireEvent.click(screen.getAllByText('1+')[0]);
expect(toggleMoreResources).toHaveBeenCalledWith(task._id);
});
});
@@ -185,4 +185,4 @@ describe('CenteredValueCell', () => {
render();
expect(screen.getByText('2022-01-01')).toHaveStyle({ textAlign: 'center' });
});
-});
+});
\ No newline at end of file