Fix: pass the right user id when impersonating a user to chorefilter
implement experimental offline mode; add toggle in StorageSettings and update chore filters
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import { useState } from 'react'
|
||||
import { networkManager } from '../hooks/NetworkManager'
|
||||
import { FEATURES, isFeatureEnabled } from '../utils/FeatureToggle'
|
||||
import {
|
||||
CreateChore,
|
||||
GetChoreByID,
|
||||
@@ -17,6 +18,11 @@ export const useChores = includeArchive => {
|
||||
queryFn: async () => {
|
||||
const onlineChores = await GetChoresNew(includeArchive)
|
||||
|
||||
// Only handle offline tasks if experimental offline mode is enabled
|
||||
if (!isFeatureEnabled(FEATURES.OFFLINE_MODE)) {
|
||||
return onlineChores
|
||||
}
|
||||
|
||||
const offlineTasks = (await localStore.getFromCache('offlineTasks')) || []
|
||||
// go throught each and if there is two chores with same id in offline and online, prefer the offline one:
|
||||
var finalChores = []
|
||||
@@ -58,7 +64,7 @@ export const useCreateChore = () => {
|
||||
return useMutation({
|
||||
mutationFn: CreateChore,
|
||||
onMutate: async newTask => {
|
||||
if (!networkManager.isOnline) {
|
||||
if (!networkManager.isOnline && isFeatureEnabled(FEATURES.OFFLINE_MODE)) {
|
||||
const tempId = crypto.randomUUID() // Generate temp ID
|
||||
const offlineTasks =
|
||||
(await localStore.getFromCache('offlineTasks')) || []
|
||||
@@ -95,7 +101,7 @@ export const useUpdateChore = () => {
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async updatedChore => {
|
||||
if (!networkManager.isOnline) {
|
||||
if (!networkManager.isOnline && isFeatureEnabled(FEATURES.OFFLINE_MODE)) {
|
||||
updatedChore['updatedAt'] = new Date().toISOString()
|
||||
if (!updatedChore['nextDueDate']) {
|
||||
updatedChore['nextDueDate'] = updatedChore['dueDate']
|
||||
@@ -150,7 +156,7 @@ export const useUpdateChore = () => {
|
||||
queryClient.invalidateQueries(['chores'])
|
||||
},
|
||||
onMutate: async updatedChore => {
|
||||
if (!networkManager.isOnline) {
|
||||
if (!networkManager.isOnline && isFeatureEnabled(FEATURES.OFFLINE_MODE)) {
|
||||
// Handle offline case here if needed
|
||||
return
|
||||
}
|
||||
@@ -192,6 +198,11 @@ export const useChoreDetails = choreId => {
|
||||
console.error('Error fetching chore detail:', error)
|
||||
}
|
||||
|
||||
// Only check offline tasks if experimental offline mode is enabled
|
||||
if (!isFeatureEnabled(FEATURES.OFFLINE_MODE)) {
|
||||
return onlineChore
|
||||
}
|
||||
|
||||
const offlineTasks = (await localStore.getFromCache('offlineTasks')) || []
|
||||
const offline = offlineTasks.find(task => {
|
||||
// Match by tempId or id if it was created offline
|
||||
@@ -224,6 +235,11 @@ export const useChore = choreId => {
|
||||
console.error('Error fetching chore detail:', error)
|
||||
}
|
||||
|
||||
// Only check offline tasks if experimental offline mode is enabled
|
||||
if (!isFeatureEnabled(FEATURES.OFFLINE_MODE)) {
|
||||
return onlineChore
|
||||
}
|
||||
|
||||
const offlineTasks = (await localStore.getFromCache('offlineTasks')) || []
|
||||
const offline = offlineTasks.find(task => {
|
||||
return (
|
||||
|
||||
@@ -327,21 +327,21 @@ export const notInCompletionWindow = chore => {
|
||||
moment().add(chore.completionWindow, 'hours') < moment(chore.nextDueDate)
|
||||
)
|
||||
}
|
||||
export const ChoreFilters = userProfile => ({
|
||||
export const ChoreFilters = userId => ({
|
||||
anyone: () => true,
|
||||
assigned_to_me: chore => {
|
||||
return chore.assignedTo && chore.assignedTo === userProfile?.id
|
||||
return chore.assignedTo && chore.assignedTo === userId
|
||||
},
|
||||
assigned_to_others: chore => {
|
||||
return chore.assignedTo && chore.assignedTo !== userProfile?.id
|
||||
return chore.assignedTo && chore.assignedTo !== userId
|
||||
},
|
||||
assigned_to_me_tasks: chore => {
|
||||
return (
|
||||
chore.assignees &&
|
||||
chore.assignees.some(assignee => assignee.userId === userProfile?.id)
|
||||
chore.assignees.some(assignee => assignee.userId === userId)
|
||||
)
|
||||
},
|
||||
created_by_me: chore => {
|
||||
return chore.createdBy && chore.createdBy === userProfile?.id
|
||||
return chore.createdBy && chore.createdBy === userId
|
||||
},
|
||||
})
|
||||
|
||||
@@ -146,7 +146,9 @@ const MyChores = () => {
|
||||
const sections = ChoresGrouper(
|
||||
selectedChoreSection,
|
||||
sortedChores,
|
||||
ChoreFilters(userProfile)[selectedChoreFilter],
|
||||
ChoreFilters(impersonatedUser?.userId || userProfile?.id)[
|
||||
selectedChoreFilter
|
||||
],
|
||||
)
|
||||
setChoreSections(sections)
|
||||
if (localStorage.getItem('openChoreSections') === null) {
|
||||
@@ -537,7 +539,11 @@ const MyChores = () => {
|
||||
)
|
||||
}
|
||||
|
||||
return choresToFilter.filter(ChoreFilters(userProfile)[selectedChoreFilter])
|
||||
return choresToFilter.filter(
|
||||
ChoreFilters(impersonatedUser?.userId || userProfile?.id)[
|
||||
selectedChoreFilter
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
// Helper function to get chores for a specific date
|
||||
@@ -567,7 +573,9 @@ const MyChores = () => {
|
||||
ChoresGrouper(
|
||||
selectedChoreSection,
|
||||
newChores,
|
||||
ChoreFilters(userProfile)[selectedChoreFilter],
|
||||
ChoreFilters(impersonatedUser?.userId || userProfile?.id)[
|
||||
selectedChoreFilter
|
||||
],
|
||||
),
|
||||
)
|
||||
setSearchFilter('All')
|
||||
@@ -641,7 +649,9 @@ const MyChores = () => {
|
||||
ChoresGrouper(
|
||||
selectedChoreSection,
|
||||
newChores,
|
||||
ChoreFilters(userProfile)[selectedChoreFilter],
|
||||
ChoreFilters(impersonatedUser?.userId || userProfile?.id)[
|
||||
selectedChoreFilter
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
@@ -715,7 +725,9 @@ const MyChores = () => {
|
||||
ChoresGrouper(
|
||||
selectedChoreSection,
|
||||
newChores,
|
||||
ChoreFilters(userProfile)[selectedChoreFilter],
|
||||
ChoreFilters(impersonatedUser?.userId || userProfile?.id)[
|
||||
selectedChoreFilter
|
||||
],
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -982,7 +994,9 @@ const MyChores = () => {
|
||||
ChoresGrouper(
|
||||
selectedChoreSection,
|
||||
newChores,
|
||||
ChoreFilters(userProfile)[selectedChoreFilter],
|
||||
ChoreFilters(impersonatedUser?.userId || userProfile?.id)[
|
||||
selectedChoreFilter
|
||||
],
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -1155,7 +1169,9 @@ const MyChores = () => {
|
||||
const section = ChoresGrouper(
|
||||
selectedChoreSection,
|
||||
chores,
|
||||
ChoreFilters(impersonatedUser | userProfile)[filter],
|
||||
ChoreFilters(impersonatedUser?.userId || userProfile?.id)[
|
||||
filter
|
||||
],
|
||||
)
|
||||
setChoreSections(section)
|
||||
setOpenChoreSectionsWithCache(
|
||||
@@ -1170,7 +1186,9 @@ const MyChores = () => {
|
||||
const section = ChoresGrouper(
|
||||
selected.value,
|
||||
chores,
|
||||
ChoreFilters(userProfile)[selectedChoreFilter],
|
||||
ChoreFilters(impersonatedUser?.userId || userProfile?.id)[
|
||||
selectedChoreFilter
|
||||
],
|
||||
)
|
||||
setChoreSections(section)
|
||||
setSelectedChoreSectionWithCache(selected.value)
|
||||
|
||||
@@ -1,8 +1,20 @@
|
||||
import { Capacitor } from '@capacitor/core'
|
||||
import { Button, Card, Chip, LinearProgress, Typography } from '@mui/joy'
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
Chip,
|
||||
LinearProgress,
|
||||
Switch,
|
||||
Typography,
|
||||
} from '@mui/joy'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useUserProfile } from '../../queries/UserQueries'
|
||||
import {
|
||||
FEATURES,
|
||||
isFeatureEnabled,
|
||||
setFeatureEnabled,
|
||||
} from '../../utils/FeatureToggle'
|
||||
import { GetStorageUsage } from '../../utils/Fetcher'
|
||||
import { isPlusAccount } from '../../utils/Helpers'
|
||||
import ConfirmationModal from '../Modals/Inputs/ConfirmationModal'
|
||||
@@ -14,6 +26,9 @@ const StorageSettings = () => {
|
||||
const [usage, setUsage] = useState({ used: 0, total: 0 })
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [confirmModalConfig, setConfirmModalConfig] = useState({})
|
||||
const [offlineModeEnabled, setOfflineModeEnabledState] = useState(
|
||||
isFeatureEnabled(FEATURES.OFFLINE_MODE),
|
||||
)
|
||||
|
||||
const showConfirmation = (
|
||||
message,
|
||||
@@ -39,6 +54,11 @@ const StorageSettings = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const handleOfflineModeToggle = enabled => {
|
||||
setOfflineModeEnabledState(enabled)
|
||||
setFeatureEnabled(FEATURES.OFFLINE_MODE, enabled)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (isPlusAccount(userProfile)) {
|
||||
GetStorageUsage().then(resp => {
|
||||
@@ -106,6 +126,40 @@ const StorageSettings = () => {
|
||||
</>
|
||||
)}
|
||||
</Card>
|
||||
|
||||
<Card className='p-4' sx={{ maxWidth: 500, mb: 2 }}>
|
||||
<Typography level='title-md' sx={{ mb: 1 }}>
|
||||
Experimental Features
|
||||
<Chip variant='soft' color='warning' sx={{ ml: 1 }}>
|
||||
Coming Soon
|
||||
</Chip>
|
||||
</Typography>
|
||||
<div className='mb-2 flex items-center justify-between'>
|
||||
<div className='flex-1'>
|
||||
<Typography level='body-md' sx={{ mb: 0.5 }}>
|
||||
Enable Offline Mode
|
||||
</Typography>
|
||||
<Typography level='body-sm' color='neutral'>
|
||||
Allows the app to work offline by caching data locally. This is
|
||||
experimental and may cause some slowness. If you experience
|
||||
performance issues, we recommend turning this off.
|
||||
</Typography>
|
||||
</div>
|
||||
<Switch
|
||||
checked={offlineModeEnabled}
|
||||
disabled={true}
|
||||
onChange={event => handleOfflineModeToggle(event.target.checked)}
|
||||
sx={{ ml: 2 }}
|
||||
/>
|
||||
</div>
|
||||
{offlineModeEnabled && (
|
||||
<Typography level='body-xs' color='warning' sx={{ mt: 1 }}>
|
||||
⚠️ Offline mode is enabled. If you experience slowness, disable
|
||||
this setting.
|
||||
</Typography>
|
||||
)}
|
||||
</Card>
|
||||
|
||||
<Card className='p-4' sx={{ maxWidth: 500, mb: 2 }}>
|
||||
<Typography level='title-md' sx={{ mb: 1 }}>
|
||||
{Capacitor.isNativePlatform() ? 'App' : 'Browser'} Local Storage &
|
||||
|
||||
Reference in New Issue
Block a user