refactor: move fetching to react query

This commit is contained in:
Carlos Valente
2023-12-15 10:49:52 +01:00
parent 884947374d
commit 95d7b61529
6 changed files with 101 additions and 66 deletions
@@ -9,6 +9,8 @@ export const HTTP_SETTINGS = ['httpSettings'];
export const APP_SETTINGS = ['appSettings'];
export const VIEW_SETTINGS = ['viewSettings'];
export const RUNTIME = ['runtimeStore'];
export const SHEET = ['sheet'];
export const SHEET_STATE = ['sheetState'];
const location = window.location;
const socketProtocol = location.protocol === 'https:' ? 'wss' : 'ws';
+1 -1
View File
@@ -302,7 +302,7 @@ export async function postSheetSettings(data: GoogleSheet): Promise<GoogleSheet>
* @description HTTP request to retrieve google sheets state
* @return {Promise}
*/
export async function getSheetstate(): Promise<GoogleSheetState> {
export async function getSheetState(): Promise<GoogleSheetState> {
const res = await axios.get(`${ontimeURL}/sheet-state`);
return res.data;
}
@@ -0,0 +1,21 @@
import { useQuery } from '@tanstack/react-query';
import { queryRefetchIntervalSlow } from '../../ontimeConfig';
import { SHEET } from '../api/apiConstants';
import { getSheetSettings } from '../api/ontimeApi';
const sheetPlaceholder = { worksheet: null, id: null };
export default function useSheet() {
const { data, status, isFetching, isError, refetch } = useQuery({
queryKey: SHEET,
queryFn: getSheetSettings,
placeholderData: sheetPlaceholder,
retry: 5,
retryDelay: (attempt) => attempt * 2500,
refetchInterval: queryRefetchIntervalSlow,
networkMode: 'always',
});
return { data, status, isFetching, isError, refetch };
}
@@ -0,0 +1,16 @@
import { useQuery } from '@tanstack/react-query';
import { SHEET_STATE } from '../api/apiConstants';
import { getSheetState } from '../api/ontimeApi';
export default function useSheetState() {
const { data, status, isFetching, isError, refetch } = useQuery({
queryKey: SHEET_STATE,
queryFn: getSheetState,
placeholderData: null,
enabled: false,
networkMode: 'always',
});
return { data, status, isFetching, isError, refetch };
}
@@ -18,20 +18,20 @@ import { IoArrowUpCircleOutline } from '@react-icons/all-files/io5/IoArrowUpCirc
import { IoCheckmarkCircleOutline } from '@react-icons/all-files/io5/IoCheckmarkCircleOutline';
import { IoCloseCircleOutline } from '@react-icons/all-files/io5/IoCloseCircleOutline';
import { useQueryClient } from '@tanstack/react-query';
import { GoogleSheetState, OntimeRundown, ProjectData, UserFields } from 'ontime-types';
import { OntimeRundown, ProjectData, UserFields } from 'ontime-types';
import { PROJECT_DATA, RUNDOWN, USERFIELDS } from '../../../common/api/apiConstants';
import { maybeAxiosError } from '../../../common/api/apiUtils';
import {
getSheetsAuthUrl,
getSheetSettings,
getSheetstate,
patchData,
postPreviewSheet,
postPushSheet,
postSheetSettings,
uploadSheetClientFile,
} from '../../../common/api/ontimeApi';
import useSheet from '../../../common/hooks-query/useSheet';
import useSheetState from '../../../common/hooks-query/useSheetState';
import { projectDataPlaceholder } from '../../../common/models/ProjectData';
import { userFieldsPlaceholder } from '../../../common/models/UserFields';
import PreviewExcel from '../upload-modal/preview/PreviewExcel';
@@ -44,22 +44,15 @@ interface SheetsModalProps {
export default function SheetsModal(props: SheetsModalProps) {
const { isOpen, onClose } = props;
const fileInputRef = useRef<HTMLInputElement>(null);
const queryClient = useQueryClient();
const { data } = useSheet();
const { data: sheetState, refetch } = useSheetState();
const [rundown, setRundown] = useState<OntimeRundown | null>(null);
const [userFields, setUserFields] = useState<UserFields | null>(null);
const [project, setProject] = useState<ProjectData | null>(null);
const [sheetState, setSheetState] = useState<GoogleSheetState>({
secret: false,
auth: false,
id: false,
worksheet: false,
worksheetOptions: [],
});
const queryClient = useQueryClient();
const fileInputRef = useRef<HTMLInputElement>(null);
const sheetid = useRef<HTMLInputElement>(null);
const worksheet = useRef<HTMLSelectElement>(null);
@@ -69,46 +62,54 @@ export default function SheetsModal(props: SheetsModalProps) {
setUserFields(null);
onClose();
};
const handleClick = () => {
fileInputRef.current?.click();
};
const handleFile = async (event: ChangeEvent<HTMLInputElement>) => {
const selectedFile = event?.target?.files?.[0];
if (selectedFile) {
await uploadSheetClientFile(selectedFile).catch((err) => {
console.error(err); //TODO: how to show this to the user
});
_onChange();
if (!event.target.files?.length) {
return;
}
const selectedFile = event.target.files[0];
try {
await uploadSheetClientFile(selectedFile);
} catch (error) {
// TODO: show this in the modal
console.error(error);
}
_onChange();
};
const _onChange = async () => {
setSheetState(await getSheetstate());
};
const _onChange = () => refetch();
useEffect(() => {
getSheetSettings().then((data) => {
if (data.id == '') {
return;
}
console.log(worksheet.current?.value);
if (
sheetid.current?.value != data.id ||
(worksheet.current?.value != data.worksheet && worksheet.current?.value)
) {
_onChange();
if (sheetid.current) {
sheetid.current.value = data.id;
}
if (worksheet.current) {
worksheet.current.value = data.worksheet;
}
}
});
});
if (!data) {
return;
}
const handelSave = () => {
const selectedSheetIdChanged = sheetid.current?.value !== data.id;
const selectedWorksheetChanged = worksheet.current?.value !== data.worksheet && worksheet.current?.value;
if (selectedSheetIdChanged || selectedWorksheetChanged) {
_onChange();
if (sheetid.current) {
sheetid.current.value = data.id;
}
if (worksheet.current) {
worksheet.current.value = data.worksheet;
}
}
}, [data]);
useEffect(() => {
return () => {
// Alex: This function will be run when the component unmounts
console.log('Component is unmounting');
};
}, []);
const handleSave = () => {
postSheetSettings({ id: sheetid.current?.value ?? '', worksheet: worksheet.current?.value ?? '' }).then((data) => {
_onChange();
if (sheetid.current) {
@@ -122,7 +123,7 @@ export default function SheetsModal(props: SheetsModalProps) {
const handleAuthenticate = () => {
getSheetsAuthUrl().then((data) => {
if (data != 'bad') {
if (data !== 'bad') {
window.open(data, '_blank', 'noreferrer');
//TODO: can we detect when this window is closed
}
@@ -199,22 +200,18 @@ export default function SheetsModal(props: SheetsModalProps) {
accept='.json'
data-testid='file-input'
/>
<div>Need to add some help here</div>
<br />
<div>
<Button onClick={handleClick}>Upload Client Secrect</Button>
{sheetState.secret ? 'have good secret' : 'no or bad secret'}
<Button onClick={handleClick}>Upload Client Secret</Button>
{sheetState?.secret ? 'have good secret' : 'no or bad secret'}
</div>
<br />
<div style={sheetState.secret ? {} : { display: 'none' }}>
<div style={sheetState?.secret ? {} : { display: 'none' }}>
<Button variant='ontime-filled' padding='0 2em' onClick={handleAuthenticate}>
Authenticate
</Button>
{sheetState.auth ? 'You are authenticated' : 'You are not authenticated'}
{sheetState?.auth ? 'You are authenticated' : 'You are not authenticated'}
</div>
<br />
<div style={sheetState.auth ? {} : { display: 'none' }}>
<label htmlFor='sheetid'>Sheet ID </label>
<div style={sheetState?.auth ? {} : { display: 'none' }}>
<label htmlFor='sheetid'>Sheet ID</label>
<InputGroup size='sm'>
<Input
type='text'
@@ -225,15 +222,14 @@ export default function SheetsModal(props: SheetsModalProps) {
variant='ontime-filled-on-light'
/>
<InputRightAddon>
{sheetState.id ? <IoCheckmarkCircleOutline color='green' /> : <IoCloseCircleOutline color='red' />}
{sheetState?.id ? <IoCheckmarkCircleOutline color='green' /> : <IoCloseCircleOutline color='red' />}
</InputRightAddon>
</InputGroup>
</div>
<br />
<div style={sheetState.id ? {} : { display: 'none' }}>
<div style={sheetState?.id ? {} : { display: 'none' }}>
<label htmlFor='worksheet'>Worksheet </label>
<Select ref={worksheet} size='sm' id='worksheet'>
{sheetState.worksheetOptions.map((value) => (
{sheetState?.worksheetOptions?.map((value) => (
<option key={value} value={value}>
{value}
</option>
@@ -241,9 +237,9 @@ export default function SheetsModal(props: SheetsModalProps) {
</Select>
</div>
<br />
<div style={sheetState.worksheet ? {} : { display: 'none' }}>
<div style={sheetState?.worksheet ? {} : { display: 'none' }}>
<Button
disabled={!sheetState.worksheet}
disabled={!sheetState?.worksheet}
variant='ontime-subtle-on-light'
padding='0 2em'
onClick={handlePullData}
@@ -252,7 +248,7 @@ export default function SheetsModal(props: SheetsModalProps) {
Pull Rundown
</Button>
<Button
disabled={!sheetState.worksheet}
disabled={!sheetState?.worksheet}
variant='ontime-subtle-on-light'
padding='0 2em'
onClick={handlePushData}
@@ -267,7 +263,7 @@ export default function SheetsModal(props: SheetsModalProps) {
<ModalFooter>
<Button variant='ontime-ghost-on-light'>Reset</Button>
{!rundown && (
<Button variant='ontime-filled' padding='0 2em' onClick={handelSave}>
<Button variant='ontime-filled' padding='0 2em' onClick={handleSave}>
Save
</Button>
)}
@@ -1,6 +1,6 @@
export type GoogleSheet = {
worksheet: string;
id: string;
worksheet: string | null;
id: string | null;
};
export type GoogleSheetState = {
@@ -9,4 +9,4 @@ export type GoogleSheetState = {
id: boolean;
worksheet: boolean;
worksheetOptions: string[];
};
} | null;