|
1 | 1 | import { css } from '@emotion/react'; |
| 2 | +import { logger } from '@jetstream/shared/client-logger'; |
2 | 3 | import { formatNumber } from '@jetstream/shared/ui-utils'; |
3 | 4 | import { pluralizeIfMultiple } from '@jetstream/shared/utils'; |
4 | 5 | import { FieldMapping, LoadSavedMappingItem } from '@jetstream/types'; |
5 | | -import { Grid, Icon, Input, Popover, PopoverRef, ScopedNotification } from '@jetstream/ui'; |
6 | | -import { dexieDb, getHashedRecordKey } from '@jetstream/ui/db'; |
| 6 | +import { fireToast, Grid, Icon, Input, Popover, PopoverRef, ScopedNotification } from '@jetstream/ui'; |
| 7 | +import { dexieDb, getHashedRecordKey, withReopenOnDatabaseClosed } from '@jetstream/ui/db'; |
7 | 8 | import { formatISO } from 'date-fns/formatISO'; |
8 | 9 | import omit from 'lodash/omit'; |
9 | 10 | import { FunctionComponent, useEffect, useMemo, useRef, useState } from 'react'; |
@@ -55,14 +56,24 @@ export const SaveMappingPopover: FunctionComponent<SaveMappingPopoverProps> = ({ |
55 | 56 | }, [fieldMapping, sobject]); |
56 | 57 |
|
57 | 58 | async function handleSave() { |
58 | | - const newMapping: LoadSavedMappingItem = { ...currentSavedMapping, name: mappingName }; |
59 | | - newMapping.createdAt = new Date(); |
60 | | - newMapping.key = `lsm_${sobject}:${newMapping.csvFields.length}:${formatISO(newMapping.createdAt).toLowerCase()}`; |
61 | | - newMapping.hashedKey = await getHashedRecordKey(newMapping.key); |
62 | | - dexieDb.load_saved_mapping.put(newMapping); |
63 | | - saveSetMappingName(''); |
64 | | - setCurrentSavedMapping(getDefaultItem(sobject)); |
65 | | - popoverRef.current?.close(); |
| 59 | + try { |
| 60 | + const newMapping: LoadSavedMappingItem = { ...currentSavedMapping, name: mappingName }; |
| 61 | + newMapping.createdAt = new Date(); |
| 62 | + newMapping.key = `lsm_${sobject}:${newMapping.csvFields.length}:${formatISO(newMapping.createdAt).toLowerCase()}`; |
| 63 | + newMapping.hashedKey = await getHashedRecordKey(newMapping.key); |
| 64 | + await withReopenOnDatabaseClosed(() => dexieDb.load_saved_mapping.put(newMapping)); |
| 65 | + saveSetMappingName(''); |
| 66 | + setCurrentSavedMapping(getDefaultItem(sobject)); |
| 67 | + popoverRef.current?.close(); |
| 68 | + } catch (ex) { |
| 69 | + // The awaited Dexie write can reject; handleSave is called fire-and-forget from onSubmit, so catch |
| 70 | + // here to avoid an unhandled rejection and give the user feedback (popover stays open to retry). |
| 71 | + logger.warn('Failed to save field mapping', ex); |
| 72 | + fireToast({ |
| 73 | + type: 'error', |
| 74 | + message: 'Uh oh, there was a problem saving the field mapping. Please try again.', |
| 75 | + }); |
| 76 | + } |
66 | 77 | } |
67 | 78 |
|
68 | 79 | return ( |
|
0 commit comments