Send expected count with bulk actions

This commit is contained in:
Jackson Harper
2023-06-08 18:47:44 +08:00
parent 85d37337a7
commit d92e5f3fd1
3 changed files with 19 additions and 177 deletions

View File

@ -627,8 +627,13 @@ export function HomeFeedContainer(): JSX.Element {
multiSelectMode === 'search'
? queryInputs.searchQuery || 'in:inbox'
: `includes:${checkedItems.join(',')}`
const expectedCount =
multiSelectMode === 'search'
? itemsPages?.[0].search.pageInfo.totalCount || 0
: checkedItems.length
try {
const res = await bulkActionMutation(action, query)
const res = await bulkActionMutation(action, query, expectedCount)
if (res) {
switch (action) {
case BulkAction.ARCHIVE:
@ -648,7 +653,7 @@ export function HomeFeedContainer(): JSX.Element {
})()
setMultiSelectMode('off')
},
[multiSelectMode, checkedItems]
[itemsPages, multiSelectMode, checkedItems]
)
return (

View File

@ -17,10 +17,15 @@ type BulkActionResponse = {
export async function bulkActionMutation(
action: BulkAction,
query: string
query: string,
expectedCount: number
): Promise<boolean> {
const mutation = gql`
mutation BulkAction($action: BulkActionType!, $query: String!) {
mutation BulkAction(
$action: BulkActionType!
$query: String!
$expectedCount: Int
) {
bulkAction(query: $query, action: $action) {
... on BulkActionSuccess {
success
@ -35,7 +40,11 @@ export async function bulkActionMutation(
console.log('bulkActionbulkActionMutation', mutation)
try {
const response = await gqlFetcher(mutation, { action, query })
const response = await gqlFetcher(mutation, {
action,
query,
expectedCount,
})
console.log('response', response)
const data = response as BulkActionResponse | undefined
return data?.bulkAction?.success ?? false

View File

@ -1,172 +0,0 @@
import { useCallback, useState } from 'react'
import { applyStoredTheme } from '../../lib/themeUpdater'
import { VStack } from '../../components/elements/LayoutPrimitives'
import { StyledText } from '../../components/elements/StyledText'
import { ProfileLayout } from '../../components/templates/ProfileLayout'
import {
BulkAction,
bulkActionMutation,
} from '../../lib/networking/mutations/bulkActionMutation'
import { Button } from '../../components/elements/Button'
import { theme } from '../../components/tokens/stitches.config'
import { ConfirmationModal } from '../../components/patterns/ConfirmationModal'
import { showErrorToast, showSuccessToast } from '../../lib/toastHelpers'
import { useRouter } from 'next/router'
type RunningState = 'none' | 'confirming' | 'running' | 'completed'
export default function BulkPerformer(): JSX.Element {
const router = useRouter()
applyStoredTheme(false)
const [action, setAction] = useState<BulkAction | undefined>()
const [errorMessage, setErrorMessage] = useState<string | undefined>()
const [runningState, setRunningState] = useState<RunningState>('none')
const performAction = useCallback(() => {
;(async () => {
console.log('performing action: ', action)
if (!action) {
showErrorToast('Unable to run action, no action set.')
return
}
try {
const success = await bulkActionMutation(action, 'in:all')
if (!success) {
throw 'Success not returned'
}
showSuccessToast('Bulk action is being performed.')
setRunningState('completed')
} catch (err) {
showErrorToast('Error performing bulk action.')
}
})()
}, [action])
return (
<ProfileLayout logoDestination="/home">
<VStack
alignment="start"
css={{
padding: '16px',
background: 'white',
minWidth: '340px',
width: '70vw',
maxWidth: '576px',
borderRadius: '8px',
border: '1px solid #3D3D3D',
boxShadow: '#B1B1B1 9px 9px 9px -9px',
}}
>
<StyledText
style="modalHeadline"
css={{
color: theme.colors.omnivoreGray.toString(),
}}
>
Perform a Bulk Action
</StyledText>
<StyledText
style="caption"
css={{ pt: '10px', color: theme.colors.omnivoreGray.toString() }}
>
Use this tool to perform a bulk operation on all the items in your
library.<br></br>
<a href="https://docs.omnivore.app/using/">More info</a>
</StyledText>
<StyledText
style="caption"
css={{ pt: '0px', color: theme.colors.omnivoreGray.toString() }}
>
<b>Note:</b> This operation can not be undone.
</StyledText>
<VStack css={{ pt: '36px', width: '100%' }}>
{runningState == 'completed' ? (
<StyledText
style="caption"
css={{
pt: '10px',
pb: '20px',
color: theme.colors.omnivoreGray.toString(),
}}
>
Your bulk action has started. Please note that it can take some
time for these actions to complete. During this time, we recommend
not modifying your library as new items could be updated by the
action.
</StyledText>
) : (
<>
<VStack css={{ width: '100%', gap: '15px' }}>
<select
disabled={runningState == 'running'}
onChange={(event) => {
const updatedAction: BulkAction =
BulkAction[
event.currentTarget.value as keyof typeof BulkAction
]
setAction(updatedAction)
}}
style={{
padding: '8px',
height: '38px',
borderRadius: '6px',
minWidth: '196px',
color: theme.colors.omnivoreGray.toString(),
}}
>
<option value="none">Choose bulk action</option>
<option value="ARCHIVE">Archive All</option>
{router.isReady && router.query['allow_delete'] && (
<option value="DELETE">Delete All</option>
)}
</select>
<Button
onClick={(e) => {
if (!action) {
alert('No action selected')
return
}
setRunningState('confirming')
}}
style="ctaDarkYellow"
>
Perform Action
</Button>
</VStack>
</>
)}
{runningState == 'confirming' && (
<ConfirmationModal
message={`Are you sure you want to ${action} your entire library? This operation can not be undone.`}
onAccept={performAction}
onOpenChange={() => setRunningState('none')}
/>
)}
{runningState == 'completed' && (
<VStack css={{ width: '100%' }} alignment="center">
<Button
onClick={(e) => {
window.location.href = '/home'
e.preventDefault()
}}
style="ctaDarkYellow"
>
Return to Library
</Button>
</VStack>
)}
{errorMessage && (
<StyledText style="error">{errorMessage}</StyledText>
)}
</VStack>
</VStack>
</ProfileLayout>
)
}