(field: T, value: ExcelImportMap[T]) => void;
}
export default function ExcelFileOptions(props: ExcelFileOptionsProps) {
- const { optionsRef, updateOptions } = props;
+ const { importOptions, updateOptions } = props;
- const worksheet: TableEntry[] = [{ label: 'Worksheet', title: 'worksheet', value: optionsRef.current.worksheet }];
+ const worksheet: TableEntry[] = [{ label: 'Worksheet', title: 'worksheet', value: importOptions.worksheet }];
const timings: TableEntry[] = [
- { label: 'Start time', title: 'timeStart', value: optionsRef.current.timeStart },
- { label: 'End Time', title: 'timeEnd', value: optionsRef.current.timeEnd },
- { label: 'Duration', title: 'duration', value: optionsRef.current.duration },
- { label: 'Warning Time', title: 'timeWarning', value: optionsRef.current.timeWarning },
- { label: 'Danger Time', title: 'timeDanger', value: optionsRef.current.timeDanger },
+ { label: 'Start time', title: 'timeStart', value: importOptions.timeStart },
+ { label: 'End Time', title: 'timeEnd', value: importOptions.timeEnd },
+ { label: 'Duration', title: 'duration', value: importOptions.duration },
+ { label: 'Warning Time', title: 'timeWarning', value: importOptions.timeWarning },
+ { label: 'Danger Time', title: 'timeDanger', value: importOptions.timeDanger },
];
const titles: TableEntry[] = [
- { label: 'Cue', title: 'cue', value: optionsRef.current.cue },
- { label: 'Colour', title: 'colour', value: optionsRef.current.colour },
- { label: 'Title', title: 'title', value: optionsRef.current.title },
- { label: 'Presenter', title: 'presenter', value: optionsRef.current.presenter },
- { label: 'Subtitle', title: 'subtitle', value: optionsRef.current.subtitle },
- { label: 'Note', title: 'note', value: optionsRef.current.note },
+ { label: 'Cue', title: 'cue', value: importOptions.cue },
+ { label: 'Colour', title: 'colour', value: importOptions.colour },
+ { label: 'Title', title: 'title', value: importOptions.title },
+ { label: 'Presenter', title: 'presenter', value: importOptions.presenter },
+ { label: 'Subtitle', title: 'subtitle', value: importOptions.subtitle },
+ { label: 'Note', title: 'note', value: importOptions.note },
];
const options: TableEntry[] = [
- { label: 'Is Public', title: 'isPublic', value: optionsRef.current.isPublic },
- { label: 'Skip', title: 'skip', value: optionsRef.current.skip },
- { label: 'Timer Type', title: 'timerType', value: optionsRef.current.timerType },
- { label: 'End Action', title: 'endAction', value: optionsRef.current.endAction },
+ { label: 'Is Public', title: 'isPublic', value: importOptions.isPublic },
+ { label: 'Skip', title: 'skip', value: importOptions.skip },
+ { label: 'Timer Type', title: 'timerType', value: importOptions.timerType },
+ { label: 'End Action', title: 'endAction', value: importOptions.endAction },
];
const userFields: TableEntry[] = [
- { label: 'User 0', title: 'user0', value: optionsRef.current.user0 },
- { label: 'User 1', title: 'user1', value: optionsRef.current.user1 },
- { label: 'User 2', title: 'user2', value: optionsRef.current.user2 },
- { label: 'User 3', title: 'user3', value: optionsRef.current.user3 },
- { label: 'User 4', title: 'user4', value: optionsRef.current.user4 },
- { label: 'User 5', title: 'user5', value: optionsRef.current.user5 },
- { label: 'User 6', title: 'user6', value: optionsRef.current.user6 },
- { label: 'User 7', title: 'user7', value: optionsRef.current.user7 },
- { label: 'User 8', title: 'user8', value: optionsRef.current.user8 },
- { label: 'User 9', title: 'user9', value: optionsRef.current.user9 },
+ { label: 'User 0', title: 'user0', value: importOptions.user0 },
+ { label: 'User 1', title: 'user1', value: importOptions.user1 },
+ { label: 'User 2', title: 'user2', value: importOptions.user2 },
+ { label: 'User 3', title: 'user3', value: importOptions.user3 },
+ { label: 'User 4', title: 'user4', value: importOptions.user4 },
+ { label: 'User 5', title: 'user5', value: importOptions.user5 },
+ { label: 'User 6', title: 'user6', value: importOptions.user6 },
+ { label: 'User 7', title: 'user7', value: importOptions.user7 },
+ { label: 'User 8', title: 'user8', value: importOptions.user8 },
+ { label: 'User 9', title: 'user9', value: importOptions.user9 },
];
return (
diff --git a/apps/client/src/features/modals/upload-modal/upload-options/ImportMapTable.tsx b/apps/client/src/features/modals/upload-modal/upload-options/ImportMapTable.tsx
index 1435d0875..bcbfa577f 100644
--- a/apps/client/src/features/modals/upload-modal/upload-options/ImportMapTable.tsx
+++ b/apps/client/src/features/modals/upload-modal/upload-options/ImportMapTable.tsx
@@ -31,8 +31,8 @@ export default function ImportMapTable(props: ImportMapTableProps) {
|
{
+export const getClientSecret = async (req: Request, res: Response) => {
try {
- const clientSecrectExists = await sheet.testClientSecret();
- if (clientSecrectExists) {
+ // TODO: can we merge this with the previous?
+ const clientSecretExists = await sheet.testClientSecret();
+ if (clientSecretExists) {
res.status(200).send();
} else {
res.status(500).send({ message: 'The Client ID does not exist' });
@@ -706,11 +707,11 @@ export const getAuthentication = async (_req: Request, res: Response) => {
*/
export const postId = async (req: Request, res: Response) => {
try {
- const { id } = req.body;
- if (id.lenght < 40) {
- res.status(400).send({ message: 'ID is usualy 44 characters long' });
+ const { sheetId } = req.body;
+ if (sheetId.length < 40) {
+ res.status(400).send({ message: 'ID is usually 44 characters long' });
}
- const state = await sheet.testSheetId(id);
+ const state = await sheet.testSheetId(sheetId);
res.status(200).send(state);
} catch (error) {
res.status(500).send({ message: String(error) });
@@ -722,8 +723,8 @@ export const postId = async (req: Request, res: Response) => {
*/
export const postWorksheet = async (req: Request, res: Response) => {
try {
- const { worksheet, id } = req.body;
- const state = await sheet.testWorksheet(worksheet, id);
+ const { sheetId, worksheet } = req.body;
+ const state = await sheet.testWorksheet(sheetId, worksheet);
res.status(200).send(state);
} catch (error) {
res.status(500).send({ message: String(error) });
@@ -731,13 +732,15 @@ export const postWorksheet = async (req: Request, res: Response) => {
};
/**
- * @description STEP-5 POST download undown to sheet
+ * @description STEP-5 POST download rundown to sheet
* @returns parsed result
*/
export async function pullSheet(req: Request, res: Response) {
try {
- const { id, options } = req.body;
- const data = await sheet.pull(id, options);
+ const { sheetId, options } = req.body;
+ console.log('starting');
+ const data = await sheet.pull(sheetId, options);
+ console.log('finished');
res.status(200).send(data);
} catch (error) {
res.status(500).send({ message: String(error) });
@@ -749,8 +752,8 @@ export async function pullSheet(req: Request, res: Response) {
*/
export async function pushSheet(req: Request, res: Response) {
try {
- const { id, options } = req.body;
- await sheet.push(id, options);
+ const { sheetId, options } = req.body;
+ await sheet.push(sheetId, options);
res.status(200).send();
} catch (error) {
res.status(500).send({ message: String(error) });
diff --git a/apps/server/src/controllers/ontimeController.validate.ts b/apps/server/src/controllers/ontimeController.validate.ts
index f385e6b82..8d01d9f92 100644
--- a/apps/server/src/controllers/ontimeController.validate.ts
+++ b/apps/server/src/controllers/ontimeController.validate.ts
@@ -244,8 +244,8 @@ export const validateProjectFiles = (projectFiles: { filename?: string; newFilen
return errors;
};
-export const validateSheetid = [
- body('id').exists().isString(),
+export const validateSheetId = [
+ body('sheetId').exists().isString(),
(req: Request, res: Response, next: NextFunction) => {
const errors = validationResult(req);
@@ -255,7 +255,7 @@ export const validateSheetid = [
];
export const validateWorksheet = [
- body('id').exists().isString(),
+ body('sheetId').exists().isString(),
body('worksheet').exists().isString(),
(req: Request, res: Response, next: NextFunction) => {
@@ -266,7 +266,7 @@ export const validateWorksheet = [
];
export const validateSheetOptions = [
- body('id').exists().isString(),
+ body('sheetId').exists().isString(),
// body('options').exists().isObject(), TODO:
(req: Request, res: Response, next: NextFunction) => {
diff --git a/apps/server/src/routes/ontimeRouter.ts b/apps/server/src/routes/ontimeRouter.ts
index a6957a827..4430909e8 100644
--- a/apps/server/src/routes/ontimeRouter.ts
+++ b/apps/server/src/routes/ontimeRouter.ts
@@ -31,7 +31,8 @@ import {
pushSheet,
postId,
getAuthentication,
- getClientSecrect as getClientSecret,
+ getClientSecret as getClientSecret,
+ postWorksheet,
} from '../controllers/ontimeController.js';
import {
@@ -45,7 +46,7 @@ import {
validateProjectDuplicate,
validateLoadProjectFile,
validateProjectRename,
- validateSheetid,
+ validateSheetId,
validateWorksheet,
validateSheetOptions,
} from '../controllers/ontimeController.validate.js';
@@ -126,6 +127,7 @@ router.post('/project', projectSanitiser, createProjectFile);
// create route between controller and '/ontime/project/:filename' endpoint
router.delete('/project/:filename', sanitizeProjectFilename, deleteProjectFile);
+// TODO: move the google sheet stuff into a separate file
// Google Sheet integration - Step 1
router.post('/sheet/clientsecret', uploadFile, uploadClientSecret);
router.get('/sheet/clientsecret', uploadFile, getClientSecret);
@@ -135,13 +137,13 @@ router.get('/sheet/authentication/url', getAuthenticationUrl);
router.get('/sheet/authentication', getAuthentication);
// Google Sheet integration - Step 3
-router.post('/sheet/id', validateSheetid, postId);
+router.post('/sheet/sheetId', validateSheetId, postId);
// Google Sheet integration - Step 4
-router.post('/sheet/worksheet', validateWorksheet, postId);
+router.post('/sheet/worksheet', validateWorksheet, postWorksheet);
// Google Sheet integration - Step 5
-router.post('/sheet/pull', validateSheetOptions, pullSheet);
+router.post('/sheet-pull', validateSheetOptions, pullSheet);
// Google Sheet integration - Step 6
router.post('/sheet-push', validateSheetOptions, pushSheet);
diff --git a/apps/server/src/utils/sheetsAuth.ts b/apps/server/src/utils/sheetsAuth.ts
index 0dba04ad5..a283e0068 100644
--- a/apps/server/src/utils/sheetsAuth.ts
+++ b/apps/server/src/utils/sheetsAuth.ts
@@ -80,7 +80,7 @@ class Sheet {
}
/**
- * @description STEP 1 - test that the saved object is pressent
+ * @description STEP 1 - test that the saved object is present
*/
testClientSecret() {
return Sheet.clientSecret !== null;
@@ -92,18 +92,15 @@ class Sheet {
* @throws
*/
async openAuthServer(): Promise {
- //TODO: this only works on local networks
+ //TODO: this only works in local networks
- // if the server is allready running retun it
+ // if the server is already running return it
if (Sheet.authUrl) {
clearTimeout(this.authServerTimeout);
- this.authServerTimeout = setTimeout(
- () => {
- Sheet.authUrl = null;
- server.unref();
- },
- 2 * 60 * 1000,
- );
+ this.authServerTimeout = setTimeout(() => {
+ Sheet.authUrl = null;
+ server.unref();
+ }, 120000);
return Sheet.authUrl;
}
@@ -209,12 +206,12 @@ class Sheet {
* @description STEP 3 - test the given sheet id
* @throws
*/
- async testSheetId(id: string) {
+ async testSheetId(sheetId: string) {
const spreadsheets = await sheets({ version: 'v4', auth: Sheet.client }).spreadsheets.get({
- spreadsheetId: id,
+ spreadsheetId: sheetId,
includeGridData: false,
});
- if (spreadsheets.status != 200) {
+ if (spreadsheets.status !== 200) {
throw new Error(spreadsheets.statusText);
}
return { worksheetOptions: spreadsheets.data.sheets.map((i) => i.properties.title) };
@@ -224,12 +221,12 @@ class Sheet {
* @description STEP 4 - test the given worksheet
* @throws
*/
- async testWorksheet(id: string, worksheet: string) {
+ async testWorksheet(sheetId: string, worksheet: string) {
const spreadsheets = await sheets({ version: 'v4', auth: Sheet.client }).spreadsheets.get({
- spreadsheetId: id,
+ spreadsheetId: sheetId,
includeGridData: false,
});
- if (spreadsheets.status != 200) {
+ if (spreadsheets.status !== 200) {
throw new Error(spreadsheets.statusText);
}
const worksheetExist = spreadsheets.data.sheets.find((i) => i.properties.title === worksheet);
@@ -250,17 +247,18 @@ class Sheet {
spreadsheetId: sheetId,
});
- if (spreadsheets.status === 200) {
- const ourWorksheetData = spreadsheets.data.sheets.find((n) => n.properties.title == worksheet);
- if (ourWorksheetData !== undefined) {
- const endCell = getA1Notation(
- ourWorksheetData.properties.gridProperties.rowCount,
- ourWorksheetData.properties.gridProperties.columnCount,
- );
- return { worksheetId: ourWorksheetData.properties.sheetId, range: `${worksheet}!A1:${endCell}` };
- }
- } else {
- throw new Error('Uable to open spreadsheets');
+ if (spreadsheets.status !== 200) {
+ throw new Error(`Request failed: ${spreadsheets.status} ${spreadsheets.statusText}`);
+ }
+
+ const ourWorksheetData = spreadsheets.data.sheets.find((n) => n.properties.title == worksheet);
+
+ if (ourWorksheetData !== undefined) {
+ const endCell = getA1Notation(
+ ourWorksheetData.properties.gridProperties.rowCount,
+ ourWorksheetData.properties.gridProperties.columnCount,
+ );
+ return { worksheetId: ourWorksheetData.properties.sheetId, range: `${worksheet}!A1:${endCell}` };
}
}
@@ -302,7 +300,7 @@ class Sheet {
updateRundown.push({
deleteDimension: { range: { dimension: 'ROWS', startIndex: titleRow + 2, sheetId: worksheetId } },
});
- // insert the lenght of the rundown
+ // insert the length of the rundown
updateRundown.push({
insertDimension: {
inheritFromBefore: false,
@@ -340,19 +338,19 @@ class Sheet {
}
/**
- * @description STEP 5 - Downpload the rundown from sheet
- * @param {string} id - id of the sheet https://docs.google.com/spreadsheets/d/[[spreadsheetId]]/edit#gid=0
+ * @description STEP 5 - Download the rundown from sheet
+ * @param {string} sheetId - id of the sheet https://docs.google.com/spreadsheets/d/[[spreadsheetId]]/edit#gid=0
* @param {ExcelImportMap} options
* @returns {Promise>}
* @throws
*/
- public async pull(id: string, options: ExcelImportMap): Promise> {
- const { range } = await this.exist(id, options.worksheet);
+ public async pull(sheetId: string, options: ExcelImportMap): Promise> {
+ const { range } = await this.exist(sheetId, options.worksheet);
const res: Partial = {};
const googleResponse = await sheets({ version: 'v4', auth: Sheet.client }).spreadsheets.values.get({
- spreadsheetId: id,
+ spreadsheetId: sheetId,
valueRenderOption: 'FORMATTED_VALUE',
majorDimension: 'ROWS',
range,
|