Skip to content

Commit fc398fd

Browse files
committed
fix(projects): Show Archived Projects
1 parent 86a2ef6 commit fc398fd

5 files changed

Lines changed: 68 additions & 44 deletions

File tree

src/components/Projects/Project/Project.jsx

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import { useState, useEffect } from 'react';
22
import PropTypes from 'prop-types';
3-
import { ARCHIVE } from './../../../languages/en/ui';
4-
// old CSS removed
5-
// import './../projects.css';
3+
import { UNARCHIVE, ARCHIVE } from './../../../languages/en/ui';
64
import styles from './../projects.module.css';
75
import { Link } from 'react-router-dom';
86
import { NavItem } from 'reactstrap';
@@ -213,14 +211,14 @@ const Project = props => {
213211
{canDeleteProject ? (
214212
<td>
215213
<button
216-
data-testid="delete-button"
217-
type="button"
218-
className="btn btn-outline-danger"
219-
style={darkMode ? { borderColor: '#D2042D' } : boxStyle}
220-
onClick={onArchiveProject}
221-
>
222-
{ARCHIVE}
223-
</button>
214+
data-testid="delete-button"
215+
type="button"
216+
className="btn btn-outline-danger"
217+
style={darkMode ? { borderColor: '#D2042D' } : boxStyle}
218+
onClick={onArchiveProject}
219+
>
220+
{projectData?.isArchived ? UNARCHIVE : ARCHIVE}
221+
</button>
224222
</td>
225223
) : null}
226224
</tr>

src/components/Projects/Projects.jsx

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { useState, useEffect } from 'react';
44
import PropTypes from 'prop-types';
55
import { connect , useSelector } from 'react-redux';
66
import SearchProjectByPerson from '~/components/SearchProjectByPerson/SearchProjectByPerson';
7-
import { fetchAllProjects, modifyProject, clearError } from '../../actions/projects';
7+
import { fetchAllProjects, fetchAllArchivedProjects, modifyProject, clearError } from '../../actions/projects';
88
import { fetchProjectsWithActiveUsers } from '../../actions/projectMembers';
99
import { getProjectsByUsersName } from '../../actions/userProfile';
1010
import { getPopupById } from '../../actions/popupEditorAction';
@@ -58,6 +58,20 @@ const Projects = function(props) {
5858
const [isArchiving, setIsArchiving] = useState(false);
5959
const [searchMode, setSearchMode] = useState('person');
6060

61+
const [showArchived, setShowArchived] = useState(false);
62+
63+
const handleFetchArchivedProjects = () => {
64+
setShowArchived(prev => {
65+
const next = !prev;
66+
if (next) {
67+
props.fetchAllArchivedProjects();
68+
} else {
69+
props.fetchAllProjects();
70+
}
71+
return next;
72+
});
73+
};
74+
6175
const useDebounce = (value, delay) => {
6276
const [debouncedValue, setDebouncedValue] = useState(value);
6377

@@ -82,8 +96,8 @@ const Projects = function(props) {
8296
setProjectTarget(projectData);
8397
setModalData({
8498
showModal: true,
85-
modalMessage: `<p style="${darkMode ? 'color: white' : 'color: black;'}">Do you want to archive ${projectData.projectName}?</p>`,
86-
modalTitle: CONFIRM_ARCHIVE,
99+
modalMessage: `<p style="${darkMode ? 'color: white' : 'color: black'}">Do you want to ${projectData.isArchived ? 'unarchive' : 'archive'} ${projectData.projectName}?</p>`,
100+
modalTitle: projectData.isArchived ? 'Confirm Unarchive' : CONFIRM_ARCHIVE,
87101
hasConfirmBtn: true,
88102
hasInactiveBtn: false,
89103
hasActiveBtn: false,
@@ -154,11 +168,15 @@ const Projects = function(props) {
154168
};
155169

156170
const confirmArchive = async () => {
157-
setIsArchiving(true); // show loading on confirm
158-
const updatedProject = { ...projectTarget, isArchived: true };
171+
setIsArchiving(true);
172+
const updatedProject = { ...projectTarget, isArchived: !projectTarget.isArchived };
159173
await onUpdateProject(updatedProject);
160-
await props.fetchAllProjects();
161-
setIsArchiving(false); // reset loading
174+
if (showArchived) {
175+
await props.fetchAllArchivedProjects(); // stay in archived view after unarchiving
176+
} else {
177+
await props.fetchAllProjects();
178+
}
179+
setIsArchiving(false);
162180
onCloseModal();
163181
};
164182

@@ -171,10 +189,14 @@ const Projects = function(props) {
171189
onCloseModal();
172190
};
173191

174-
const generateProjectList = (categorySelectedForSort, showStatus) => {
192+
const generateProjectList = (categorySelectedForSort, showStatus, isShowingArchived) => {
193+
console.log('generateProjectList called, isShowingArchived:', isShowingArchived);
194+
console.log('total projects:', allReduxProjects.length);
195+
console.log('archived projects:', allReduxProjects.filter(p => p.isArchived).length);
196+
console.log('non-archived projects:', allReduxProjects.filter(p => !p.isArchived).length);
175197
const activeMemberCounts = props.state.projectMembers?.activeMemberCounts || {};
176198
const filteredProjects = allReduxProjects
177-
.filter(project => !project.isArchived)
199+
.filter(project => isShowingArchived ? project.isArchived : !project.isArchived)
178200
.filter(project => {
179201
if (categorySelectedForSort && showStatus){
180202
return project.category === categorySelectedForSort && project.isActive === showStatus;
@@ -254,7 +276,8 @@ const Projects = function(props) {
254276
}, []);
255277

256278
useEffect(() => {
257-
generateProjectList(categorySelectedForSort, showStatus);
279+
console.log('useEffect triggered, showArchived:', showArchived);
280+
generateProjectList(categorySelectedForSort, showStatus, showArchived);
258281
if (status !== 200) {
259282
setModalData({
260283
showModal: true,
@@ -264,7 +287,7 @@ const Projects = function(props) {
264287
hasInactiveBtn: false,
265288
});
266289
}
267-
}, [categorySelectedForSort, showStatus, sorter, allReduxProjects, props.state.theme.darkMode, props.state.projectMembers?.activeMemberCounts]);
290+
}, [categorySelectedForSort, showStatus, sorter, allReduxProjects, props.state.theme.darkMode, props.state.projectMembers?.activeMemberCounts, showArchived]);
268291

269292
useEffect(() => {
270293
const fetchProjects = async () => {
@@ -343,8 +366,13 @@ const Projects = function(props) {
343366

344367
{canPostProject ? <AddProject hasPermission={hasPermission} /> : null}
345368
</div>
346-
<div className="d-flex" style={{ gap: '10px' }}>
347-
<SearchProjectByPerson onSearch={handleSearchName} searchMode={searchMode} />
369+
<div className="d-flex mb-3" style={{ gap: '10px' }}>
370+
<SearchProjectByPerson
371+
onSearch={handleSearchName}
372+
searchMode={searchMode}
373+
handleFetchArchivedProjects={handleFetchArchivedProjects}
374+
showArchived={showArchived}
375+
/>
348376
<div className="input-group" style={{ maxWidth: '260px', maxHeight: '38px' }}>
349377
<div className="input-group-prepend">
350378
<span
@@ -363,6 +391,16 @@ const Projects = function(props) {
363391
<option value="project">Project Name</option>
364392
</select>
365393
</div>
394+
<button
395+
type="button"
396+
onClick={handleFetchArchivedProjects}
397+
style={{ whiteSpace: 'nowrap', height: '38px', flexShrink: 0 }}
398+
className={`btn px-3 ${
399+
showArchived ? 'btn-warning' : darkMode ? 'btn-outline-light' : 'btn-outline-secondary'
400+
}`}
401+
>
402+
{showArchived ? 'Hide Archived' : 'Show Archived'}
403+
</button>
366404
</div>
367405
<div>
368406
<table className="table table-bordered table-responsive-sm">
@@ -391,7 +429,10 @@ const Projects = function(props) {
391429
modalMessage={modalData.modalMessage}
392430
modalTitle={modalData.modalTitle}
393431
darkMode={darkMode}
394-
confirmButtonText={isArchiving ? 'Archiving...' : 'Confirm'}
432+
confirmButtonText={isArchiving
433+
? (projectTarget.isArchived ? 'Unarchiving...' : 'Archiving...')
434+
: (projectTarget.isArchived ? 'Unarchive' : 'Confirm')
435+
}
395436
isConfirmDisabled={isArchiving}
396437
setInactiveButton={isChangingStatus ? 'Setting Inactive' : 'Yes, hide it all'}
397438
isSetInactiveDisabled={isChangingStatus}
@@ -410,6 +451,7 @@ const mapStateToProps = state => {
410451
Projects.propTypes = {
411452
clearError: PropTypes.func.isRequired,
412453
fetchAllProjects: PropTypes.func.isRequired,
454+
fetchAllArchivedProjects: PropTypes.func.isRequired,
413455
fetchProjectsWithActiveUsers: PropTypes.func.isRequired,
414456
getProjectsByUsersName: PropTypes.func.isRequired,
415457
hasPermission: PropTypes.func.isRequired,
@@ -436,6 +478,7 @@ Projects.propTypes = {
436478

437479
export default connect(mapStateToProps, {
438480
fetchAllProjects,
481+
fetchAllArchivedProjects,
439482
modifyProject,
440483
clearError,
441484
getPopupById,

src/components/SearchProjectByPerson/SearchProjectByPerson.jsx

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -50,24 +50,6 @@ export default function SearchProjectByPerson({
5050
value={inputValue}
5151
onChange={handleInputChange} // Trigger input change
5252
/>
53-
<div>
54-
{/* <button type="submit" className="archived-button" onClick={handleFetchArchivedProjects}>
55-
{showArchived ? 'Hide Archived' : 'Show Archived'}
56-
</button> */}
57-
<button
58-
type="button"
59-
onClick={handleFetchArchivedProjects}
60-
className={`btn ${
61-
showArchived
62-
? 'btn-warning'
63-
: darkMode
64-
? 'btn-outline-light'
65-
: 'btn-outline-secondary'
66-
}`}
67-
>
68-
{showArchived ? 'Hide Archived' : 'Show Archived'}
69-
</button>
70-
</div>
7153
</form>
7254

7355
{showSuggestions && suggestions?.length > 0 && (

src/languages/en/messages.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export const CONFIRM_DELETION = 'Confirm Deletion';
22
export const CONFIRM_ARCHIVE = 'Confirm Archive';
3-
export const CONFIRM_UNARCHIVE = 'Confirm UnArchive';
3+
export const CONFIRM_UNARCHIVE = 'Confirm Unarchive';
44
export const DELETE = 'delete';
55
export const ARE_YOU_SURE_YOU_WANT_TO = 'Are you sure you want to ';
66
export const THIS_PROJECT_NAME_IS_ALREADY_TAKEN = 'This project name is already taken';

src/languages/en/ui.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export const LESSON = 'Lesson';
2222
export const DASHBOARD = 'Dashboard';
2323
export const DELETE = 'Delete';
2424
export const ARCHIVE = 'Archive';
25+
export const UNARCHIVE = "Unarchive";
2526
export const LOGO = 'Time Tracking Tool';
2627
export const LOGOUT = 'Logout';
2728
export const MEMBERS = 'Members';

0 commit comments

Comments
 (0)