mirror of
https://github.com/cpvalente/ontime.git
synced 2026-09-05 14:29:20 +00:00
Sheets revision (#809)
* refactor: poll for authentication * refactor: show success card
This commit is contained in:
@@ -10,7 +10,7 @@ const sheetsPath = `${apiEntryUrl}/sheets`;
|
|||||||
* HTTP request to verify whether we are authenticated with Google Sheet service
|
* HTTP request to verify whether we are authenticated with Google Sheet service
|
||||||
*/
|
*/
|
||||||
export const verifyAuthenticationStatus = async (): Promise<{ authenticated: AuthenticationStatus }> => {
|
export const verifyAuthenticationStatus = async (): Promise<{ authenticated: AuthenticationStatus }> => {
|
||||||
const response = await axios.get(`${apiEntryUrl}/connect`);
|
const response = await axios.get(`${sheetsPath}/connect`);
|
||||||
return response.data;
|
return response.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+25
-23
@@ -69,29 +69,31 @@ export default function ProjectSettingsPanel() {
|
|||||||
</AlertDescription>
|
</AlertDescription>
|
||||||
</Alert>
|
</Alert>
|
||||||
</Panel.Section>
|
</Panel.Section>
|
||||||
{isAdding && <CustomFieldForm onSubmit={handleCreate} onCancel={handleCancel} />}
|
<Panel.Section>
|
||||||
<Panel.Table>
|
{isAdding && <CustomFieldForm onSubmit={handleCreate} onCancel={handleCancel} />}
|
||||||
<thead>
|
<Panel.Table>
|
||||||
<tr>
|
<thead>
|
||||||
<th>Colour</th>
|
<tr>
|
||||||
<th>Name</th>
|
<th>Colour</th>
|
||||||
<th />
|
<th>Name</th>
|
||||||
</tr>
|
<th />
|
||||||
</thead>
|
</tr>
|
||||||
<tbody>
|
</thead>
|
||||||
{Object.entries(data).map(([key, { colour, label }]) => {
|
<tbody>
|
||||||
return (
|
{Object.entries(data).map(([key, { colour, label }]) => {
|
||||||
<CustomFieldEntry
|
return (
|
||||||
key={key}
|
<CustomFieldEntry
|
||||||
colour={colour}
|
key={key}
|
||||||
label={label}
|
colour={colour}
|
||||||
onEdit={handleEditField}
|
label={label}
|
||||||
onDelete={handleDelete}
|
onEdit={handleEditField}
|
||||||
/>
|
onDelete={handleDelete}
|
||||||
);
|
/>
|
||||||
})}
|
);
|
||||||
</tbody>
|
})}
|
||||||
</Panel.Table>
|
</tbody>
|
||||||
|
</Panel.Table>
|
||||||
|
</Panel.Section>
|
||||||
</Panel.Card>
|
</Panel.Card>
|
||||||
</Panel.Section>
|
</Panel.Section>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -36,16 +36,12 @@ export default function GSheetSetup(props: GSheetSetupProps) {
|
|||||||
const result = await verifyAuth();
|
const result = await verifyAuth();
|
||||||
if (result) {
|
if (result) {
|
||||||
setAuthenticationStatus(result.authenticated);
|
setAuthenticationStatus(result.authenticated);
|
||||||
// if we are still pending, lets check again in 2seconds
|
|
||||||
if (result.authenticated === 'pending') {
|
|
||||||
setTimeout(getAuthStatus, 2000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** check if the current session has been authenticated */
|
/** check if the current session has been authenticated */
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getAuthStatus();
|
untilAuthenticated();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// user cancels the flow
|
// user cancels the flow
|
||||||
@@ -88,6 +84,22 @@ export default function GSheetSetup(props: GSheetSetupProps) {
|
|||||||
setLoading('');
|
setLoading('');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const untilAuthenticated = async (attempts: number = 0) => {
|
||||||
|
const result = await verifyAuth();
|
||||||
|
if (result?.authenticated) {
|
||||||
|
setAuthenticationStatus(result.authenticated);
|
||||||
|
if (result.authenticated !== 'pending') {
|
||||||
|
setLoading('');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (attempts <= 10) {
|
||||||
|
setTimeout(() => untilAuthenticated(attempts + 1), 2000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setLoading('');
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open google auth
|
* Open google auth
|
||||||
*/
|
*/
|
||||||
@@ -99,8 +111,7 @@ export default function GSheetSetup(props: GSheetSetupProps) {
|
|||||||
window.addEventListener(
|
window.addEventListener(
|
||||||
'focus',
|
'focus',
|
||||||
async () => {
|
async () => {
|
||||||
getAuthStatus();
|
untilAuthenticated();
|
||||||
setLoading('');
|
|
||||||
},
|
},
|
||||||
{ once: true },
|
{ once: true },
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
.uploadSection {
|
.uploadSection,
|
||||||
|
.successSection {
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
|
||||||
gap: 2rem;
|
|
||||||
padding: 3rem 1rem;
|
padding: 3rem 1rem;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -11,6 +10,19 @@
|
|||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.uploadSection {
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.successSection {
|
||||||
|
color: $green-500;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
text-align: center;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
.buttonRow {
|
.buttonRow {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import { useSheetStore } from './useSheetStore';
|
|||||||
import style from './SourcesPanel.module.scss';
|
import style from './SourcesPanel.module.scss';
|
||||||
|
|
||||||
export default function SourcesPanel() {
|
export default function SourcesPanel() {
|
||||||
const [importFlow, setImportFlow] = useState<'none' | 'excel' | 'gsheet'>('none');
|
const [importFlow, setImportFlow] = useState<'none' | 'excel' | 'gsheet' | 'finished'>('none');
|
||||||
const [error, setError] = useState('');
|
const [error, setError] = useState('');
|
||||||
|
|
||||||
const { exportRundown, importRundownPreview, revoke, verifyAuth } = useGoogleSheet();
|
const { exportRundown, importRundownPreview, revoke, verifyAuth } = useGoogleSheet();
|
||||||
@@ -100,7 +100,7 @@ export default function SourcesPanel() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleFinished = () => {
|
const handleFinished = () => {
|
||||||
setImportFlow('none');
|
setImportFlow('finished');
|
||||||
setRundown(null);
|
setRundown(null);
|
||||||
setSpreadsheet(null);
|
setSpreadsheet(null);
|
||||||
setCustomFields(null);
|
setCustomFields(null);
|
||||||
@@ -116,6 +116,7 @@ export default function SourcesPanel() {
|
|||||||
const hasFile = Boolean(spreadsheet);
|
const hasFile = Boolean(spreadsheet);
|
||||||
const isAuthenticated = authenticationStatus === 'authenticated';
|
const isAuthenticated = authenticationStatus === 'authenticated';
|
||||||
const showInput = importFlow === 'none';
|
const showInput = importFlow === 'none';
|
||||||
|
const showSuccess = importFlow === 'finished';
|
||||||
const showAuth = isGSheetFlow && !isAuthenticated;
|
const showAuth = isGSheetFlow && !isAuthenticated;
|
||||||
const showImportMap = (isGSheetFlow && isAuthenticated) || (isExcelFlow && hasFile);
|
const showImportMap = (isGSheetFlow && isAuthenticated) || (isExcelFlow && hasFile);
|
||||||
const showReview = rundown !== null && customFields !== null;
|
const showReview = rundown !== null && customFields !== null;
|
||||||
@@ -154,6 +155,14 @@ export default function SourcesPanel() {
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
{showSuccess && (
|
||||||
|
<div className={style.successSection}>
|
||||||
|
<span>Import successful</span>
|
||||||
|
<Button variant='ontime-filled' size='sm' onClick={() => setImportFlow('none')}>
|
||||||
|
Return
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{showAuth && <GSheetSetup onCancel={cancelGSheetFlow} />}
|
{showAuth && <GSheetSetup onCancel={cancelGSheetFlow} />}
|
||||||
{showImportMap && !showReview && (
|
{showImportMap && !showReview && (
|
||||||
<ImportMapForm
|
<ImportMapForm
|
||||||
|
|||||||
Reference in New Issue
Block a user