fix: Sheet import error when user doesn't have correct permissions for the sheet (#865)

* refactor: better throw error message

* fix: await verify so wa catch the potential error

* fix: catch and display error about varification

* fix: don't block the Authenticate with a spinner

* center spinner

* propper boolean
This commit is contained in:
Alex Christoffer Rasmussen
2024-04-03 14:18:04 +02:00
committed by GitHub
parent 01c2ef4c4d
commit 8b8b3347fb
3 changed files with 22 additions and 15 deletions
@@ -1,9 +1,10 @@
import { ChangeEvent, useEffect, useState } from 'react'; import { ChangeEvent, useEffect, useState } from 'react';
import { Button, Input } from '@chakra-ui/react'; import { Button, Input, Spinner } from '@chakra-ui/react';
import { IoCheckmark } from '@react-icons/all-files/io5/IoCheckmark'; import { IoCheckmark } from '@react-icons/all-files/io5/IoCheckmark';
import { IoShieldCheckmarkOutline } from '@react-icons/all-files/io5/IoShieldCheckmarkOutline'; import { IoShieldCheckmarkOutline } from '@react-icons/all-files/io5/IoShieldCheckmarkOutline';
import { getWorksheetNames } from '../../../../common/api/sheets'; import { getWorksheetNames } from '../../../../common/api/sheets';
import { maybeAxiosError } from '../../../../common/api/utils';
import CopyTag from '../../../../common/components/copy-tag/CopyTag'; import CopyTag from '../../../../common/components/copy-tag/CopyTag';
import { openLink } from '../../../../common/utils/linkUtils'; import { openLink } from '../../../../common/utils/linkUtils';
import * as Panel from '../PanelUtils'; import * as Panel from '../PanelUtils';
@@ -29,7 +30,7 @@ export default function GSheetSetup(props: GSheetSetupProps) {
const sheetId = useSheetStore((state) => state.sheetId); const sheetId = useSheetStore((state) => state.sheetId);
const setSheetId = useSheetStore((state) => state.setSheetId); const setSheetId = useSheetStore((state) => state.setSheetId);
const setWorksheets = useSheetStore((state) => state.setWorksheets); const setWorksheets = useSheetStore((state) => state.setWorksheets);
const patchStepData = useSheetStore((state) => state.patchStepData);
const authenticationStatus = useSheetStore((state) => state.authenticationStatus); const authenticationStatus = useSheetStore((state) => state.authenticationStatus);
const setAuthenticationStatus = useSheetStore((state) => state.setAuthenticationStatus); const setAuthenticationStatus = useSheetStore((state) => state.setAuthenticationStatus);
@@ -91,8 +92,13 @@ export default function GSheetSetup(props: GSheetSetupProps) {
setAuthenticationStatus(result.authenticated); setAuthenticationStatus(result.authenticated);
if (result.authenticated !== 'pending') { if (result.authenticated !== 'pending') {
if (result.authenticated == 'authenticated') { if (result.authenticated == 'authenticated') {
const names = await getWorksheetNames(result.sheetId); try {
setWorksheets(names); const names = await getWorksheetNames(result.sheetId);
setWorksheets(names);
} catch (error) {
const message = maybeAxiosError(error);
patchStepData({ worksheet: { available: false, error: message } });
}
} }
setLoading(''); setLoading('');
return; return;
@@ -184,6 +190,7 @@ export default function GSheetSetup(props: GSheetSetupProps) {
) : ( ) : (
<Panel.ListGroup> <Panel.ListGroup>
<div className={style.buttonRow}> <div className={style.buttonRow}>
{isAuthenticating && <Spinner />}
<CopyTag label='Google Auth Key' disabled={!canAuthenticate} size='sm'> <CopyTag label='Google Auth Key' disabled={!canAuthenticate} size='sm'>
{authKey ? authKey : 'Upload files to generate Auth Key'} {authKey ? authKey : 'Upload files to generate Auth Key'}
</CopyTag> </CopyTag>
@@ -192,8 +199,7 @@ export default function GSheetSetup(props: GSheetSetupProps) {
size='sm' size='sm'
leftIcon={<IoShieldCheckmarkOutline />} leftIcon={<IoShieldCheckmarkOutline />}
onClick={handleAuthenticate} onClick={handleAuthenticate}
isDisabled={!canAuthenticate || isLoading} isDisabled={!canAuthenticate}
isLoading={loading === 'authenticate' || isAuthenticating}
> >
Authenticate Authenticate
</Button> </Button>
@@ -26,6 +26,7 @@
.buttonRow { .buttonRow {
display: flex; display: flex;
gap: 1rem; gap: 1rem;
align-items: center;
justify-content: end; justify-content: end;
} }
@@ -183,7 +183,7 @@ function verifyConnection(
pollInterval = null; pollInterval = null;
} }
postAction(); await postAction();
} catch (_error) { } catch (_error) {
/** we do not handle failure */ /** we do not handle failure */
} }
@@ -201,15 +201,15 @@ async function verifySheet(
sheetId = currentSheetId, sheetId = currentSheetId,
authClient = currentAuthClient, authClient = currentAuthClient,
): Promise<{ worksheetOptions: string[] }> { ): Promise<{ worksheetOptions: string[] }> {
const spreadsheets = await sheets({ version: 'v4', auth: authClient }).spreadsheets.get({ try {
spreadsheetId: sheetId, const spreadsheets = await sheets({ version: 'v4', auth: authClient }).spreadsheets.get({
includeGridData: false, spreadsheetId: sheetId,
}); includeGridData: false,
});
if (spreadsheets.status !== 200) { return { worksheetOptions: spreadsheets.data.sheets.map((i) => i.properties.title) };
throw new Error(spreadsheets.statusText); } catch (error) {
throw new Error(`Failed to verify sheet: ${error.message}`);
} }
return { worksheetOptions: spreadsheets.data.sheets.map((i) => i.properties.title) };
} }
export async function handleInitialConnection( export async function handleInitialConnection(