mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-27 09:59:08 +00:00
push project data
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { ChangeEvent, useRef, useState, useEffect } from 'react';
|
import { ChangeEvent, useEffect,useRef, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Input,
|
Input,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { millisToString } from 'ontime-utils';
|
import { millisToString } from 'ontime-utils';
|
||||||
import { getA1Notation, cellRequenstFromEvent } from '../googleSheetUtils.js';
|
import { getA1Notation, cellRequenstFromEvent, cellRequenstFromProjectData } from '../googleSheetUtils.js';
|
||||||
import { EndAction, OntimeRundownEntry, SupportedEvent, TimerType } from 'ontime-types';
|
import { EndAction, OntimeRundownEntry, ProjectData, SupportedEvent, TimerType } from 'ontime-types';
|
||||||
|
|
||||||
describe('getA1Notation()', () => {
|
describe('getA1Notation()', () => {
|
||||||
test('A1', () => {
|
test('A1', () => {
|
||||||
@@ -328,3 +328,106 @@ describe('cellRequenstFromEvent()', () => {
|
|||||||
expect(result2.updateCells.fields).toStrictEqual('userEnteredValue');
|
expect(result2.updateCells.fields).toStrictEqual('userEnteredValue');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('cellRequenstFromProjectData()', () => {
|
||||||
|
test('string to string', () => {
|
||||||
|
const projectData: ProjectData = {
|
||||||
|
title: 'Title',
|
||||||
|
description: 'Description',
|
||||||
|
publicUrl: 'Public Url',
|
||||||
|
backstageUrl: 'Backstage Url',
|
||||||
|
publicInfo: 'Public Info',
|
||||||
|
backstageInfo: 'Backstage Info',
|
||||||
|
};
|
||||||
|
const metadata = {
|
||||||
|
title: { row: 0, col: 1 },
|
||||||
|
description: { row: 1, col: 1 },
|
||||||
|
publicUrl: { row: 2, col: 1 },
|
||||||
|
backstageUrl: { row: 3, col: 1 },
|
||||||
|
publicInfo: { row: 4, col: 1 },
|
||||||
|
backstageInfo: { row: 5, col: 1 },
|
||||||
|
};
|
||||||
|
const result = cellRequenstFromProjectData(projectData, 1234, metadata);
|
||||||
|
expect(result.updateCells.rows[0].values[0].userEnteredValue.stringValue).toStrictEqual(projectData.title);
|
||||||
|
expect(result.updateCells.rows[1].values[0].userEnteredValue.stringValue).toStrictEqual(projectData.description);
|
||||||
|
expect(result.updateCells.rows[2].values[0].userEnteredValue.stringValue).toStrictEqual(projectData.publicUrl);
|
||||||
|
expect(result.updateCells.rows[3].values[0].userEnteredValue.stringValue).toStrictEqual(projectData.backstageUrl);
|
||||||
|
expect(result.updateCells.rows[4].values[0].userEnteredValue.stringValue).toStrictEqual(projectData.publicInfo);
|
||||||
|
expect(result.updateCells.rows[5].values[0].userEnteredValue.stringValue).toStrictEqual(projectData.backstageInfo);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('metadata offset from zero', () => {
|
||||||
|
const projectData: ProjectData = {
|
||||||
|
title: 'Title',
|
||||||
|
description: 'Description',
|
||||||
|
publicUrl: 'Public Url',
|
||||||
|
backstageUrl: 'Backstage Url',
|
||||||
|
publicInfo: 'Public Info',
|
||||||
|
backstageInfo: 'Backstage Info',
|
||||||
|
};
|
||||||
|
const metadata = {
|
||||||
|
title: { row: 5, col: 10 },
|
||||||
|
description: { row: 6, col: 10 },
|
||||||
|
publicUrl: { row: 7, col: 10 },
|
||||||
|
backstageUrl: { row: 9, col: 10 },
|
||||||
|
publicInfo: { row: 10, col: 10 },
|
||||||
|
backstageInfo: { row: 11, col: 10 },
|
||||||
|
};
|
||||||
|
const result = cellRequenstFromProjectData(projectData, 1234, metadata);
|
||||||
|
expect(result.updateCells.rows[0].values[0].userEnteredValue.stringValue).toStrictEqual(projectData.title);
|
||||||
|
expect(result.updateCells.rows[1].values[0].userEnteredValue.stringValue).toStrictEqual(projectData.description);
|
||||||
|
expect(result.updateCells.rows[2].values[0].userEnteredValue.stringValue).toStrictEqual(projectData.publicUrl);
|
||||||
|
expect(result.updateCells.rows[4].values[0].userEnteredValue.stringValue).toStrictEqual(projectData.backstageUrl);
|
||||||
|
expect(result.updateCells.rows[5].values[0].userEnteredValue.stringValue).toStrictEqual(projectData.publicInfo);
|
||||||
|
expect(result.updateCells.rows[6].values[0].userEnteredValue.stringValue).toStrictEqual(projectData.backstageInfo);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('spacing in metadata', () => {
|
||||||
|
const projectData: ProjectData = {
|
||||||
|
title: 'Title',
|
||||||
|
description: 'Description',
|
||||||
|
publicUrl: 'Public Url',
|
||||||
|
backstageUrl: 'Backstage Url',
|
||||||
|
publicInfo: 'Public Info',
|
||||||
|
backstageInfo: 'Backstage Info',
|
||||||
|
};
|
||||||
|
const metadata = {
|
||||||
|
title: { row: 0, col: 1 },
|
||||||
|
description: { row: 1, col: 1 },
|
||||||
|
publicUrl: { row: 2, col: 1 },
|
||||||
|
backstageUrl: { row: 9, col: 1 },
|
||||||
|
publicInfo: { row: 15, col: 1 },
|
||||||
|
backstageInfo: { row: 50, col: 1 },
|
||||||
|
};
|
||||||
|
const result = cellRequenstFromProjectData(projectData, 1234, metadata);
|
||||||
|
expect(result.updateCells.rows[0].values[0].userEnteredValue.stringValue).toStrictEqual(projectData.title);
|
||||||
|
expect(result.updateCells.rows[1].values[0].userEnteredValue.stringValue).toStrictEqual(projectData.description);
|
||||||
|
expect(result.updateCells.rows[2].values[0].userEnteredValue.stringValue).toStrictEqual(projectData.publicUrl);
|
||||||
|
expect(result.updateCells.rows[9].values[0].userEnteredValue.stringValue).toStrictEqual(projectData.backstageUrl);
|
||||||
|
expect(result.updateCells.rows[15].values[0].userEnteredValue.stringValue).toStrictEqual(projectData.publicInfo);
|
||||||
|
expect(result.updateCells.rows[50].values[0].userEnteredValue.stringValue).toStrictEqual(projectData.backstageInfo);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('sheet setup', () => {
|
||||||
|
const projectData: ProjectData = {
|
||||||
|
title: 'Title',
|
||||||
|
description: 'Description',
|
||||||
|
publicUrl: 'Public Url',
|
||||||
|
backstageUrl: 'Backstage Url',
|
||||||
|
publicInfo: 'Public Info',
|
||||||
|
backstageInfo: 'Backstage Info',
|
||||||
|
};
|
||||||
|
const metadata = {
|
||||||
|
title: { row: 0, col: 10 },
|
||||||
|
description: { row: 1, col: 10 },
|
||||||
|
publicUrl: { row: 2, col: 10 },
|
||||||
|
backstageUrl: { row: 3, col: 10 },
|
||||||
|
publicInfo: { row: 4, col: 10 },
|
||||||
|
backstageInfo: { row: 5, col: 10 },
|
||||||
|
};
|
||||||
|
const result = cellRequenstFromProjectData(projectData, 1234, metadata);
|
||||||
|
expect(result.updateCells.start.rowIndex).toStrictEqual(0);
|
||||||
|
expect(result.updateCells.start.columnIndex).toStrictEqual(11);
|
||||||
|
expect(result.updateCells.fields).toStrictEqual('userEnteredValue');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { sheets_v4 } from '@googleapis/sheets';
|
import { sheets_v4 } from '@googleapis/sheets';
|
||||||
import { millisToString } from 'ontime-utils';
|
import { millisToString } from 'ontime-utils';
|
||||||
import { OntimeRundownEntry, isOntimeEvent } from 'ontime-types';
|
import { OntimeRundownEntry, ProjectData, isOntimeEvent } from 'ontime-types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -34,7 +34,6 @@ export function getA1Notation(row: number, column: number): string {
|
|||||||
* @param {number} index - index of the event
|
* @param {number} index - index of the event
|
||||||
* @param {number} worksheetId
|
* @param {number} worksheetId
|
||||||
* @param {any} metadata - object with all the cell positions of the title of each attribute
|
* @param {any} metadata - object with all the cell positions of the title of each attribute
|
||||||
* @param {number} titleCol - smallest col index
|
|
||||||
* @returns {sheets_v4.Schema} - list of update requests
|
* @returns {sheets_v4.Schema} - list of update requests
|
||||||
*/
|
*/
|
||||||
export function cellRequenstFromEvent(
|
export function cellRequenstFromEvent(
|
||||||
@@ -103,3 +102,64 @@ export function cellRequenstFromEvent(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description - creates updateCells request from ontime event
|
||||||
|
* @param {ProjectData} projectData
|
||||||
|
* @param {number} worksheetId
|
||||||
|
* @param {any} metadata - object with all the cell positions of the title of each attribute
|
||||||
|
* @returns {sheets_v4.Schema} - list of update requests
|
||||||
|
*/
|
||||||
|
export function cellRequenstFromProjectData(
|
||||||
|
projectData: ProjectData,
|
||||||
|
worksheetId: number,
|
||||||
|
metadata,
|
||||||
|
): sheets_v4.Schema$Request {
|
||||||
|
const r: sheets_v4.Schema$RowData[] = [];
|
||||||
|
const tmp = Object.entries(metadata)
|
||||||
|
.filter(([_, value]) => value !== undefined)
|
||||||
|
.sort(([_a, a], [_b, b]) => a['col'] - b['col']) as [string, { col: number; row: number }][];
|
||||||
|
|
||||||
|
const minRow = Object.values(metadata).reduce(
|
||||||
|
(accumulator: number, val) => Math.min(accumulator, val['row']),
|
||||||
|
Number.MAX_VALUE,
|
||||||
|
) as number;
|
||||||
|
const minCol = tmp[0][1].col + 1;
|
||||||
|
|
||||||
|
for (const [index, e] of tmp.entries()) {
|
||||||
|
if (index != 0) {
|
||||||
|
const prevRow = tmp[index - 1][1].row;
|
||||||
|
const thisRow = e[1].row;
|
||||||
|
const diff = thisRow - prevRow;
|
||||||
|
if (diff > 1) {
|
||||||
|
const fillArr = new Array<(typeof tmp)[0]>(1).fill(['blank', { row: prevRow + 1, col: e[1].col }]);
|
||||||
|
tmp.splice(index, 0, ...fillArr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tmp.forEach(([key, _]) => {
|
||||||
|
if (key == 'blank') {
|
||||||
|
r.push({});
|
||||||
|
} else {
|
||||||
|
r.push({
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
userEnteredValue: { stringValue: projectData[key] },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
updateCells: {
|
||||||
|
start: {
|
||||||
|
sheetId: worksheetId,
|
||||||
|
rowIndex: minRow,
|
||||||
|
columnIndex: minCol,
|
||||||
|
},
|
||||||
|
fields: 'userEnteredValue',
|
||||||
|
rows: r,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -121,11 +121,11 @@ export const parseExcel = (excelData: unknown[][], options?: Partial<ExcelImport
|
|||||||
const handlers = {
|
const handlers = {
|
||||||
[importMap.projectName]: (row: number, col: number) => {
|
[importMap.projectName]: (row: number, col: number) => {
|
||||||
projectTitleNext = true;
|
projectTitleNext = true;
|
||||||
projectMetadata['projectName'] = { row: row, col: col };
|
projectMetadata['title'] = { row: row, col: col };
|
||||||
},
|
},
|
||||||
[importMap.projectDescription]: (row: number, col: number) => {
|
[importMap.projectDescription]: (row: number, col: number) => {
|
||||||
projectDescriptionNext = true;
|
projectDescriptionNext = true;
|
||||||
projectMetadata['projectDescription'] = { row: row, col: col };
|
projectMetadata['description'] = { row: row, col: col };
|
||||||
},
|
},
|
||||||
[importMap.publicUrl]: (row: number, col: number) => {
|
[importMap.publicUrl]: (row: number, col: number) => {
|
||||||
publicUrlNext = true;
|
publicUrlNext = true;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { parseProject, parseRundown, parseUserFields } from './parserFunctions.j
|
|||||||
import { ensureDirectory } from './fileManagement.js';
|
import { ensureDirectory } from './fileManagement.js';
|
||||||
import { DataProvider } from '../classes/data-provider/DataProvider.js';
|
import { DataProvider } from '../classes/data-provider/DataProvider.js';
|
||||||
import { GoogleSheetState } from 'ontime-types';
|
import { GoogleSheetState } from 'ontime-types';
|
||||||
import { cellRequenstFromEvent, getA1Notation } from './googleSheetUtils.js';
|
import { cellRequenstFromEvent, cellRequenstFromProjectData, getA1Notation } from './googleSheetUtils.js';
|
||||||
|
|
||||||
type ResponseOK = {
|
type ResponseOK = {
|
||||||
data: Partial<DatabaseModel>;
|
data: Partial<DatabaseModel>;
|
||||||
@@ -97,9 +97,9 @@ class sheet {
|
|||||||
range: this.range,
|
range: this.range,
|
||||||
});
|
});
|
||||||
if (rq.status === 200) {
|
if (rq.status === 200) {
|
||||||
//TODO: projectMetadata
|
const { rundownMetadata, projectMetadata } = parseExcel(rq.data.values);
|
||||||
const { rundownMetadata } = parseExcel(rq.data.values);
|
|
||||||
const rundown = DataProvider.getRundown();
|
const rundown = DataProvider.getRundown();
|
||||||
|
const projectData = DataProvider.getProjectData();
|
||||||
const titleRow = Object.values(rundownMetadata)[0]['row'];
|
const titleRow = Object.values(rundownMetadata)[0]['row'];
|
||||||
|
|
||||||
const updateRundown = Array<sheets_v4.Schema$Request>();
|
const updateRundown = Array<sheets_v4.Schema$Request>();
|
||||||
@@ -133,12 +133,14 @@ class sheet {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
//update the corespunding row with event data
|
//update the corresponding row with event data
|
||||||
rundown.forEach((entry, index) =>
|
rundown.forEach((entry, index) =>
|
||||||
updateRundown.push(
|
updateRundown.push(cellRequenstFromEvent(entry, index, this.worksheetId, rundownMetadata)),
|
||||||
cellRequenstFromEvent(entry, index, this.worksheetId, rundownMetadata),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//update project data
|
||||||
|
updateRundown.push(cellRequenstFromProjectData(projectData, this.worksheetId, projectMetadata));
|
||||||
|
|
||||||
const writeResponds = await sheets({ version: 'v4', auth: sheet.client }).spreadsheets.batchUpdate({
|
const writeResponds = await sheets({ version: 'v4', auth: sheet.client }).spreadsheets.batchUpdate({
|
||||||
spreadsheetId: this.sheetId,
|
spreadsheetId: this.sheetId,
|
||||||
requestBody: {
|
requestBody: {
|
||||||
@@ -227,8 +229,6 @@ class sheet {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private authServerTimeout;
|
private authServerTimeout;
|
||||||
/**
|
/**
|
||||||
* create local Auth Server - returns url to serve on success
|
* create local Auth Server - returns url to serve on success
|
||||||
|
|||||||
Reference in New Issue
Block a user