* refactor: add typescript dependencies
* chore: update chakra-ui
* refactor: typescript config
* refactor: convert <MenuBar> component to typescript
* refactor: convert <TooltipActionBtn> component to typescript
* refactor: improve UX in file upload
* refactor: upgrade dependencies
* refactor: prepare data provider
* refactor: prevent importing bad fields
* refactor: extract merge to provider
* refactor(upload): parser merges only given fields
* refactor(upload): add event fields to excel
* refactor(upload): improve styling on modal open
* style: improve styling in menu
* style: prevent global pollution
* feat(upload): add upload options
* fix: avoid potential bug in log queue
This commit is contained in:
Carlos Valente
2022-09-17 23:28:52 +02:00
committed by GitHub
parent 94b03312a6
commit 3128f5a195
25 changed files with 788 additions and 368 deletions
@@ -564,6 +564,9 @@ describe('test parseExcel function', () => {
[],
['Event Name', 'Test Event'],
['Event URL', 'www.carlosvalente.com'],
['Public Info', 'test public info'],
['Backstage Info', 'test backstage info'],
['End Message', 'test end message'],
[],
[],
[
@@ -640,6 +643,14 @@ describe('test parseExcel function', () => {
[],
];
const expectedParsedEvent = {
title: 'Test Event',
url: 'www.carlosvalente.com',
publicInfo: 'test public info',
backstageInfo: 'test backstage info',
endMessage: 'test end message',
};
const expectedParsedEvents = [
{
timeStart: 25200000,
@@ -681,6 +692,7 @@ describe('test parseExcel function', () => {
const parsedData = await parseExcel_v1(testdata);
expect(parsedData.event).toStrictEqual(expectedParsedEvent);
expect(parsedData.events).toBeDefined();
expect(parsedData.events.title).toBe(expectedParsedEvents.title);
expect(parsedData.events.presenter).toBe(expectedParsedEvents.presenter);
+25 -2
View File
@@ -68,6 +68,9 @@ export const parseExcel_v1 = async (excelData) => {
.forEach((row) => {
let eventTitleNext = false;
let eventUrlNext = false;
let publicInfoNext = false;
let backstageInfoNext = false;
let endMessageNext = false;
const event = {};
row.forEach((column, j) => {
@@ -78,6 +81,15 @@ export const parseExcel_v1 = async (excelData) => {
} else if (eventUrlNext) {
eventData.url = column;
eventUrlNext = false;
} else if (publicInfoNext) {
eventData.publicInfo = column;
publicInfoNext = false;
} else if (backstageInfoNext) {
eventData.backstageInfo = column;
backstageInfoNext = false;
} else if (endMessageNext) {
eventData.endMessage = column;
endMessageNext = false;
} else if (j === timeStartIndex) {
event.timeStart = parseExcelDate(column);
} else if (j === timeEndIndex) {
@@ -128,6 +140,15 @@ export const parseExcel_v1 = async (excelData) => {
case 'event url':
eventUrlNext = true;
break;
case 'public info':
publicInfoNext = true;
break;
case 'backstage info':
backstageInfoNext = true;
break;
case 'end message':
endMessageNext = true;
break;
case 'time start':
case 'start':
timeStartIndex = j;
@@ -329,7 +350,6 @@ export const fileHandler = async (file) => {
let res = {};
// check which file type are we dealing with
if (file.endsWith('.xlsx')) {
try {
const excelData = xlsx
@@ -341,7 +361,10 @@ export const fileHandler = async (file) => {
// we only look at worksheets called ontime or event schedule
if (excelData?.data) {
const dataFromExcel = await parseExcel_v1(excelData.data);
res.data = await parseJson_v1(dataFromExcel);
res.data = {};
res.data.events = parseEvents_v1(dataFromExcel);
res.data.event = parseEvent_v1(dataFromExcel, true);
res.data.userFields = parseUserFields_v1(dataFromExcel);
res.message = 'success';
} else {
console.log('Error: No sheets found named ontime or event schedule');
+67 -55
View File
@@ -14,37 +14,41 @@ export const parseEvents_v1 = (data) => {
if ('events' in data) {
console.log('Found events definition, importing...');
const events = [];
const ids = [];
for (const e of data.events) {
// cap number of events
if (events.length >= MAX_EVENTS) {
console.log(`ERROR: Reached limit number of ${MAX_EVENTS} events`);
break;
}
// double check unique ids
if (ids.indexOf(e?.id) !== -1) {
console.log('ERROR: ID collision on import, skipping');
continue;
}
if (e.type === 'event') {
const event = validateEvent_v1(e);
if (event != null) {
events.push(event);
ids.push(event.id);
try {
const ids = [];
for (const e of data.events) {
// cap number of events
if (events.length >= MAX_EVENTS) {
console.log(`ERROR: Reached limit number of ${MAX_EVENTS} events`);
break;
}
// double check unique ids
if (ids.indexOf(e?.id) !== -1) {
console.log('ERROR: ID collision on import, skipping');
continue;
}
if (e.type === 'event') {
const event = validateEvent_v1(e);
if (event != null) {
events.push(event);
ids.push(event.id);
}
} else if (e.type === 'delay') {
events.push({
...delayDef,
duration: e.duration,
id: e.id || generateId(),
});
} else if (e.type === 'block') {
events.push({ ...blockDef, id: e.id || generateId() });
} else {
console.log('ERROR: undefined event type, skipping');
}
} else if (e.type === 'delay') {
events.push({
...delayDef,
duration: e.duration,
id: e.id || generateId(),
});
} else if (e.type === 'block') {
events.push({ ...blockDef, id: e.id || generateId() });
} else {
console.log('ERROR: undefined event type, skipping');
}
} catch (error) {
console.log(`Error ${error}`);
}
// write to db
newEvents = events;
@@ -73,7 +77,7 @@ export const parseEvent_v1 = (data, enforce) => {
endMessage: e.endMessage || dbModelv1.event.endMessage,
};
} else if (enforce) {
newEvent = dbModelv1.event;
newEvent = { ...dbModelv1.event };
console.log(`Created event object in db`);
}
return newEvent;
@@ -137,7 +141,7 @@ export const parseOsc_v1 = (data, enforce) => {
...osc,
};
} else if (enforce) {
newOsc = dbModelv1.osc;
newOsc = { ...dbModelv1.osc };
console.log(`Created OSC object in db`);
}
return newOsc;
@@ -165,7 +169,7 @@ export const parseHttp_v1 = (data, enforce) => {
...http,
};
} else if (enforce) {
newHttp.http = dbModelv1.http;
newHttp.http = { ...dbModelv1.http };
console.log(`Created http object in db`);
}
return newHttp;
@@ -181,23 +185,27 @@ export const parseAliases_v1 = (data) => {
if ('aliases' in data) {
console.log('Found Aliases definition, importing...');
const ids = [];
for (const a of data.aliases) {
// double check unique ids
if (ids.indexOf(a?.id) !== -1) {
console.log('ERROR: ID collision on import, skipping');
continue;
}
const newAlias = {
id: a.id || generateId(),
enabled: a.enabled || false,
alias: a.alias || '',
pathAndParams: a.pathAndParams || '',
};
try {
for (const a of data.aliases) {
// double check unique ids
if (ids.indexOf(a?.id) !== -1) {
console.log('ERROR: ID collision on import, skipping');
continue;
}
const newAlias = {
id: a.id || generateId(),
enabled: a.enabled || false,
alias: a.alias || '',
pathAndParams: a.pathAndParams || '',
};
ids.push(newAlias.id);
newAliases.push(newAlias);
ids.push(newAlias.id);
newAliases.push(newAlias);
}
console.log(`Uploaded ${newAliases?.length || 0} alias(es)`);
} catch (error) {
console.log(`Error: ${error}`);
}
console.log(`Uploaded ${newAliases?.length || 0} alias(es)`);
}
return newAliases;
};
@@ -208,19 +216,23 @@ export const parseAliases_v1 = (data) => {
* @returns {object} - event object data
*/
export const parseUserFields_v1 = (data) => {
const newUserFields = dbModelv1.userFields;
const newUserFields = { ...dbModelv1.userFields };
if ('userFields' in data) {
console.log('Found User Fields definition, importing...');
// we will only be importing the fields we know, so look for that
let fieldsFound = 0;
for (const n in newUserFields) {
if (n in data.userFields) {
fieldsFound++;
newUserFields[n] = data.userFields[n];
try {
let fieldsFound = 0;
for (const n in newUserFields) {
if (n in data.userFields) {
fieldsFound++;
newUserFields[n] = data.userFields[n];
}
}
console.log(`Uploaded ${fieldsFound} user fields`);
} catch (error) {
console.log(`Error: ${error}`);
}
console.log(`Uploaded ${fieldsFound} user fields`);
}
return { ...dbModelv1.userFields, ...newUserFields };
return { ...newUserFields };
};