clean up sheet flow

This commit is contained in:
arc-alex
2023-11-24 17:47:21 +01:00
parent 111df94d6d
commit e8bcbb4291
6 changed files with 63 additions and 104 deletions
+4 -12
View File
@@ -251,21 +251,13 @@ export const getSheetsAuthUrl = async () => {
return res.data;
};
export const postPreviewSheet = async (sheetId: string, worksheet: string, options?: ExcelImportMap) => {
const response = await axios.post(`${ontimeURL}/sheet-preview`, {
sheetid: sheetId,
worksheet: worksheet,
options: options,
});
export const postPreviewSheet = async () => {
const response = await axios.post(`${ontimeURL}/sheet-preview`);
return response.data.data;
};
export const postPushSheet = async (sheetId: string, worksheet: string, options?: ExcelImportMap) => {
const response = await axios.post(`${ontimeURL}/sheet-push`, {
sheetid: sheetId,
worksheet: worksheet,
options: options,
});
export const postPushSheet = async () => {
const response = await axios.post(`${ontimeURL}/sheet-push`);
return response.data.data;
};
@@ -13,7 +13,7 @@ import {
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 { GoogleSheetState, OntimeRundown, ProjectData, UserFields } from 'ontime-types';
import { PROJECT_DATA, RUNDOWN, USERFIELDS } from '../../../common/api/apiConstants';
import { maybeAxiosError } from '../../../common/api/apiUtils';
@@ -56,19 +56,19 @@ export default function SheetsModal(props: SheetsModalProps) {
setRundown(null);
setProject(null);
setUserFields(null);
// setSheetState({ auth: false, id: false, worksheet: false });
onClose();
};
const handleClick = () => {
fileInputRef.current?.click();
};
const handleFile = (event: ChangeEvent<HTMLInputElement>) => {
const handleFile = async (event: ChangeEvent<HTMLInputElement>) => {
const selectedFile = event?.target?.files?.[0];
if (!selectedFile) {
return;
} else {
uploadSheetClientFile(selectedFile);
await uploadSheetClientFile(selectedFile);
_onChange();
}
};
@@ -112,7 +112,7 @@ export default function SheetsModal(props: SheetsModalProps) {
};
const handlePullData = () => {
postPreviewSheet(sheetid.current?.value ?? '', worksheet.current?.value ?? '').then((data) => {
postPreviewSheet().then((data) => {
setProject(data.project);
setRundown(data.rundown);
setUserFields(data.userFields);
@@ -120,7 +120,7 @@ export default function SheetsModal(props: SheetsModalProps) {
};
const handlePushData = () => {
postPushSheet(sheetid.current?.value ?? '', worksheet.current?.value ?? '').then((data) => {
postPushSheet().then((data) => {
console.log(data);
});
};
@@ -218,18 +218,20 @@ export default function SheetsModal(props: SheetsModalProps) {
/>
{sheetState.worksheet ? <IoCheckmarkCircleOutline /> : <IoCloseCircleOutline />}
</div>
<div>
<Button variant='ontime-filled' padding='0 2em' onClick={handlePullData}>
Pull data
</Button>
<Button variant='ontime-filled' padding='0 2em' onClick={handlePushData}>
Push data
</Button>
</div>
</>
)}
</ModalBody>
<ModalFooter>
{!rundown && (
<div>
<Button variant='ontime-subtle-on-light' padding='0 2em' onClick={handlePullData}>
Pull data
</Button>
<Button variant='ontime-subtle-on-light' padding='0 2em' onClick={handlePushData}>
Push data
</Button>
</div>
)}
<Button variant='ontime-ghost-on-light'>Reset</Button>
{!rundown && (
<Button variant='ontime-filled' padding='0 2em' onClick={handelSave}>
@@ -423,7 +423,7 @@ export const postNew: RequestHandler = async (req, res) => {
*/
export async function previewSheet(req, res) {
try {
const data = await Sheet.pull(req.body.sheetid, req.body.worksheet);
const data = await Sheet.pull();
res.status(200).send(data);
} catch (error) {
res.status(500).send({ message: error.toString() });
@@ -436,7 +436,7 @@ export async function previewSheet(req, res) {
*/
export async function pushSheet(req, res) {
try {
await Sheet.push(req.body.sheetid, req.body.worksheet);
await Sheet.push();
res.status(200).send('ok');
} catch (error) {
res.status(500).send({ message: error.toString() });
@@ -465,14 +465,6 @@ export async function uploadGoogleSheetClientFile(req, res) {
});
}
/**
* @returns sheet auth state
*/
export async function sheetAuthState(req, res) {
const send = (await Sheet.authorized()) ? 'true' : 'false';
res.status(200).send(send);
}
/**
* @returns link to sheet auth url
*/
-4
View File
@@ -20,7 +20,6 @@ import {
postViewSettings,
previewExcel,
sheetAuthUrl,
sheetAuthState,
uploadGoogleSheetClientFile,
previewSheet,
pushSheet,
@@ -101,9 +100,6 @@ router.post('/new', projectSanitiser, postNew);
// create route between controller and '/ontime/sheet-client' endpoint
router.post('/sheet-clientsecrect', uploadFile, uploadGoogleSheetClientFile);
// create route between controller and '/ontime/sheet-authstatus' endpoint
router.get('/sheet-authstatus', sheetAuthState);
// create route between controller and '/ontime/sheet-authstatus' endpoint
router.get('/sheet-authurl', sheetAuthUrl);
+1 -1
View File
@@ -17,7 +17,6 @@ import {
UserFields,
EndAction,
TimerType,
GoogleSheet,
} from 'ontime-types';
import fs from 'fs';
@@ -370,6 +369,7 @@ export const parseJson = async (jsonData): Promise<DatabaseModel | null> => {
returnData.osc = parseOsc(jsonData) ?? dbModel.osc;
// Import HTTP settings if any
// returnData.http = parseHttp(jsonData, enforce);
// Import GoogleSheet settings if any
returnData.googleSheet = parseGoogleSheet(jsonData, true);
return returnData as DatabaseModel;
+40 -63
View File
@@ -6,7 +6,7 @@ import { URL } from 'url';
import { logger } from '../classes/Logger.js';
import { getAppDataPath } from '../setup.js';
import { DatabaseModel, LogOrigin, OntimeRundownEntry, isOntimeEvent } from 'ontime-types';
import { isExcelImportMap, defaultExcelImportMap, millisToString } from 'ontime-utils';
import { millisToString } from 'ontime-utils';
import { parseExcel } from './parser.js';
import { parseProject, parseRundown, parseUserFields } from './parserFunctions.js';
import { ensureDirectory } from './fileManagement.js';
@@ -24,6 +24,9 @@ class sheet {
private readonly client_secret = this.sheetsFolder + '/client_secret.json';
private readonly token = this.sheetsFolder + '/token.json';
private static authUrl: null | string = null;
private worksheetId: number = 0;
private sheetId: string = '';
private range: string = '';
public async getSheetState(): Promise<GoogleSheetState> {
const ret: GoogleSheetState = {
@@ -31,35 +34,31 @@ class sheet {
id: false,
worksheet: false,
};
ret.auth = await this.authorized();
this.sheetId = '';
this.worksheetId = 0;
if (!sheet.client) {
return ret;
}
await this.loadToken();
ret.auth = await this.refreshToken();
if (ret.auth) {
const settings = DataProvider.getGoogleSheet();
const x = await this.exist(settings.id, settings.worksheet);
if (x === true) {
ret.id = true;
this.sheetId = settings.id;
} else if (x !== false) {
ret.id = true;
ret.worksheet = true;
this.sheetId = settings.id;
this.worksheetId = x.worksheetId;
this.range = x.range;
}
}
logger.info(LogOrigin.Server, `Sheet State: ${JSON.stringify(ret)}`);
return ret;
}
/**
* checks the authorized state
* @returns {Promise<boolean>}
*/
public async authorized(): Promise<boolean> {
if (await this.loadToken()) {
if (await this.refreshToken()) {
return true;
}
} else {
return false;
}
}
/**
* test existance of sheet and workssheet and get is index
* @param {string} sheetId - https://docs.google.com/spreadsheets/d/[[spreadsheetId]]/edit#gid=0
@@ -67,7 +66,7 @@ class sheet {
* @returns {Promise<false | {worksheetId: number, range: string}>} - false if not found | true if sheetId existes | id of worksheet and rage of worksheet
* @throws
*/
public async exist(
private async exist(
sheetId: string,
worksheet: string,
): Promise<false | true | { worksheetId: number; range: string }> {
@@ -90,32 +89,21 @@ class sheet {
return false;
}
public async push(sheetId: string, worksheet: string, options = defaultExcelImportMap) {
if (!sheet.client) {
if (!(await this.authorized())) {
throw new Error(`Sheet not authorized`);
}
public async push() {
const { auth, id, worksheet } = await this.getSheetState();
if (!auth && !id && !worksheet) {
throw new Error(`Sheet not authorized or incorrect ID or worksheet`);
}
const sheetInfo = await this.exist(sheetId, worksheet);
if (!sheetInfo) {
throw new Error(`Sheet not dose not exits`);
} else if (sheetInfo === true) {
throw new Error(`Worksheet not dose not exits`);
}
if (!isExcelImportMap(options)) {
throw new Error('Got incorrect options to excel import', JSON.parse(options));
}
const rq = await sheets({ version: 'v4', auth: sheet.client }).spreadsheets.values.get({
spreadsheetId: sheetId,
spreadsheetId: this.sheetId,
valueRenderOption: 'FORMATTED_VALUE',
majorDimension: 'ROWS',
range: sheetInfo.range,
range: this.range,
});
if (rq.status === 200) {
//TODO: projectMetadata
const { rundownMetadata } = parseExcel(rq.data.values, options);
const { rundownMetadata } = parseExcel(rq.data.values);
const rundown = DataProvider.getRundown();
const titleRow = Object.values(rundownMetadata)[0]['row'];
@@ -129,13 +117,13 @@ class sheet {
dimension: 'ROWS',
startIndex: titleRow + 1,
endIndex: titleRow + 2,
sheetId: sheetInfo.worksheetId,
sheetId: this.worksheetId,
},
},
});
//and delete the rest
updateRundown.push({
deleteDimension: { range: { dimension: 'ROWS', startIndex: titleRow + 2, sheetId: sheetInfo.worksheetId } },
deleteDimension: { range: { dimension: 'ROWS', startIndex: titleRow + 2, sheetId: this.worksheetId } },
});
// insert the lenght of the rundown
updateRundown.push({
@@ -145,7 +133,7 @@ class sheet {
dimension: 'ROWS',
startIndex: titleRow + 1,
endIndex: titleRow + rundown.length,
sheetId: sheetInfo.worksheetId,
sheetId: this.worksheetId,
},
},
});
@@ -160,14 +148,14 @@ class sheet {
//update the corespunding row with event data
rundown.forEach((entry, index) =>
updateRundown.push(
this.cellRequenstFromEvent(entry, index, sheetInfo.worksheetId, rundownMetadata, titleCol as number),
this.cellRequenstFromEvent(entry, index, this.worksheetId, rundownMetadata, titleCol as number),
),
);
const writeResponds = await sheets({ version: 'v4', auth: sheet.client }).spreadsheets.batchUpdate({
spreadsheetId: sheetId,
spreadsheetId: this.sheetId,
requestBody: {
includeSpreadsheetInResponse: false,
responseRanges: [sheetInfo.range],
responseRanges: [this.range],
requests: updateRundown,
},
});
@@ -185,42 +173,31 @@ class sheet {
/**
* `parse` a given sheet
* @param {string} sheetId - https://docs.google.com/spreadsheets/d/[[spreadsheetId]]/edit#gid=0
* @param {string} worksheet - the name of the worksheet containg ontime data
* @param {string} worksheetName - the name of the worksheet containg ontime data
* @param {ExcelImportOptions} options
* @returns {Promise<Partial<ResponseOK>>}
* @throws
*/
public async pull(sheetId: string, worksheet: string, options = defaultExcelImportMap) {
if (!sheet.client) {
if (!(await this.authorized())) {
throw new Error(`Sheet not authorized`);
}
public async pull() {
const { auth, id, worksheet } = await this.getSheetState();
if (!auth && !id && !worksheet) {
throw new Error(`Sheet not authorized or incorrect ID or worksheet`);
}
const res: Partial<ResponseOK> = {};
if (!isExcelImportMap(options)) {
throw new Error('Got incorrect options to excel import', JSON.parse(options));
}
const sheetInfo = await this.exist(sheetId, worksheet);
if (!sheetInfo) {
throw new Error(`Sheet not dose not exits`);
} else if (sheetInfo === true) {
throw new Error(`Worksheet not dose not exits`);
}
const rq = await sheets({ version: 'v4', auth: sheet.client }).spreadsheets.values.get({
spreadsheetId: sheetId,
spreadsheetId: this.sheetId,
valueRenderOption: 'FORMATTED_VALUE',
majorDimension: 'ROWS',
range: sheetInfo.range,
range: this.range,
});
if (rq.status === 200) {
res.data = {};
const dataFromSheet = parseExcel(rq.data.values, options);
const dataFromSheet = parseExcel(rq.data.values);
res.data.rundown = parseRundown(dataFromSheet);
if (res.data.rundown.length < 1) {
throw new Error(`Could not find data to import in the worksheet ${options.worksheet}`);
throw new Error(`Could not find data to import in the worksheet`);
}
res.data.project = parseProject(dataFromSheet);
res.data.userFields = parseUserFields(dataFromSheet);
@@ -242,7 +219,7 @@ class sheet {
sheet.client = null;
sheet.authUrl = null;
await writeFile(this.client_secret, JSON.stringify(secrets), 'utf-8');
return await this.getSheetState();
return;
}
/**