display errors in UI

This commit is contained in:
arc-alex
2024-01-03 01:52:30 +01:00
parent ba89673d5f
commit cb6dee552f
4 changed files with 76 additions and 35 deletions
@@ -55,6 +55,14 @@ export default function SheetsModal(props: SheetsModalProps) {
const sheetRef = useRef<HTMLInputElement>(null);
const worksheetRef = useRef<HTMLSelectElement>(null);
const [errors, setErrors] = useState({
clientSecret: '',
authenticate: '',
sheetId: '',
worksheet: '',
pullPush: '',
});
const [sheetState, setState] = useState<SheetState>({
secret: false,
auth: false,
@@ -63,10 +71,6 @@ export default function SheetsModal(props: SheetsModalProps) {
worksheetOptions: [],
});
const testId = async () => {
setState(await getSheetState(sheetRef.current?.value ?? '', worksheetRef.current?.value ?? ''));
};
const handleClose = () => {
setRundown(null);
setProject(null);
@@ -81,21 +85,37 @@ export default function SheetsModal(props: SheetsModalProps) {
const updateSheetState = () => {
const currentSheetId = sheetRef.current?.value ?? '';
const currentWorksheet = worksheetRef.current?.value ?? '';
getSheetState(currentSheetId, currentWorksheet).then((data) => setState(data));
return getSheetState(currentSheetId, currentWorksheet).then((data) => setState(data));
};
const handleFile = async (event: ChangeEvent<HTMLInputElement>) => {
const testId = () => {
const currentSheetId = sheetRef.current?.value ?? '';
const currentWorksheet = worksheetRef.current?.value ?? '';
getSheetState(currentSheetId, currentWorksheet)
.then((data) => setState(data))
.catch((err) => {
if (err.response.data.message) {
setErrors({ ...errors, sheetId: err.response.data.message });
}
});
};
const handleFile = (event: ChangeEvent<HTMLInputElement>) => {
if (!event.target.files?.length) {
setErrors({ ...errors, clientSecret: 'Missing file' });
return;
}
const selectedFile = event.target.files[0];
try {
await uploadSheetClientFile(selectedFile);
} catch (error) {
// TODO: show this in the modal
console.error(error);
}
uploadSheetClientFile(selectedFile)
.then(() => {
setErrors({ ...errors, clientSecret: '' });
})
.catch((err) => {
if (err.response.data.message) {
setErrors({ ...errors, clientSecret: err.response.data.message });
}
});
updateSheetState();
};
@@ -106,12 +126,16 @@ export default function SheetsModal(props: SheetsModalProps) {
}, [isOpen]);
const handleAuthenticate = () => {
getSheetsAuthUrl().then((data) => {
if (data !== 'bad') {
getSheetsAuthUrl()
.then((data) => {
openLink(data);
window.addEventListener('focus', () => updateSheetState(), { once: true });
}
});
})
.catch((err) => {
if (err.response.data.message) {
setErrors({ ...errors, authenticate: err.response.data.message });
}
});
};
const handlePullData = () => {
@@ -180,7 +204,12 @@ export default function SheetsModal(props: SheetsModalProps) {
</Alert>
{!rundown ? (
<>
<Step title='1 - Upload OAuth 2.0 Client ID' completed={Boolean(sheetState?.secret)} disabled={false}>
<Step
title='1 - Upload OAuth 2.0 Client ID'
completed={Boolean(sheetState?.secret)}
disabled={false}
error={errors.clientSecret}
>
<Input
ref={fileInputRef}
style={{ display: 'none' }}
@@ -198,6 +227,7 @@ export default function SheetsModal(props: SheetsModalProps) {
title='2 - Authenticate with Google'
completed={Boolean(sheetState?.auth)}
disabled={!sheetState?.secret}
error={errors.authenticate}
>
<Button
size='sm'
@@ -209,7 +239,12 @@ export default function SheetsModal(props: SheetsModalProps) {
</Button>
</Step>
<Step title='3 - Add Document ID' completed={Boolean(sheetState?.id)} disabled={!sheetState?.auth}>
<Step
title='3 - Add Document ID'
completed={Boolean(sheetState?.id)}
disabled={!sheetState?.auth}
error={errors.sheetId}
>
<HStack>
<Input
type='text'
@@ -1,6 +1,6 @@
import { PropsWithChildren, useEffect, useState } from 'react';
import { IoCheckmarkCircle } from '@react-icons/all-files/io5/IoCheckmarkCircle';
import { IoClose } from '@react-icons/all-files/io5/IoClose';
import { IoCloseCircle } from '@react-icons/all-files/io5/IoCloseCircle';
import { IoRadioButtonOffOutline } from '@react-icons/all-files/io5/IoRadioButtonOffOutline';
import style from './Step.module.scss';
@@ -15,7 +15,7 @@ interface StepProps {
export default function Step(props: PropsWithChildren<StepProps>) {
const { title, disabled, completed, error, children } = props;
const [collapsed, setCollapsed] = useState(disabled);
const handleCollapse = () => setCollapsed((prev) => !prev);
useEffect(() => {
@@ -27,9 +27,14 @@ export default function Step(props: PropsWithChildren<StepProps>) {
return (
<div className={style.wrapper}>
<div className={style.header} onClick={handleCollapse}>
{completed ? <IoCheckmarkCircle className={style.step} /> : <IoRadioButtonOffOutline className={style.step} />}
{completed ? (
<IoCheckmarkCircle className={style.step} style={{ color: 'green' }} />
) : error ? (
<IoCloseCircle className={style.step} style={{ color: 'red' }} />
) : (
<IoRadioButtonOffOutline className={style.step} />
)}
<span className={style.title}>{title}</span>
{error && <IoClose className={style.errorIcon} />}
</div>
{!collapsed && (
<>
@@ -515,11 +515,11 @@ export async function uploadSheetClientFile(req, res) {
* @method GET
*/
export async function sheetAuthUrl(req, res) {
const authUrl = await Sheet.openAuthServer();
if (!authUrl) {
res.status(500).send('Unable to start auth server');
} else {
try {
const authUrl = await Sheet.openAuthServer();
res.status(200).send(authUrl);
} catch (error) {
res.status(500).send({ message: error.toString() });
}
}
@@ -529,5 +529,10 @@ export async function sheetAuthUrl(req, res) {
*/
export const getSheetState = async (req, res) => {
const { id, worksheet } = req.body;
res.status(200).send(await Sheet.getSheetState(id, worksheet));
try {
const state = await Sheet.getSheetState(id, worksheet);
res.status(200).send(state);
} catch (error) {
res.status(500).send({ message: error.toString() });
}
};
+4 -8
View File
@@ -54,14 +54,10 @@ class sheet {
state.auth = sheet.client !== null;
if (id != '' && state.auth) {
const spreadsheets = await sheets({ version: 'v4', auth: sheet.client })
.spreadsheets.get({
spreadsheetId: id,
includeGridData: false,
})
.catch((err) => {
logger.error(LogOrigin.Server, `Sheet: faild to load sheet ${err}`);
});
const spreadsheets = await sheets({ version: 'v4', auth: sheet.client }).spreadsheets.get({
spreadsheetId: id,
includeGridData: false,
});
if (!spreadsheets || spreadsheets.status != 200) {
return state;
}