mirror of
https://github.com/cpvalente/ontime.git
synced 2026-09-01 20:39:18 +00:00
refactor: move fetching to react query
This commit is contained in:
@@ -9,6 +9,8 @@ export const HTTP_SETTINGS = ['httpSettings'];
|
|||||||
export const APP_SETTINGS = ['appSettings'];
|
export const APP_SETTINGS = ['appSettings'];
|
||||||
export const VIEW_SETTINGS = ['viewSettings'];
|
export const VIEW_SETTINGS = ['viewSettings'];
|
||||||
export const RUNTIME = ['runtimeStore'];
|
export const RUNTIME = ['runtimeStore'];
|
||||||
|
export const SHEET = ['sheet'];
|
||||||
|
export const SHEET_STATE = ['sheetState'];
|
||||||
|
|
||||||
const location = window.location;
|
const location = window.location;
|
||||||
const socketProtocol = location.protocol === 'https:' ? 'wss' : 'ws';
|
const socketProtocol = location.protocol === 'https:' ? 'wss' : 'ws';
|
||||||
|
|||||||
@@ -302,7 +302,7 @@ export async function postSheetSettings(data: GoogleSheet): Promise<GoogleSheet>
|
|||||||
* @description HTTP request to retrieve google sheets state
|
* @description HTTP request to retrieve google sheets state
|
||||||
* @return {Promise}
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
export async function getSheetstate(): Promise<GoogleSheetState> {
|
export async function getSheetState(): Promise<GoogleSheetState> {
|
||||||
const res = await axios.get(`${ontimeURL}/sheet-state`);
|
const res = await axios.get(`${ontimeURL}/sheet-state`);
|
||||||
return res.data;
|
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 { IoCheckmarkCircleOutline } from '@react-icons/all-files/io5/IoCheckmarkCircleOutline';
|
||||||
import { IoCloseCircleOutline } from '@react-icons/all-files/io5/IoCloseCircleOutline';
|
import { IoCloseCircleOutline } from '@react-icons/all-files/io5/IoCloseCircleOutline';
|
||||||
import { useQueryClient } from '@tanstack/react-query';
|
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 { PROJECT_DATA, RUNDOWN, USERFIELDS } from '../../../common/api/apiConstants';
|
||||||
import { maybeAxiosError } from '../../../common/api/apiUtils';
|
import { maybeAxiosError } from '../../../common/api/apiUtils';
|
||||||
import {
|
import {
|
||||||
getSheetsAuthUrl,
|
getSheetsAuthUrl,
|
||||||
getSheetSettings,
|
|
||||||
getSheetstate,
|
|
||||||
patchData,
|
patchData,
|
||||||
postPreviewSheet,
|
postPreviewSheet,
|
||||||
postPushSheet,
|
postPushSheet,
|
||||||
postSheetSettings,
|
postSheetSettings,
|
||||||
uploadSheetClientFile,
|
uploadSheetClientFile,
|
||||||
} from '../../../common/api/ontimeApi';
|
} 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 { projectDataPlaceholder } from '../../../common/models/ProjectData';
|
||||||
import { userFieldsPlaceholder } from '../../../common/models/UserFields';
|
import { userFieldsPlaceholder } from '../../../common/models/UserFields';
|
||||||
import PreviewExcel from '../upload-modal/preview/PreviewExcel';
|
import PreviewExcel from '../upload-modal/preview/PreviewExcel';
|
||||||
@@ -44,22 +44,15 @@ interface SheetsModalProps {
|
|||||||
export default function SheetsModal(props: SheetsModalProps) {
|
export default function SheetsModal(props: SheetsModalProps) {
|
||||||
const { isOpen, onClose } = props;
|
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 [rundown, setRundown] = useState<OntimeRundown | null>(null);
|
||||||
const [userFields, setUserFields] = useState<UserFields | null>(null);
|
const [userFields, setUserFields] = useState<UserFields | null>(null);
|
||||||
const [project, setProject] = useState<ProjectData | null>(null);
|
const [project, setProject] = useState<ProjectData | null>(null);
|
||||||
|
|
||||||
const [sheetState, setSheetState] = useState<GoogleSheetState>({
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||||
secret: false,
|
|
||||||
auth: false,
|
|
||||||
id: false,
|
|
||||||
worksheet: false,
|
|
||||||
worksheetOptions: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
const queryClient = useQueryClient();
|
|
||||||
|
|
||||||
const sheetid = useRef<HTMLInputElement>(null);
|
const sheetid = useRef<HTMLInputElement>(null);
|
||||||
const worksheet = useRef<HTMLSelectElement>(null);
|
const worksheet = useRef<HTMLSelectElement>(null);
|
||||||
|
|
||||||
@@ -69,46 +62,54 @@ export default function SheetsModal(props: SheetsModalProps) {
|
|||||||
setUserFields(null);
|
setUserFields(null);
|
||||||
onClose();
|
onClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
fileInputRef.current?.click();
|
fileInputRef.current?.click();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFile = async (event: ChangeEvent<HTMLInputElement>) => {
|
const handleFile = async (event: ChangeEvent<HTMLInputElement>) => {
|
||||||
const selectedFile = event?.target?.files?.[0];
|
if (!event.target.files?.length) {
|
||||||
if (selectedFile) {
|
return;
|
||||||
await uploadSheetClientFile(selectedFile).catch((err) => {
|
|
||||||
console.error(err); //TODO: how to show this to the user
|
|
||||||
});
|
|
||||||
_onChange();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 () => {
|
const _onChange = () => refetch();
|
||||||
setSheetState(await getSheetstate());
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getSheetSettings().then((data) => {
|
if (!data) {
|
||||||
if (data.id == '') {
|
return;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
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) => {
|
postSheetSettings({ id: sheetid.current?.value ?? '', worksheet: worksheet.current?.value ?? '' }).then((data) => {
|
||||||
_onChange();
|
_onChange();
|
||||||
if (sheetid.current) {
|
if (sheetid.current) {
|
||||||
@@ -122,7 +123,7 @@ export default function SheetsModal(props: SheetsModalProps) {
|
|||||||
|
|
||||||
const handleAuthenticate = () => {
|
const handleAuthenticate = () => {
|
||||||
getSheetsAuthUrl().then((data) => {
|
getSheetsAuthUrl().then((data) => {
|
||||||
if (data != 'bad') {
|
if (data !== 'bad') {
|
||||||
window.open(data, '_blank', 'noreferrer');
|
window.open(data, '_blank', 'noreferrer');
|
||||||
//TODO: can we detect when this window is closed
|
//TODO: can we detect when this window is closed
|
||||||
}
|
}
|
||||||
@@ -199,22 +200,18 @@ export default function SheetsModal(props: SheetsModalProps) {
|
|||||||
accept='.json'
|
accept='.json'
|
||||||
data-testid='file-input'
|
data-testid='file-input'
|
||||||
/>
|
/>
|
||||||
<div>Need to add some help here</div>
|
|
||||||
<br />
|
|
||||||
<div>
|
<div>
|
||||||
<Button onClick={handleClick}>Upload Client Secrect</Button>
|
<Button onClick={handleClick}>Upload Client Secret</Button>
|
||||||
{sheetState.secret ? 'have good secret' : 'no or bad secret'}
|
{sheetState?.secret ? 'have good secret' : 'no or bad secret'}
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<div style={sheetState?.secret ? {} : { display: 'none' }}>
|
||||||
<div style={sheetState.secret ? {} : { display: 'none' }}>
|
|
||||||
<Button variant='ontime-filled' padding='0 2em' onClick={handleAuthenticate}>
|
<Button variant='ontime-filled' padding='0 2em' onClick={handleAuthenticate}>
|
||||||
Authenticate
|
Authenticate
|
||||||
</Button>
|
</Button>
|
||||||
{sheetState.auth ? 'You are authenticated' : 'You are not authenticated'}
|
{sheetState?.auth ? 'You are authenticated' : 'You are not authenticated'}
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<div style={sheetState?.auth ? {} : { display: 'none' }}>
|
||||||
<div style={sheetState.auth ? {} : { display: 'none' }}>
|
<label htmlFor='sheetid'>Sheet ID</label>
|
||||||
<label htmlFor='sheetid'>Sheet ID </label>
|
|
||||||
<InputGroup size='sm'>
|
<InputGroup size='sm'>
|
||||||
<Input
|
<Input
|
||||||
type='text'
|
type='text'
|
||||||
@@ -225,15 +222,14 @@ export default function SheetsModal(props: SheetsModalProps) {
|
|||||||
variant='ontime-filled-on-light'
|
variant='ontime-filled-on-light'
|
||||||
/>
|
/>
|
||||||
<InputRightAddon>
|
<InputRightAddon>
|
||||||
{sheetState.id ? <IoCheckmarkCircleOutline color='green' /> : <IoCloseCircleOutline color='red' />}
|
{sheetState?.id ? <IoCheckmarkCircleOutline color='green' /> : <IoCloseCircleOutline color='red' />}
|
||||||
</InputRightAddon>
|
</InputRightAddon>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<div style={sheetState?.id ? {} : { display: 'none' }}>
|
||||||
<div style={sheetState.id ? {} : { display: 'none' }}>
|
|
||||||
<label htmlFor='worksheet'>Worksheet </label>
|
<label htmlFor='worksheet'>Worksheet </label>
|
||||||
<Select ref={worksheet} size='sm' id='worksheet'>
|
<Select ref={worksheet} size='sm' id='worksheet'>
|
||||||
{sheetState.worksheetOptions.map((value) => (
|
{sheetState?.worksheetOptions?.map((value) => (
|
||||||
<option key={value} value={value}>
|
<option key={value} value={value}>
|
||||||
{value}
|
{value}
|
||||||
</option>
|
</option>
|
||||||
@@ -241,9 +237,9 @@ export default function SheetsModal(props: SheetsModalProps) {
|
|||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
<div style={sheetState.worksheet ? {} : { display: 'none' }}>
|
<div style={sheetState?.worksheet ? {} : { display: 'none' }}>
|
||||||
<Button
|
<Button
|
||||||
disabled={!sheetState.worksheet}
|
disabled={!sheetState?.worksheet}
|
||||||
variant='ontime-subtle-on-light'
|
variant='ontime-subtle-on-light'
|
||||||
padding='0 2em'
|
padding='0 2em'
|
||||||
onClick={handlePullData}
|
onClick={handlePullData}
|
||||||
@@ -252,7 +248,7 @@ export default function SheetsModal(props: SheetsModalProps) {
|
|||||||
Pull Rundown
|
Pull Rundown
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
disabled={!sheetState.worksheet}
|
disabled={!sheetState?.worksheet}
|
||||||
variant='ontime-subtle-on-light'
|
variant='ontime-subtle-on-light'
|
||||||
padding='0 2em'
|
padding='0 2em'
|
||||||
onClick={handlePushData}
|
onClick={handlePushData}
|
||||||
@@ -267,7 +263,7 @@ export default function SheetsModal(props: SheetsModalProps) {
|
|||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button variant='ontime-ghost-on-light'>Reset</Button>
|
<Button variant='ontime-ghost-on-light'>Reset</Button>
|
||||||
{!rundown && (
|
{!rundown && (
|
||||||
<Button variant='ontime-filled' padding='0 2em' onClick={handelSave}>
|
<Button variant='ontime-filled' padding='0 2em' onClick={handleSave}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export type GoogleSheet = {
|
export type GoogleSheet = {
|
||||||
worksheet: string;
|
worksheet: string | null;
|
||||||
id: string;
|
id: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type GoogleSheetState = {
|
export type GoogleSheetState = {
|
||||||
@@ -9,4 +9,4 @@ export type GoogleSheetState = {
|
|||||||
id: boolean;
|
id: boolean;
|
||||||
worksheet: boolean;
|
worksheet: boolean;
|
||||||
worksheetOptions: string[];
|
worksheetOptions: string[];
|
||||||
};
|
} | null;
|
||||||
|
|||||||
Reference in New Issue
Block a user