Fix Assignee Bug, Support loading Archive

This commit is contained in:
Mo Tarbin 2024-12-15 18:11:39 -05:00
commit f0e1ac00e2
5 changed files with 108 additions and 18 deletions

23
package-lock.json generated
View file

@ -1,12 +1,12 @@
{ {
"name": "donetick", "name": "donetick",
"version": "0.1.78", "version": "0.1.82",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "donetick", "name": "donetick",
"version": "0.1.78", "version": "0.1.82",
"dependencies": { "dependencies": {
"@emotion/react": "^11.11.3", "@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0", "@emotion/styled": "^11.11.0",
@ -17,6 +17,7 @@
"@tanstack/react-query": "^5.17.0", "@tanstack/react-query": "^5.17.0",
"aos": "^2.3.4", "aos": "^2.3.4",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"esm": "^3.2.25",
"fuse.js": "^7.0.0", "fuse.js": "^7.0.0",
"js-cookie": "^3.0.5", "js-cookie": "^3.0.5",
"moment": "^2.30.1", "moment": "^2.30.1",
@ -4320,9 +4321,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001635", "version": "1.0.30001688",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001635.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001688.tgz",
"integrity": "sha512-34NOwyGFZxFoIOFNoLPP08eHzaCN+3wJFKx4Vph0XpidU1tRxB0p3Q2etIbOj0W8TYeuXkYsMCcyjV1+phBzxQ==", "integrity": "sha512-Nmqpru91cuABu/DTCXbM2NSRHzM2uVHfPnhJ/1zEAJx/ILBRVmz3pzH4N7DZqbdG0gWClsCC05Oj0mJ/1AWMbA==",
"funding": [ "funding": [
{ {
"type": "opencollective", "type": "opencollective",
@ -4336,7 +4337,8 @@
"type": "github", "type": "github",
"url": "https://github.com/sponsors/ai" "url": "https://github.com/sponsors/ai"
} }
] ],
"license": "CC-BY-4.0"
}, },
"node_modules/chalk": { "node_modules/chalk": {
"version": "4.1.2", "version": "4.1.2",
@ -5256,6 +5258,15 @@
"url": "https://opencollective.com/eslint" "url": "https://opencollective.com/eslint"
} }
}, },
"node_modules/esm": {
"version": "3.2.25",
"resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
"integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/espree": { "node_modules/espree": {
"version": "9.6.1", "version": "9.6.1",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",

View file

@ -1,7 +1,7 @@
{ {
"name": "donetick", "name": "donetick",
"private": true, "private": true,
"version": "0.1.82", "version": "0.1.83",
"type": "module", "type": "module",
"lint-staged": { "lint-staged": {
"*.{js,jsx,ts,tsx}": [ "*.{js,jsx,ts,tsx}": [
@ -29,6 +29,7 @@
"@tanstack/react-query": "^5.17.0", "@tanstack/react-query": "^5.17.0",
"aos": "^2.3.4", "aos": "^2.3.4",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"esm": "^3.2.25",
"fuse.js": "^7.0.0", "fuse.js": "^7.0.0",
"js-cookie": "^3.0.5", "js-cookie": "^3.0.5",
"moment": "^2.30.1", "moment": "^2.30.1",

View file

@ -59,6 +59,12 @@ const GetChores = () => {
headers: HEADERS(), headers: HEADERS(),
}) })
} }
const GetArchivedChores = () => {
return Fetch(`${API_URL}/chores/archived`, {
method: 'GET',
headers: HEADERS(),
})
}
const GetChoreByID = id => { const GetChoreByID = id => {
return Fetch(`${API_URL}/chores/${id}`, { return Fetch(`${API_URL}/chores/${id}`, {
@ -356,6 +362,7 @@ export {
DeleteThing, DeleteThing,
GetAllCircleMembers, GetAllCircleMembers,
GetAllUsers, GetAllUsers,
GetArchivedChores,
GetChoreByID, GetChoreByID,
GetChoreDetailById, GetChoreDetailById,
GetChoreHistory, GetChoreHistory,

View file

@ -169,6 +169,9 @@ const ChoreEdit = () => {
return true return true
} }
const handleDueDateChange = e => {
setDueDate(e.target.value)
}
const HandleSaveChore = () => { const HandleSaveChore = () => {
setAttemptToSave(true) setAttemptToSave(true)
if (!HandleValidateChore()) { if (!HandleValidateChore()) {
@ -386,12 +389,15 @@ const ChoreEdit = () => {
<ListItem key={item.id}> <ListItem key={item.id}>
<Checkbox <Checkbox
// disabled={index === 0} // disabled={index === 0}
checked={assignees.find(a => a.userId == item.id) != null} checked={assignees.find(a => a.userId == item.userId) != null}
onClick={() => { onClick={() => {
if (assignees.find(a => a.userId == item.id)) { if (assignees.some(a => a.userId === item.userId)) {
setAssignees(assignees.filter(i => i.userId !== item.id)) const newAssignees = assignees.filter(
a => a.userId !== item.userId,
)
setAssignees(newAssignees)
} else { } else {
setAssignees([...assignees, { userId: item.id }]) setAssignees([...assignees, { userId: item.userId }])
} }
}} }}
overlay overlay
@ -431,10 +437,10 @@ const ChoreEdit = () => {
?.filter(p => assignees.find(a => a.userId == p.userId)) ?.filter(p => assignees.find(a => a.userId == p.userId))
.map((item, index) => ( .map((item, index) => (
<Option <Option
value={item.id} value={item.userId}
key={item.displayName} key={item.displayName}
onClick={() => { onClick={() => {
setAssignedTo(item.id) setAssignedTo(item.userId)
}} }}
> >
{item.displayName} {item.displayName}
@ -552,9 +558,7 @@ const ChoreEdit = () => {
<Input <Input
type='datetime-local' type='datetime-local'
value={dueDate} value={dueDate}
onChange={e => { onChange={handleDueDateChange}
setDueDate(e.target.value)
}}
/> />
<FormHelperText>{errors.dueDate}</FormHelperText> <FormHelperText>{errors.dueDate}</FormHelperText>
</FormControl> </FormControl>

View file

@ -6,6 +6,7 @@ import {
FilterAlt, FilterAlt,
PriorityHigh, PriorityHigh,
Style, Style,
Unarchive,
} from '@mui/icons-material' } from '@mui/icons-material'
import { import {
Accordion, Accordion,
@ -29,7 +30,11 @@ import { useContext, useEffect, useRef, useState } from 'react'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
import { UserContext } from '../../contexts/UserContext' import { UserContext } from '../../contexts/UserContext'
import { useChores } from '../../queries/ChoreQueries' import { useChores } from '../../queries/ChoreQueries'
import { GetAllUsers, GetUserProfile } from '../../utils/Fetcher' import {
GetAllUsers,
GetArchivedChores,
GetUserProfile,
} from '../../utils/Fetcher'
import Priorities from '../../utils/Priorities' import Priorities from '../../utils/Priorities'
import LoadingComponent from '../components/Loading' import LoadingComponent from '../components/Loading'
import { useLabels } from '../Labels/LabelQueries' import { useLabels } from '../Labels/LabelQueries'
@ -41,6 +46,7 @@ const MyChores = () => {
const [isSnackbarOpen, setIsSnackbarOpen] = useState(false) const [isSnackbarOpen, setIsSnackbarOpen] = useState(false)
const [snackBarMessage, setSnackBarMessage] = useState(null) const [snackBarMessage, setSnackBarMessage] = useState(null)
const [chores, setChores] = useState([]) const [chores, setChores] = useState([])
const [archivedChores, setArchivedChores] = useState(null)
const [filteredChores, setFilteredChores] = useState([]) const [filteredChores, setFilteredChores] = useState([])
const [selectedFilter, setSelectedFilter] = useState('All') const [selectedFilter, setSelectedFilter] = useState('All')
const [choreSections, setChoreSections] = useState([]) const [choreSections, setChoreSections] = useState([])
@ -226,6 +232,7 @@ const MyChores = () => {
document.removeEventListener('mousedown', handleMenuOutsideClick) document.removeEventListener('mousedown', handleMenuOutsideClick)
} }
}, [anchorEl]) }, [anchorEl])
const handleMenuOutsideClick = event => { const handleMenuOutsideClick = event => {
if ( if (
anchorEl && anchorEl &&
@ -280,6 +287,7 @@ const MyChores = () => {
}) })
setChores(newChores) setChores(newChores)
setFilteredChores(newFilteredChores) setFilteredChores(newFilteredChores)
setChoreSections(sectionSorter('due_date', newChores))
switch (event) { switch (event) {
case 'completed': case 'completed':
setSnackBarMessage('Completed') setSnackBarMessage('Completed')
@ -303,6 +311,7 @@ const MyChores = () => {
) )
setChores(newChores) setChores(newChores)
setFilteredChores(newFilteredChores) setFilteredChores(newFilteredChores)
setChoreSections(sectionSorter('due_date', newChores))
} }
const searchOptions = { const searchOptions = {
@ -626,6 +635,65 @@ const MyChores = () => {
})} })}
</AccordionGroup> </AccordionGroup>
)} )}
<Box
sx={{
// center the button
justifyContent: 'center',
mt: 2,
}}
>
{archivedChores === null && (
<Box sx={{ display: 'flex', justifyContent: 'center' }}>
<Button
sx={{}}
onClick={() => {
GetArchivedChores()
.then(response => response.json())
.then(data => {
setArchivedChores(data.res)
})
}}
variant='outlined'
color='neutral'
startDecorator={<Unarchive />}
>
Show Archived
</Button>
</Box>
)}
{archivedChores !== null && (
<>
<Divider orientation='horizontal'>
<Chip
variant='soft'
color='danger'
size='md'
startDecorator={
<>
<Chip color='danger' size='sm' variant='plain'>
{archivedChores?.length}
</Chip>
</>
}
>
Archived
</Chip>
</Divider>
{archivedChores?.map(chore => (
<ChoreCard
key={chore.id}
chore={chore}
onChoreUpdate={handleChoreUpdated}
onChoreRemove={handleChoreDeleted}
performers={performers}
userLabels={userLabels}
onChipClick={handleLabelFiltering}
/>
))}
</>
)}
</Box>
<Box <Box
// variant='outlined' // variant='outlined'
sx={{ sx={{
@ -647,7 +715,6 @@ const MyChores = () => {
width: 50, width: 50,
height: 50, height: 50,
}} }}
// startDecorator={<Add />}
onClick={() => { onClick={() => {
Navigate(`/chores/create`) Navigate(`/chores/create`)
}} }}