mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-19 22:24:11 +00:00
display errors in UI
This commit is contained in:
@@ -55,6 +55,14 @@ export default function SheetsModal(props: SheetsModalProps) {
|
|||||||
const sheetRef = useRef<HTMLInputElement>(null);
|
const sheetRef = useRef<HTMLInputElement>(null);
|
||||||
const worksheetRef = useRef<HTMLSelectElement>(null);
|
const worksheetRef = useRef<HTMLSelectElement>(null);
|
||||||
|
|
||||||
|
const [errors, setErrors] = useState({
|
||||||
|
clientSecret: '',
|
||||||
|
authenticate: '',
|
||||||
|
sheetId: '',
|
||||||
|
worksheet: '',
|
||||||
|
pullPush: '',
|
||||||
|
});
|
||||||
|
|
||||||
const [sheetState, setState] = useState<SheetState>({
|
const [sheetState, setState] = useState<SheetState>({
|
||||||
secret: false,
|
secret: false,
|
||||||
auth: false,
|
auth: false,
|
||||||
@@ -63,10 +71,6 @@ export default function SheetsModal(props: SheetsModalProps) {
|
|||||||
worksheetOptions: [],
|
worksheetOptions: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
const testId = async () => {
|
|
||||||
setState(await getSheetState(sheetRef.current?.value ?? '', worksheetRef.current?.value ?? ''));
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
setRundown(null);
|
setRundown(null);
|
||||||
setProject(null);
|
setProject(null);
|
||||||
@@ -81,21 +85,37 @@ export default function SheetsModal(props: SheetsModalProps) {
|
|||||||
const updateSheetState = () => {
|
const updateSheetState = () => {
|
||||||
const currentSheetId = sheetRef.current?.value ?? '';
|
const currentSheetId = sheetRef.current?.value ?? '';
|
||||||
const currentWorksheet = worksheetRef.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) {
|
if (!event.target.files?.length) {
|
||||||
|
setErrors({ ...errors, clientSecret: 'Missing file' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectedFile = event.target.files[0];
|
const selectedFile = event.target.files[0];
|
||||||
try {
|
uploadSheetClientFile(selectedFile)
|
||||||
await uploadSheetClientFile(selectedFile);
|
.then(() => {
|
||||||
} catch (error) {
|
setErrors({ ...errors, clientSecret: '' });
|
||||||
// TODO: show this in the modal
|
})
|
||||||
console.error(error);
|
.catch((err) => {
|
||||||
}
|
if (err.response.data.message) {
|
||||||
|
setErrors({ ...errors, clientSecret: err.response.data.message });
|
||||||
|
}
|
||||||
|
});
|
||||||
updateSheetState();
|
updateSheetState();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -106,12 +126,16 @@ export default function SheetsModal(props: SheetsModalProps) {
|
|||||||
}, [isOpen]);
|
}, [isOpen]);
|
||||||
|
|
||||||
const handleAuthenticate = () => {
|
const handleAuthenticate = () => {
|
||||||
getSheetsAuthUrl().then((data) => {
|
getSheetsAuthUrl()
|
||||||
if (data !== 'bad') {
|
.then((data) => {
|
||||||
openLink(data);
|
openLink(data);
|
||||||
window.addEventListener('focus', () => updateSheetState(), { once: true });
|
window.addEventListener('focus', () => updateSheetState(), { once: true });
|
||||||
}
|
})
|
||||||
});
|
.catch((err) => {
|
||||||
|
if (err.response.data.message) {
|
||||||
|
setErrors({ ...errors, authenticate: err.response.data.message });
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePullData = () => {
|
const handlePullData = () => {
|
||||||
@@ -180,7 +204,12 @@ export default function SheetsModal(props: SheetsModalProps) {
|
|||||||
</Alert>
|
</Alert>
|
||||||
{!rundown ? (
|
{!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
|
<Input
|
||||||
ref={fileInputRef}
|
ref={fileInputRef}
|
||||||
style={{ display: 'none' }}
|
style={{ display: 'none' }}
|
||||||
@@ -198,6 +227,7 @@ export default function SheetsModal(props: SheetsModalProps) {
|
|||||||
title='2 - Authenticate with Google'
|
title='2 - Authenticate with Google'
|
||||||
completed={Boolean(sheetState?.auth)}
|
completed={Boolean(sheetState?.auth)}
|
||||||
disabled={!sheetState?.secret}
|
disabled={!sheetState?.secret}
|
||||||
|
error={errors.authenticate}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
size='sm'
|
size='sm'
|
||||||
@@ -209,7 +239,12 @@ export default function SheetsModal(props: SheetsModalProps) {
|
|||||||
</Button>
|
</Button>
|
||||||
</Step>
|
</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>
|
<HStack>
|
||||||
<Input
|
<Input
|
||||||
type='text'
|
type='text'
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { PropsWithChildren, useEffect, useState } from 'react';
|
import { PropsWithChildren, useEffect, useState } from 'react';
|
||||||
import { IoCheckmarkCircle } from '@react-icons/all-files/io5/IoCheckmarkCircle';
|
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 { IoRadioButtonOffOutline } from '@react-icons/all-files/io5/IoRadioButtonOffOutline';
|
||||||
|
|
||||||
import style from './Step.module.scss';
|
import style from './Step.module.scss';
|
||||||
@@ -15,7 +15,7 @@ interface StepProps {
|
|||||||
export default function Step(props: PropsWithChildren<StepProps>) {
|
export default function Step(props: PropsWithChildren<StepProps>) {
|
||||||
const { title, disabled, completed, error, children } = props;
|
const { title, disabled, completed, error, children } = props;
|
||||||
const [collapsed, setCollapsed] = useState(disabled);
|
const [collapsed, setCollapsed] = useState(disabled);
|
||||||
|
|
||||||
const handleCollapse = () => setCollapsed((prev) => !prev);
|
const handleCollapse = () => setCollapsed((prev) => !prev);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -27,9 +27,14 @@ export default function Step(props: PropsWithChildren<StepProps>) {
|
|||||||
return (
|
return (
|
||||||
<div className={style.wrapper}>
|
<div className={style.wrapper}>
|
||||||
<div className={style.header} onClick={handleCollapse}>
|
<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>
|
<span className={style.title}>{title}</span>
|
||||||
{error && <IoClose className={style.errorIcon} />}
|
|
||||||
</div>
|
</div>
|
||||||
{!collapsed && (
|
{!collapsed && (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -515,11 +515,11 @@ export async function uploadSheetClientFile(req, res) {
|
|||||||
* @method GET
|
* @method GET
|
||||||
*/
|
*/
|
||||||
export async function sheetAuthUrl(req, res) {
|
export async function sheetAuthUrl(req, res) {
|
||||||
const authUrl = await Sheet.openAuthServer();
|
try {
|
||||||
if (!authUrl) {
|
const authUrl = await Sheet.openAuthServer();
|
||||||
res.status(500).send('Unable to start auth server');
|
|
||||||
} else {
|
|
||||||
res.status(200).send(authUrl);
|
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) => {
|
export const getSheetState = async (req, res) => {
|
||||||
const { id, worksheet } = req.body;
|
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() });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -54,14 +54,10 @@ class sheet {
|
|||||||
state.auth = sheet.client !== null;
|
state.auth = sheet.client !== null;
|
||||||
|
|
||||||
if (id != '' && state.auth) {
|
if (id != '' && state.auth) {
|
||||||
const spreadsheets = await sheets({ version: 'v4', auth: sheet.client })
|
const spreadsheets = await sheets({ version: 'v4', auth: sheet.client }).spreadsheets.get({
|
||||||
.spreadsheets.get({
|
spreadsheetId: id,
|
||||||
spreadsheetId: id,
|
includeGridData: false,
|
||||||
includeGridData: false,
|
});
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
logger.error(LogOrigin.Server, `Sheet: faild to load sheet ${err}`);
|
|
||||||
});
|
|
||||||
if (!spreadsheets || spreadsheets.status != 200) {
|
if (!spreadsheets || spreadsheets.status != 200) {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user