@@ -4,7 +4,7 @@ import { useState, useEffect } from 'react';
44import PropTypes from 'prop-types' ;
55import { connect , useSelector } from 'react-redux' ;
66import SearchProjectByPerson from '~/components/SearchProjectByPerson/SearchProjectByPerson' ;
7- import { fetchAllProjects , modifyProject , clearError } from '../../actions/projects' ;
7+ import { fetchAllProjects , fetchAllArchivedProjects , modifyProject , clearError } from '../../actions/projects' ;
88import { fetchProjectsWithActiveUsers } from '../../actions/projectMembers' ;
99import { getProjectsByUsersName } from '../../actions/userProfile' ;
1010import { 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 => {
410451Projects . 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
437479export default connect ( mapStateToProps , {
438480 fetchAllProjects,
481+ fetchAllArchivedProjects,
439482 modifyProject,
440483 clearError,
441484 getPopupById,
0 commit comments