diff --git a/packages/web/lib/networking/mutations/bulkActionMutation.ts b/packages/web/lib/networking/mutations/bulkActionMutation.ts new file mode 100644 index 000000000..935e5a8e6 --- /dev/null +++ b/packages/web/lib/networking/mutations/bulkActionMutation.ts @@ -0,0 +1,43 @@ +import { gql } from 'graphql-request' +import { gqlFetcher } from '../networkHelpers' + +export enum BulkAction { + ARCHIVE = 'ARCHIVE', + DELETE = 'DELETE', +} + +type BulkActionResponseData = { + success: boolean +} + +type BulkActionResponse = { + errorCodes?: string[] + bulkAction?: BulkActionResponseData +} + +export async function bulkActionMutation(action: BulkAction): Promise { + const mutation = gql` + mutation { + bulkAction (action: ${action}) { + ... on BulkActionSuccess { + success + } + ... on BulkActionError { + errorCodes + } + } + } + ` + + console.log('bulkActionbulkActionMutation', mutation) + + try { + const response = await gqlFetcher(mutation, { action }) + console.log('response', response) + const data = response as BulkActionResponse | undefined + return data?.bulkAction?.success ?? false + } catch (error) { + console.error(error) + return false + } +} diff --git a/packages/web/pages/tools/bulk.tsx b/packages/web/pages/tools/bulk.tsx new file mode 100644 index 000000000..9b4031937 --- /dev/null +++ b/packages/web/pages/tools/bulk.tsx @@ -0,0 +1,172 @@ +import { useCallback, useState } from 'react' +import { applyStoredTheme } from '../../lib/themeUpdater' + +import { Box, 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() + const [errorMessage, setErrorMessage] = useState() + const [runningState, setRunningState] = useState('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) + if (!success) { + throw 'Success not returned' + } + showSuccessToast('Bulk action is being performed.') + setRunningState('completed') + } catch (err) { + showErrorToast('Error performing bulk action.') + } + })() + }, [action]) + + return ( + + + + Perform a Bulk Action + + + Use this tool to perform a bulk operation on all the items in your + library.

+ More info +
+ + Note: This operation can not be undone. + + + {runningState == 'completed' ? ( + + 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. + + ) : ( + <> + + + + + + + )} + + {runningState == 'confirming' && ( + setRunningState('none')} + /> + )} + {runningState == 'completed' && ( + + + + )} + + {errorMessage && ( + {errorMessage} + )} + +
+
+ ) +}